链上交易和K线-爬算存查询模块复盘
- K线连续性
- 必须保证 K 线图的连续性,当前 K 线的开盘价必须与前一根 K 线的收盘价平滑衔接。即使在系统重启或状态丢失的情况下,K 线连续性也必须得到保障。
- 数据顺序性: 对于同一交易标的(如交易对),交易数据必须按照时间顺序严格处理,这是保证 K 线计算连续性的基础。
- 实时性要求: K 线计算必须是实时的,能够及时反映最新的交易数据,并快速更新展示。
- 海量时序数据的高效存储与查询
- 数据规模: 系统需要能够存储和管理十亿级别甚至更大规模的金融交易数据和 K 线数据,且数据量持续快速增长。
- 数据类型特点: 数据本质是典型的时序数据,包含时间戳、价格、成交量等关键信息。
- 高性能查询: 需要支持对海量数据进行毫秒级的实时查询,以满足 K 线图的快速展示和用户交互需求。
- 复杂查询与分析: 除了基本的 K 线数据查询,还需要支持更复杂的查询和聚合分析,例如按时间范围、交易标的查询,以及技术指标的计算等,为深入分析提供支持。
- 数据一致性、可靠性与状态管理
- 数据一致性: 必须保证数据的事务完整性,尤其是在处理区块数据时,要确保一个区块内的交易数据要么全部成功,要么全部失败。
- 数据持久化: 为了保证数据不丢失,即使系统发生故障,数据也必须能够持久化存储,并支持快速恢复。
- 可靠状态管理: 在流式数据处理场景下,需要建立可靠的状态管理机制,保证 K 线计算过程中的状态能够正确维护和恢复,从而确保 K 线计算的连续性和准确性。
- 处理区块链分叉与区块回滚:
- 分叉识别与回滚检测: 系统必须能够及时识别区块链网络中发生的分叉,并检测到区块回滚事件。
- 数据还原与状态回退: 当区块回滚发生时,系统需要能够自动还原已经抓取的交易数据和计算出的 K 线数据,并将系统状态回退到回滚发生之前的状态。
- 重新抓取与计算: 系统需要能够回退到分叉点之前的区块,并从那里开始重新抓取交易数据,重新进行 K 线计算,保证最终数据的准确性和链上数据的最终一致性。
需求总结
构建这样一个系统,核心挑战不仅在于海量、实时、动态变化的区块链金融数据处理和高性能 K 线计算与查询,更在于如何应对区块链自身的不确定性,即处理区块链分叉和区块回滚,并在所有环节都保证数据的一致性和可靠性。 这需要更加精细的设计和更加健壮的技术方案,才能构建真正可靠的区块链金融数据分析系统。
方案1: MySQL方案
-
数据流:
-
爬虫: 抓取区块链数据。
-
内存处理: 在应用程序内存中解析交易数据并计算 K 线。
-
MySQL 事务:
- 将原始交易数据插入
transactions表。 - 将计算好的 K 线数据插入
klines表。 - 更新进度表: 在
progress表中记录最新的已处理区块高度。
- 将原始交易数据插入
-
WebSocket 推送: 通过 WebSocket 将 K 线推送到前端。
-
-
容错和恢复:
- 进度追踪: MySQL 中的
progress表充当持久化的检查点,记录最后成功处理的区块高度。 - 重启恢复: 系统崩溃重启后,从
progress表读取最后处理的区块高度,并从下一个区块开始继续抓取和处理。 - 事务原子性: MySQL 事务确保所有操作(交易插入、K 线插入、进度更新)要么全部成功,要么全部失败,保证数据一致性,防止部分更新。
- 进度追踪: MySQL 中的
方案2: Kafka + Flink + 专用数据库
数据流:
-
爬虫 (Crawler): 抓取区块链节点数据,包括区块和交易数据。
-
Kafka 消息队列: 爬虫将抓取的交易数据作为消息,推送到 Kafka Topic 中。
-
Flink 流处理:
- Flink 应用程序从 Kafka Topic 中消费交易数据流。
- 内存处理: Flink 在内存中进行流式数据处理,解析交易数据并进行 K 线计算。
- 状态管理: Flink 使用 State Backend (例如 RocksDB) 持久化 K 线计算的中间状态,保证状态的可靠性和容错性。
-
专用数据库 (ClickHouse / DolphinDB): Flink 将计算好的 K 线数据以及原始交易数据批量写入专用数据库中进行持久化存储。
-
WebSocket 推送: 后端服务 (例如独立的 API 服务或 Flink 应用程序的一部分) 从专用数据库中查询最新的 K 线数据,并通过 WebSocket 服务实时推送给前端。
容错和恢复:
- Kafka 数据持久化与副本机制: Kafka 将消息持久化到磁盘,并支持多副本机制。即使 Kafka Broker 发生故障,数据也不会丢失,且可以从其他副本恢复,保证消息队列的高可用性和数据可靠性。
- Flink Checkpointing: Flink 的 Checkpointing 机制定期将 Flink 应用程序的状态 (包括 K 线计算中间状态和 Kafka 消费位点 Offset) 持久化到外部存储系统 (例如 HDFS, S3, RocksDB)。 当 Flink 任务发生故障重启时,可以从最近一次成功的 Checkpoint 恢复状态,保证数据处理的一致性,并实现 Exactly-Once 语义。
- Flink State Backend 持久化: Flink 的 State Backend (例如 RocksDBStateBackend) 将状态数据持久化到外部存储,防止 TaskManager 故障导致状态丢失,保证 K 线计算的连续性。
- 专用数据库数据可靠性: 专用数据库 (ClickHouse 或 DolphinDB) 通常具备良好的数据可靠性和高可用性机制,例如数据副本、数据持久化、集群管理等,保证数据存储的可靠性和查询服务的稳定性。
- 监控与告警: 完善的监控和告警系统,实时监控 Kafka 集群、Flink 集群、数据库集群以及爬虫程序的运行状态,及时发现和处理异常情况,保障系统的稳定运行。
方案比较
| 特性 | 只用MySQL | Kafka + Flink + 专用数据库 |
|---|---|---|
| 延迟 | 可能更低 (在极低负载场景下) | 较高 (由于分布式组件,但可优化至毫秒级) |
| 吞吐量/扩展性 | 有限 | 极高 (分布式架构) |
| 可靠性/容错性 | 已提升 (进度追踪,事务更新) | 优秀 (分布式,检查点,副本机制) |
| 数据一致性 | 良好 (MySQL 事务保证) | 优秀 (Flink Exactly-Once, Kafka 副本,数据库事务) |
| K 线计算复杂度 | 有限 (手动实现,可能复杂的 SQL) | 优秀 (Flink 窗口,专用数据库函数) |
| 分析查询性能 | 有限 (MySQL OLTP 数据库) | 优秀 (专用 OLAP 数据库 - ClickHouse/DolphinDB) |
| 复杂度 | 初始设置更简单 | 设置和管理更复杂 |
| 可维护性 | 随着复杂度增加,维护难度可能增加 | 长期来看,模块化设计更易维护 |
| 成本 | 初始成本较低 (单机) | 初始成本较高 (分布式基础设施) |
参考
-
learnblockchain.cn/article/654… // kafka+flink方案可以参考这个,不过还实现了多版本可以迅速回滚,这个也是chainbase的技术方案
-
github.com/spalladino/… // 本地测试分叉
-
github.com/flashbots/r… // 查找分叉点的算法
-
blog.csdn.net/sinat_33261… // 一种mongodb存储的尝试