You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
11 KiB

# Redis缓存架构设计
## 一、设计概述
本Redis缓存架构用于存储股票分析系统的热点数据减少对数据源和数据库的访问提高系统响应速度。设计采用Redis作为缓存层主要存储以下数据
- 实时行情数据
- 板块动量数据
- 市场统计数据
- K线历史数据
- 计算结果缓存
## 二、缓存键设计
### 1. 实时行情缓存
| 缓存类型 | 缓存键格式 | 数据结构 | 过期时间 | 描述 |
|---------|-----------|---------|---------|------|
| 单只股票实时行情 | `realtime:stock:{code}` | Hash | 30分钟 | 存储单只股票的实时行情数据 |
| 全市场实时行情 | `realtime:full` | String | 30分钟 | 存储全市场股票的实时行情数据(压缩) |
| ETF实时行情 | `realtime:etf:{code}` | Hash | 30分钟 | 存储ETF的实时行情数据 |
| 实时行情批次 | `realtime:batch` | Set | 1小时 | 记录最近更新的股票代码 |
### 2. 板块数据缓存
| 缓存类型 | 缓存键格式 | 数据结构 | 过期时间 | 描述 |
|---------|-----------|---------|---------|------|
| 板块动量 | `sector:momentum:{period}:{sort}:{order}:{limit}` | Sorted Set | 1小时 | 存储板块动量数据,按动量值排序 |
| 板块成分股 | `sector:stocks:{sector_code}` | List | 24小时 | 存储板块的成分股列表 |
| 板块基本信息 | `sector:info:{sector_code}` | Hash | 24小时 | 存储板块的基本信息 |
### 3. 市场数据缓存
| 缓存类型 | 缓存键格式 | 数据结构 | 过期时间 | 描述 |
|---------|-----------|---------|---------|------|
| 市场统计 | `market:stats` | Hash | 1小时 | 存储市场统计数据 |
| 指数数据 | `market:index:{code}` | Hash | 1小时 | 存储指数的实时数据 |
| 涨跌分布 | `market:distribution` | Hash | 1小时 | 存储市场涨跌分布数据 |
### 4. K线数据缓存
| 缓存类型 | 缓存键格式 | 数据结构 | 过期时间 | 描述 |
|---------|-----------|---------|---------|------|
| K线数据 | `kline:{code}:{period}:{days}` | List | 1天 | 存储股票的K线数据 |
| K线数据压缩 | `kline:compressed:{code}:{period}:{days}` | String | 1天 | 存储压缩后的K线数据 |
### 5. 计算结果缓存
| 缓存类型 | 缓存键格式 | 数据结构 | 过期时间 | 描述 |
|---------|-----------|---------|---------|------|
| 技术指标 | `indicator:{code}:{indicator}:{params}` | Hash | 1天 | 存储计算好的技术指标 |
| 选股结果 | `stock:selection:{strategy}:{params}` | Set | 1小时 | 存储选股策略的结果 |
| 回测结果 | `backtest:{strategy}:{params}` | Hash | 24小时 | 存储回测结果 |
## 三、数据结构选择
### 1. Hash
- **适用场景**:存储结构化数据,如实时行情、板块信息
- **优点**
- 支持字段级操作,节省内存
- 适合存储对象类型数据
- 查找速度快
- **示例**
```
HSET realtime:stock:600519 price 1800.00 change_pct 2.50 volume 1000000
HGETALL realtime:stock:600519
```
### 2. Sorted Set
- **适用场景**:需要排序的数据,如板块动量排名
- **优点**
- 自动排序
- 支持范围查询
- 适合Top-N查询
- **示例**
```
ZADD sector:momentum:5:desc:20 12.5 HY001 10.2 HY002 8.7 HY003
ZRANGE sector:momentum:5:desc:20 0 9 WITHSCORES
```
### 3. List
- **适用场景**存储有序数据如K线数据、成分股列表
- **优点**
- 支持顺序访问
- 适合存储时间序列数据
- 支持范围查询
- **示例**
```
LPUSH kline:600519:1d:30 {"date":"2023-01-01","open":1700,"high":1800,"low":1650,"close":1750}
LRANGE kline:600519:1d:30 0 -1
```
### 4. Set
- **适用场景**:存储唯一数据,如股票代码集合
- **优点**
- 自动去重
- 支持集合操作
- 适合存储标签类数据
- **示例**
```
SADD sector:stocks:HY001 600000 601398 601288
SMEMBERS sector:stocks:HY001
```
### 5. String
- **适用场景**:存储任意数据,如全市场实时行情(压缩)
- **优点**
- 灵活存储任意格式数据
- 支持二进制数据
- 适合存储大体积数据
- **示例**
```
SET realtime:full "{compressed json data}" EX 1800
GET realtime:full
```
## 四、缓存策略
### 1. 写入策略
#### 实时数据
- **主动更新**定时任务每30秒拉取全市场数据更新Redis
- **惰性更新**:当缓存过期时,请求触发更新
- **批量更新**使用Pipeline批量写入减少网络往返
#### 计算数据
- **预计算**:定时任务提前计算板块动量、技术指标等
- **按需计算**:首次请求时计算并缓存
- **增量计算**:只更新变化的数据
### 2. 读取策略
- **优先缓存**先从Redis读取未命中再从数据库读取
- **缓存预热**:服务启动时预热热门数据
- **降级策略**Redis不可用时直接从数据库读取
### 3. 过期策略
- **时间过期**:设置合理的过期时间
- **主动清理**:定期清理过期数据
- **内存限制**设置Redis最大内存使用LRU策略
### 4. 缓存一致性
- **先更新数据库,后更新缓存**:确保数据一致性
- **缓存标记失效**:更新数据库后,标记缓存失效,下次读取时更新
- **定期全量同步**:定时全量同步数据,确保最终一致性
## 五、部署方案
### 1. 单节点部署
- **适用场景**:开发/测试环境
- **配置**
- 内存4GB+
- 端口6379
- 持久化RDB + AOF
### 2. 主从复制
- **适用场景**:生产环境
- **配置**
- 主节点:负责写入
- 从节点:负责读取
- 复制方式:异步复制
### 3. 哨兵模式
- **适用场景**:生产环境,需要高可用性
- **配置**
- 3个哨兵节点
- 自动故障转移
- 监控主从状态
### 4. 集群模式
- **适用场景**:大数据量场景,需要水平扩展
- **配置**
- 3个主节点3个从节点
- 数据分片
- 自动重平衡
## 六、性能优化
### 1. 内存优化
- **数据压缩**使用Redis的压缩列表
- **键空间优化**:使用哈希标签减少键冲突
- **内存淘汰策略**:设置合适的内存淘汰策略
### 2. 网络优化
- **Pipeline**:批量执行命令,减少网络往返
- **连接池**使用连接池管理Redis连接
- **批量操作**使用MSET、MGET等批量命令
### 3. 命令优化
- **使用Hash存储对象**:减少键数量
- **使用Sorted Set排序**利用Redis内置排序
- **避免使用KEYS命令**使用SCAN替代
### 4. 监控与调优
- **监控指标**
- 内存使用情况
- 命中率
- 命令执行时间
- 连接数
- **调优参数**
- maxmemory
- maxmemory-policy
- hash-max-ziplist-entries
- hash-max-ziplist-value
## 七、缓存工具类设计
### 1. 缓存操作接口
```python
class RedisCache:
def get(self, key):
"""获取缓存"""
pass
def set(self, key, value, expire=None):
"""设置缓存"""
pass
def delete(self, key):
"""删除缓存"""
pass
def hash_get(self, key, field):
"""获取Hash字段"""
pass
def hash_set(self, key, field, value):
"""设置Hash字段"""
pass
def sorted_set_add(self, key, score, member):
"""添加到有序集合"""
pass
def sorted_set_range(self, key, start, end, withscores=False):
"""获取有序集合范围"""
pass
```
### 2. 缓存键生成器
```python
class CacheKeyGenerator:
@staticmethod
def get_stock_realtime_key(code):
return f"realtime:stock:{code}"
@staticmethod
def get_sector_momentum_key(period, sort, order, limit):
return f"sector:momentum:{period}:{sort}:{order}:{limit}"
@staticmethod
def get_kline_key(code, period, days):
return f"kline:{code}:{period}:{days}"
```
### 3. 缓存管理器
```python
class CacheManager:
def __init__(self, redis_client):
self.redis = redis_client
self.key_generator = CacheKeyGenerator()
def get_stock_realtime(self, code):
"""获取股票实时行情"""
key = self.key_generator.get_stock_realtime_key(code)
return self.redis.get(key)
def set_stock_realtime(self, code, data, expire=1800):
"""设置股票实时行情"""
key = self.key_generator.get_stock_realtime_key(code)
return self.redis.set(key, data, expire)
def get_sector_momentum(self, period, sort, order, limit):
"""获取板块动量"""
key = self.key_generator.get_sector_momentum_key(period, sort, order, limit)
return self.redis.sorted_set_range(key, 0, limit-1, withscores=True)
```
## 八、监控与告警
### 1. 监控指标
| 指标 | 描述 | 阈值 |
|------|------|------|
| 内存使用率 | Redis内存使用百分比 | >80% |
| 命中率 | 缓存命中次数/总请求次数 | <80% |
| 连接数 | 当前Redis连接数 | >1000 |
| 命令执行时间 | 平均命令执行时间 | >1ms |
| 过期键数量 | 过期键占比 | >50% |
### 2. 告警策略
- **内存告警**内存使用率超过80%时告警
- **命中率告警**命中率低于80%时告警
- **连接数告警**连接数超过1000时告警
- **错误率告警**命令错误率超过1%时告警
### 3. 监控工具
- **Prometheus**收集Redis指标
- **Grafana**:可视化监控面板
- **Redis Exporter**导出Redis指标
- **Alertmanager**:处理告警
## 九、安全考虑
### 1. 访问控制
- **密码认证**设置Redis密码
- **IP白名单**限制访问IP
- **ACL**使用Redis 6.0+的ACL功能
### 2. 数据安全
- **数据加密**:对敏感数据进行加密
- **定期备份**定期备份Redis数据
- **灾难恢复**:制定灾难恢复计划
### 3. 网络安全
- **网络隔离**Redis服务放在内网
- **SSL加密**使用SSL加密传输
- **防火墙**:配置防火墙规则
## 十、扩展性考虑
### 1. 数据分片
- **水平分片**:按股票代码范围分片
- **垂直分片**:按数据类型分片
- **一致性哈希**:使用一致性哈希算法
### 2. 读写分离
- **主节点**:处理写入请求
- **从节点**:处理读取请求
- **负载均衡**:使用负载均衡器分发请求
### 3. 集群扩展
- **自动扩缩容**:根据负载自动扩缩容
- **滚动升级**:支持无停机升级
- **跨区域部署**:支持多区域部署
## 十一、总结
Redis缓存架构设计采用多种数据结构和缓存策略为股票分析系统提供高性能、高可靠性的数据访问层。通过合理的缓存键设计、数据结构选择和缓存策略可以显著减少对数据源和数据库的访问提高系统响应速度同时保证数据的一致性和可靠性。
该设计不仅满足当前系统的需求,还为未来的扩展和优化预留了空间,能够应对数据量增长和业务需求变化的挑战。