
采用“数据源校验层 + 高吞吐消息队列(Kafka) + Exactly-Once流处理引擎(Flink) + 事务化存储(Cassandra)”架构,通过交易所数据时间戳/校验和校验、Flink微批处理(1秒窗口)、Kafka 100分区+3副本、Cassandra按股票代码分区,结合Kafka事务与数据库事务,实现秒级延迟、高吞吐,并保证数据准确性与一致性。
老师口吻,解释核心组件及关键机制:
| 组件 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 数据源校验层 | 交易所数据预处理模块 | 时间戳验证、校验和检查 | 过滤无效Tick数据 | 需与交易所API对接,实时校验 |
| Kafka | 分布式消息队列 | 高吞吐(分区并行)、持久化、副本机制 | 数据缓冲、解耦系统 | 分区数=并发数/每分区吞吐,副本因子≥2 |
| Flink | 分布式流处理引擎 | Exactly-Once、微批处理、状态管理 | 实时计算、复杂事件处理 | 微批处理时间=1秒,并行度=CPU核心数*2 |
| Cassandra | 分布式数据库 | 高并发写入、水平扩展、分区键优化 | 持久化存储原始数据+聚合结果 | 分区键=股票代码,避免热点分区 |
伪代码展示最小可运行架构(含数据源校验、Kafka生产、Flink处理、Cassandra写入):
import json, hashlib, time
def validate_tick(data):
# 时间戳验证:当前时间±1秒内
if not (time.time() - 1 <= data['timestamp'] <= time.time() + 1):
return None
# 校验和验证:计算MD5并对比
expected_checksum = "expected_md5"
if hashlib.md5(json.dumps(data).encode()).hexdigest() != expected_checksum:
return None
return data
from kafka import KafkaProducer
producer = KafkaProducer(bootstrap_servers='kafka:9092',
value_serializer=lambda v: json.dumps(v).encode('utf-8'))
for tick in validated_ticks:
producer.send('stock-tick', tick)
from pyflink import StreamExecutionEnvironment
env = StreamExecutionEnvironment.get_execution_environment()
env.set_parallelism(32) # 并行度=CPU核心数*2
data_stream = env.add_source(KafkaSource(...))
processed = data_stream
.filter(lambda x: x['volume'] > 0) # 过滤无效数据
.key_by(lambda x: x['symbol']) # 按股票代码分组
.window(TumblingProcessingTimeWindow.of(Time.seconds(1))) # 1秒微批处理
.aggregate(lambda acc, cur: (acc[0] + cur['volume'], acc[1] + cur['price']),
lambda acc, cur: (acc[0] + cur['volume'], acc[1] + cur['price'])) # 聚合
.map(lambda x: {'symbol': x[0], 'avg_price': x[1]/x[0], 'total_volume': x[0]})
processed.write_output(RedisSink(...), CassandraSink(...)) # 写入缓存+数据库
BEGIN TRANSACTION;
INSERT INTO stock_tick (symbol, price, volume, timestamp) VALUES ('000001', 10.5, 1000, 1699112800);
INSERT INTO stock_agg (symbol, avg_price, total_volume, window_end) VALUES ('000001', 10.5, 1000, 1699112800);
COMMIT;
(约90秒,自然表达)
“面试官您好,针对每秒数千笔股票Tick数据的实时处理需求,我设计的架构核心是构建一个‘数据源校验 + 高吞吐消息队列 + Exactly-Once流处理引擎 + 事务化存储’的闭环系统。首先,数据源(交易所API)发送的Tick数据会先经过校验层,验证时间戳(是否在当前1秒窗口内)和校验和(MD5匹配),过滤无效数据,确保输入准确性。然后,数据进入Kafka,配置100个分区(每秒数千笔,分区数=并发数/每分区吞吐)和3副本,作为缓冲层解耦数据源与计算,避免数据丢失。接着,Flink消费Kafka数据流,设置微批处理时间为1秒(TumblingProcessingTimeWindow.of(Time.seconds(1))),并行度为CPU核心数*2(假设16核,并行度32),通过检查点机制(CheckpointInterval=5000ms)保证状态一致性,实现Exactly-Once语义。处理后的数据一方面写入Redis缓存热点聚合结果(如实时均价),另一方面通过Cassandra的ACID事务持久化,按股票代码分区(分区键=symbol),保证数据一致性。这样,整个架构既能通过微批处理将延迟控制在1秒以内,满足秒级延迟要求,又能通过Kafka事务(生产Kafka消息→写入数据库的原子操作)和数据库事务,确保数据准确性与一致性。”