第二章:开发环境搭建 — Python 3.10+、Redis、Kafka、Docker 环境配置与项目初始化

说实话,搭建开发环境这件事,很多新手觉得不值一提。但我见过太多团队,项目跑了大半年,突然因为某个依赖版本不一致,整个系统炸了。高频交易对延迟极其敏感,环境不一致导致的bug,排查起来比写代码痛苦十倍。

这一章,我们就来把地基打牢。我会带你一步步配好Python、Redis、Kafka、Docker,并初始化一个风控引擎的项目骨架。

2.1 Python 3.10+ 环境配置

我个人习惯用pyenv来管理多个Python版本。为什么?因为高频交易项目往往需要锁定一个稳定版本,而系统自带的Python可能太老或太新。

核心原则:生产环境与开发环境的Python版本必须完全一致。小版本号都不能差。

安装pyenv(以Ubuntu为例):

# 安装依赖
sudo apt-get update
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

# 安装pyenv
curl https://pyenv.run | bash

# 配置环境变量(加到~/.bashrc或~/.zshrc)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc

# 安装Python 3.10.11
pyenv install 3.10.11
pyenv global 3.10.11
python --version  # 确认输出: Python 3.10.11

避坑指南:我曾经在某个项目里用了Python 3.11,结果发现一个关键的异步库不兼容,回退到3.10花了整整两天。所以,高频交易项目我建议锁定3.10.x系列,生态最成熟。

接下来,创建虚拟环境。我推荐用poetry,它比pipenv更轻量,依赖解析也更快。

# 安装poetry
curl -sSL https://install.python-poetry.org | python3 -

# 初始化项目
mkdir hft-risk-engine && cd hft-risk-engine
poetry init --name hft-risk-engine --python "^3.10" --no-interaction

# 添加核心依赖
poetry add numpy pandas redis kafka-python pyyaml
poetry add --dev pytest pytest-cov mypy black

2.2 Redis 配置 — 低延迟缓存与状态存储

在高频交易里,Redis不只是缓存。它用来存订单状态、风控规则、实时统计量。说白了,它是风控引擎的「内存数据库」。

我建议用Docker来跑Redis,这样版本切换和清理都方便。

# 拉取Redis 7.2镜像
docker pull redis:7.2

# 启动Redis(生产环境记得加密码和持久化)
docker run -d --name hft-redis \
  -p 6379:6379 \
  -v /data/redis:/data \
  redis:7.2 \
  redis-server --appendonly yes --requirepass "YourStrongPass"

验证连接:

import redis

r = redis.Redis(host='localhost', port=6379, password='YourStrongPass', decode_responses=True)
r.set('test_key', 'hello_hft')
print(r.get('test_key'))  # 输出: hello_hft

注意:高频交易场景下,Redis的appendonly模式会带来写性能损耗。如果只是做纯缓存,可以关掉持久化。但风控数据必须持久化,你想想看,万一宕机丢了订单状态,那损失可不是闹着玩的。

2.3 Kafka 配置 — 高吞吐消息总线

Kafka是风控引擎的「血管」。行情数据、订单指令、风控事件,全都要通过它流转。我见过有人用RabbitMQ做高频交易,延迟和吞吐量都扛不住,后来全换了Kafka。

同样用Docker部署,但Kafka依赖ZooKeeper(或者用KRaft模式,不过我个人觉得ZooKeeper更稳)。

# 创建docker-compose.yml
version: '3.8'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:7.5.0
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka:
    image: confluentinc/cp-kafka:7.5.0
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1

启动并创建主题:

docker-compose up -d

# 创建风控相关主题
docker exec -it hft-kafka-1 kafka-topics --create \
  --topic order_events \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 1

docker exec -it hft-kafka-1 kafka-topics --create \
  --topic risk_alerts \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 1

经验之谈:分区数不要设太多。我刚开始做的时候设了16个分区,结果消费者组重平衡时延迟飙升。高频交易场景,3-6个分区通常就够了。

2.4 Docker 容器化 — 环境一致性保障

Docker是解决「在我机器上能跑」问题的终极方案。风控引擎必须保证开发、测试、生产环境完全一致。

这是我的Dockerfile:

FROM python:3.10.11-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    gcc \
    libssl-dev \
    && rm -rf /var/lib/apt/lists/*

# 安装poetry
RUN pip install poetry==1.7.1

# 复制依赖文件
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false && poetry install --no-dev

# 复制源码
COPY . .

CMD ["python", "main.py"]

构建并运行:

docker build -t hft-risk-engine:latest .
docker run -d --name hft-engine \
  --network host \
  -v $(pwd)/config:/app/config \
  hft-risk-engine:latest

注意:使用--network host是为了减少网络延迟。在Kubernetes里你可能需要用hostNetwork模式。嗯,这里要注意,网络模式的选择直接影响延迟,别为了省事用bridge模式。

2.5 项目初始化 — 风控引擎骨架

最后,我们搭一个项目骨架。这是我多年总结的目录结构:

hft-risk-engine/
├── config/               # 配置文件
│   ├── redis.yaml
│   ├── kafka.yaml
│   └── risk_rules.yaml
├── src/
│   ├── __init__.py
│   ├── engine/           # 风控引擎核心
│   │   ├── __init__.py
│   │   ├── risk_engine.py
│   │   └── rules/
│   ├── adapters/         # 外部系统适配器
│   │   ├── redis_adapter.py
│   │   └── kafka_adapter.py
│   ├── models/           # 数据模型
│   │   ├── order.py
│   │   └── risk_event.py
│   └── utils/            # 工具函数
│       ├── logger.py
│       └── timer.py
├── tests/
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
└── main.py

初始化脚本:

mkdir -p src/{engine/rules,adapters,models,utils} config tests
touch src/__init__.py src/engine/__init__.py src/engine/rules/__init__.py
touch src/adapters/__init__.py src/models/__init__.py src/utils/__init__.py
touch config/redis.yaml config/kafka.yaml config/risk_rules.yaml
touch main.py

写一个简单的启动入口:

# main.py
import yaml
from src.adapters.redis_adapter import RedisAdapter
from src.adapters.kafka_adapter import KafkaAdapter
from src.engine.risk_engine import RiskEngine

def main():
    # 加载配置
    with open('config/redis.yaml') as f:
        redis_config = yaml.safe_load(f)
    with open('config/kafka.yaml') as f:
        kafka_config = yaml.safe_load(f)

    # 初始化适配器
    redis_adapter = RedisAdapter(redis_config)
    kafka_adapter = KafkaAdapter(kafka_config)

    # 启动风控引擎
    engine = RiskEngine(redis_adapter, kafka_adapter)
    engine.start()

if __name__ == '__main__':
    main()

2.6 本章知识体系

下面这张图,是我手绘的架构关系。你看一眼就能明白各组件怎么配合:

Python 3.10+ 风控引擎运行时 Redis 7.2 状态存储 / 缓存 Kafka 7.5 消息总线 Docker 容器化环境 风控规则引擎 订单处理模块 监控告警模块 共享配置与日志

环境搭好了,骨架也立起来了。接下来就可以往里面填风控逻辑了。记住,环境一致性是高频交易的命根子,别在这上面偷懒。


专注资料整理