第二章:开发环境搭建 — 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 本章知识体系
下面这张图,是我手绘的架构关系。你看一眼就能明白各组件怎么配合:
环境搭好了,骨架也立起来了。接下来就可以往里面填风控逻辑了。记住,环境一致性是高频交易的命根子,别在这上面偷懒。