高频L2行情数据Redis存储架构设计(含C++实现代码)
mhr18 2025-05-16 14:54 32 浏览 0 评论
一、Redis核心设计原则
- 内存高效:优化数据结构,减少内存占用
- 低延迟访问:单次操作≤0.1ms响应时间
- 数据完整性:完整存储所有L2字段
- 实时订阅:支持多客户端实时数据推送
- 持久化策略:RDB+AOF保障数据安全
二、数据结构设计与键规范
2.1 键命名规范
数据类型 | 键模式 | 示例 | 说明 |
盘口数据 | orderbook:{symbol} | orderbook:600000.SH | Hash存储最新盘口 |
逐笔委托流 | ts:order:{symbol} | ts:order:600000.SH | TimeSeries时间序列 |
逐笔成交流 | ts:trade:{symbol} | ts:trade:600000.SH | TimeSeries时间序列 |
委托订单索引 | order:{order_id} | order:1234567890123456 | Hash存储单笔委托详情 |
历史快照 | snapshot:{symbol}:{ts} | snapshot:600000.SH:1629126000 | ZSET存储时间索引 |
三、详细数据存储方案
3.1 盘口数据(OrderBook)
# 存储结构
HSET orderbook:600000.SH \
"update_time" "1629123456789" \
"bid1_px" "12.34" \
"bid1_vol" "5000" \
"bid1_ord" "3" \
"ask1_px" "12.35" \
"ask1_vol" "6000" \
"ask1_ord" "2" \
... # bid2~bid5, ask2~ask5 \
"total_bid" "25000" \
"total_ask" "30000"
# 字段说明表
| 字段名 | 数据类型 | 示例值 | 对应L2字段 |
|----------------|----------|------------|--------------------------|
| update_time | String | 1629123456789 | OrderBook.update_time |
| bid{1-5}_px | Double | 12.34 | OrderBook.BidLevels[i].price |
| bid{1-5}_vol | Integer | 5000 | OrderBook.BidLevels[i].volume|
| bid{1-5}_ord | Integer | 3 | OrderBook.BidLevels[i].orders|
| total_bid | Integer | 25000 | OrderBook.total_bid_vol |
设计理由:
- Hash结构:单次HSET原子更新全部档位
- 扁平化存储:避免嵌套结构,直接映射L2原始数据
- 快速访问:通过HGETALL一次获取完整盘口
3.2 逐笔委托(OrderDetail)
# 时间序列存储(纳秒级精度)
TS.CREATE ts:order:600000.SH
RETENTION 86400000 # 保留24小时数据
LABELS symbol 600000.SH type order
# 写入数据(时间戳单位:毫秒)
TS.ADD ts:order:600000.SH 1629123456789
"order_id:1234567890|price:12.34|vol:5000|dir:B|type:A"
# 独立存储订单详情
HSET order:1234567890
"symbol" "600000.SH"
"time" "1629123456789"
"price" "12.34"
"vol" "5000"
"dir" "B"
"type" "A"
"related" "0"
字段编码规则:
value格式:field1:value1|field2:value2...
示例:order_id:123456|price:12.34|vol:5000|dir:B|type:A
设计理由:
- TimeSeries模块:
- 自动按时间排序,支持范围查询(TS.RANGE)
- 内置降采样(TS.DOWNAMPLE),快速生成分钟级统计
- Hash存储:独立存储订单详情,避免重复数据
3.3 逐笔成交(Transaction)
# 成交流(Stream结构)
XADD stream:trade:600000.SH *
time 1629123456789000
bid_order 1234567890
ask_order 1234567891
price 12.35
vol 100
type N
# 时间序列存储
TS.CREATE ts:trade:600000.SH
DUPLICATE_POLICY LAST
RETENTION 604800000 # 保留7天
Stream消息体结构:
{
"time": "1629123456789000", // 纳秒时间戳
"bid_order": "1234567890", // 买方订单号
"ask_order": "1234567891", // 卖方订单号
"price": "12.35", // 成交价格
"vol": "100", // 成交量
"type": "N" // 成交类型(N/C)
}
设计理由:
- Stream结构:
- 消息持久化,支持消费者组(Consumer Group)
- 严格有序,保证成交顺序
- TimeSeries冗余存储:支持时间范围快速统计
四、数据关系与访问模式
4.1 数据关联逻辑
4.2 典型访问场景
- 实时盘口查询
HGETALL orderbook:600000.SH
- 历史委托分析
TS.RANGE ts:order:600000.SH 1629123000000 1629123600000
- 成交回放
XREAD STREAMS stream:trade:600000.SH 0-0
- 订单溯源
HGETALL order:1234567890
五、C++接入实现
5.1 盘口更新示例
#include <hiredis/hiredis.h>
#include <string>
struct OrderBook {
std::string symbol;
int64_t update_time;
struct {
double price;
int volume;
int orders;
} bid[5], ask[5];
int total_bid, total_ask;
};
void update_orderbook(redisContext* c, const OrderBook& book) {
std::string key = "orderbook:" + book.symbol;
redisReply* reply = (redisReply*)redisCommand(c, "MULTI");
freeReplyObject(reply);
// 删除旧数据
reply = redisCommand(c, "DEL %s", key.c_str());
freeReplyObject(reply);
// 构造HSET命令
std::vector<const char*> args = {"HSET", key.c_str(),
"update_time", std::to_string(book.update_time).c_str()};
for (int i = 0; i < 5; ++i) {
std::string bid_px = "bid" + std::to_string(i+1) + "_px";
std::string bid_vol = "bid" + std::to_string(i+1) + "_vol";
args.insert(args.end(), {
bid_px.c_str(), std::to_string(book.bid[i].price).c_str(),
bid_vol.c_str(), std::to_string(book.bid[i].volume).c_str()
});
}
// 添加其他字段...
reply = redisCommandArgv(c, args.size(), args.data(), NULL);
if (reply->type == REDIS_REPLY_ERROR) {
// 错误处理
}
freeReplyObject(reply);
reply = redisCommand(c, "EXEC");
freeReplyObject(reply);
}
5.2 逐笔数据写入
#include <chrono>
void insert_order(redisContext* c, const OrderDetail& order) {
// 时间戳生成(C++11)
auto now = std::chrono::system_clock::now();
auto ts = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count();
// TimeSeries写入
redisReply* reply = (redisReply*)redisCommand(c,
"TS.ADD ts:order:%s %lld *",
order.symbol.c_str(),
ts);
// 构造value
std::string value =
"order_id:" + std::to_string(order.order_id) + "|" +
"price:" + std::to_string(order.price) + "|" +
"vol:" + std::to_string(order.volume) + "|" +
"dir:" + std::string(1, order.direction) + "|" +
"type:" + std::string(1, order.order_type);
if (reply->type == REDIS_REPLY_ERROR) {
// 错误处理
}
freeReplyObject(reply);
// 独立存储订单详情
reply = redisCommand(c,
"HSET order:%lld "
"symbol %s "
"time %lld "
"price %f "
"vol %d "
"dir %c "
"type %c "
"related %lld",
order.order_id,
order.symbol.c_str(),
ts,
order.price,
order.volume,
order.direction,
order.order_type,
order.related_order_id);
freeReplyObject(reply);
}
六、性能优化策略
6.1 内存管理
# 设置最大内存(根据服务器配置调整)
CONFIG SET maxmemory 64gb
# 内存淘汰策略
CONFIG SET maxmemory-policy volatile-lru
# 压缩Hash字段
CONFIG SET hash-max-ziplist-entries 512
CONFIG SET hash-max-ziplist-value 64
6.2 持久化配置
# RDB快照(每5分钟保存)
CONFIG SET save "300 1"
# AOF追加(每秒同步)
CONFIG SET appendfsync everysec
6.3 集群扩展
# 创建集群(3主3从)
redis-cli --cluster create \
192.168.1.101:6379 \
192.168.1.102:6379 \
192.168.1.103:6379 \
192.168.1.104:6379 \
192.168.1.105:6379 \
192.168.1.106:6379 \
--cluster-replicas 1
七、监控指标与容灾
7.1 关键监控项
指标 | 预警阈值 | 监控工具 |
内存使用率 | >85% | Redis INFO命令 |
网络延迟(P99) | >2ms | Prometheus+Granafa |
命令耗时(HSET) | >1ms | Redis慢查询日志 |
连接数 | >5000 | Zabbix |
7.2 容灾方案
- 主从复制:实时同步数据到备用节点
- 哨兵模式:自动故障转移
- 跨机房同步:使用redis-replicator工具
八、架构总结
8.1 方案优势
特性 | 实现方法 | 性能指标 |
亚毫秒级延迟 | 内存存储+Hash结构 | 单操作≤0.1ms |
高频写入支持 | Pipeline批量操作 | 50万次/秒(单节点) |
数据完整性 | 冗余存储(TimeSeries+Hash) | 零字段丢失 |
实时分析 | Stream消费者组 | 万级并发处理 |
8.2 适用场景
- 算法交易:实时获取盘口数据计算最优下单路径
- 风控引擎:监控异常委托/成交模式
- 行情分发:通过Pub/Sub向多个客户端广播
- 快速回测:从Stream回放历史数据
相关推荐
- JDK从8升级到21的问题集(jdk8版本)
-
一、背景与挑战1.升级动因oOracle长期支持策略o现代特性需求:协程、模式匹配、ZGC等o安全性与性能的需求oAI新技术引入的版本要求2.项目情况o100+项目并行升级的协同作战o多技术栈并存o持...
- 科莱特SAP ABAP干货 | 基础篇:二、数据字典(1)
-
ABAP开发基础及应用二、数据字典(1)目标及说明目标:1、掌握SAP数据字典各种对象的定义和使用2、能根据业务数据要求,建立存储数据用的表和视图需求说明:1、在SAP中自建程序,以对一企业(自由行集...
- Mycat入门(mycatalog)
-
一、Linux系统下搭建Mycat注:如果没有服务器可以选择虚拟机进行操作1、首先准备好服务器或者虚拟机2、安装和配置MySQL数据库2.1、删除原来的数据库//查询已安装的mariadb[root...
- MySQL从入门到实战:表设计、索引优化与高频面试解析
-
一、业务场景驱动表设计:电商订单系统案例场景背景某电商平台需设计用户、商品、订单模块,要求支持以下操作:用户高频查询最新订单按商品分类+价格区间筛选商品统计每日订单金额建表实战--用户表(反范式设计...
- oracle生成AWR报告的两种方法(oracle中awr报告的输出格式有哪些)
-
方法1:sqlplus中执行:execdbms_workload_repository.create_snapshot();@?/rdbms/admin/awrrpt.sql方法2:setpage...
- Navicat Premium:数据库管理神器(navicat 本地数据库)
-
提供免费下载网站Mavom.cn在数据库管理的世界里,「NavicatPremium」是一款「一体化的数据库管理和迁移工具」,适用于MySQL、SQLServer、Oracle和PostgreSQ...
- Iperius Backup功能特色(backup如何使用)
-
备份作业:1.文件夹备份:本地的文件夹,带SMB的路径文件夹,网络路径文件夹,NAS文件夹等等2.文件备份:对某个文件进行备份3.备份镜像:可以把系统刻录成镜像用于恢复(图1)4.FTP:自带FTP...
- sql注入攻击,拿到网站账户,黑客这样神操作
-
首先的话,我们来仔细搞清楚这个攻击的流程,第一步就是了解一下,什么是sql?又什么是sql注入、sql注入的流程和步骤。1、首先什么是sql,Sql是一种数据库查询和程序设计的语言,这里的数据库是指存...
- Java 8 新特性指南(java的八大特性)
-
本教程可以在实验楼(shiyanlou.com)中在线练习。一、实验简介Java8是近年来最后起来的一个Java编程语言发行版本。Oracle在2014年3月发布了它。该版本为Java带来...
- Java系统开发从入门到精通第三讲(文字版)
-
下来我们进入数据持久化的部分,对于一个真实的业务系统,能够正常的运转离不开数据的持久化。在数据持久化这块,目前主流的还是关系型数据库(RDBMS),NoSQL(NewSQL)也有了长足发展,特别在大数...
- 扣细节:while (true) 和 for (;;) 哪个更快
-
来源:zhihu.com/question/52311366/answer/130090347在JDK8u的jdk项目下做个很粗略的搜索:mymbp:/Users/me/workspace/jdk8u...
- JAVA 8 环境安装配置(java环境怎么装)
-
一、下载这里选择的是OracleJDK,首先到Oracle官网下载JDK8,以Windows10操作系统为例,若是32位系统则下载“Windowsx86”,否则64位系统下载“Windows...
- 从零开始学Java系列之最详细的Java环境变量配置教程
-
前言:在上一篇文章中,壹哥给大家重点讲解了Java实现跨平台的原理,不知道你现在有没有弄清楚呢?如果你还有疑问,可以在评论区留言~之前的三篇文章,主要是理论性的内容,其实你暂时跳过不看也是可以的,我们...
- Linux下乱码的文件名修改或删除(linux文件名乱码如何处理)
-
查看文件名#lstouch1?.txt#ll-itotal1469445217956913-rw-r--r--1oracleoinstall0Jan18...
- 「论文写作-解决方案」数据库TDE加密
-
数据是应用的核心。对于绝大多数应用,存储数据的数据库是系统日常管理的重中之重。数据库安全背景根据verizon2014年的统计数据,96%数据攻击行为是针对数据库进行的。数据库已经成为外部入侵与内部渗...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)