2. 技术选型:实时计算框架与存储的实战抉择
做实时指标开发,第一步不是写代码,而是选工具。选错了,后面全是坑。我这些年换过好几套技术栈,踩过的雷不少,今天把核心经验摊开来讲。
核心原则:没有最好的技术,只有最适合你场景的选型。实时计算尤其如此——延迟、吞吐、状态管理、运维成本,每个维度都得权衡。
2.1 实时计算框架对比:Flink vs Spark Streaming vs Storm
这三个框架我都用过。Storm 是我最早接触的,后来转 Spark Streaming,最近几年主力是 Flink。说说我的真实感受。
| 维度 | Flink | Spark Streaming | Storm |
|---|---|---|---|
| 处理模型 | 真正的流处理(逐条) | 微批次(Mini-Batch) | 逐条处理 |
| 延迟 | 毫秒级 | 秒级(批次间隔决定) | 毫秒级 |
| 状态管理 | 内置强大,支持 Checkpoint | 需借助外部存储 | 需自己实现 |
| Exactly-Once | 原生支持 | 支持(需配置) | 需额外处理 |
| SQL 支持 | Flink SQL 成熟 | Structured Streaming | 无原生 SQL |
| 运维复杂度 | 中等 | 较低(基于 YARN) | 较高 |
Flink:我现在的首选
Flink 的流处理是真正的「来一条处理一条」。它内置的状态后端和 Checkpoint 机制,让故障恢复变得很优雅。我个人习惯用 Flink 做需要精确一次语义的场景,比如金融风控、实时对账。
我的经验:Flink 的 Watermark 机制处理乱序数据很顺手。曾经有个电商大促项目,用户点击流延迟严重,靠 Flink 的 allowedLateness 完美解决了数据迟到问题。
Spark Streaming:适合批流一体
Spark Streaming 本质是微批次。如果你团队已经用了 Spark 做离线,那 Streaming 的学习成本很低。但要注意,它的延迟受批次间隔限制,做不到真正的毫秒级。
我记得有个日志分析项目,业务方说「秒级就行」,我们用了 Spark Streaming。后来业务增长,批次间隔从 5 秒缩到 2 秒,吞吐就扛不住了。嗯,这里要注意——微批次在高峰期容易产生背压。
Storm:老将,但已边缘化
Storm 是实时计算的先驱,延迟极低。但它的状态管理太弱,Exactly-Once 实现起来很痛苦。我曾经维护过一个 Storm 集群,拓扑一挂,状态全丢,得手动补数据。后来我们全迁到了 Flink。
避坑指南:新项目不建议选 Storm。除非你维护的是遗留系统,且短期内没有重构计划。否则,选 Flink 更稳妥。
2.2 消息队列选型:Kafka vs Pulsar
消息队列是实时指标的「血管」。数据从源头到计算层,全靠它输送。我主要用 Kafka,Pulsar 也调研过,各有千秋。
| 维度 | Kafka | Pulsar |
|---|---|---|
| 架构 | Broker + Partition | Broker + BookKeeper(存算分离) |
| 消息持久化 | 磁盘顺序写 | BookKeeper 分段存储 |
| 延迟 | 毫秒级 | 毫秒级 |
| 重平衡 | Stop-the-World | 无感 |
| 多租户 | 需手动隔离 | 原生支持 |
| 生态 | 极其成熟 | 快速发展中 |
Kafka:生态之王
Kafka 的生态太强了。Flink、Spark、各种 Connector 都优先支持它。我个人习惯用 Kafka 做实时指标的数据总线,吞吐高、延迟低,运维也成熟。
但 Kafka 有个痛点——重平衡。消费者组变动时,所有分区会暂停消费。我曾经在高峰期触发过重平衡,导致数据堆积了几分钟。后来我们控制了消费者组的变动频率,才缓解了这个问题。
Pulsar:存算分离的革新者
Pulsar 的存算分离架构很吸引人。Broker 无状态,BookKeeper 负责存储,扩容时数据不用迁移。它的重平衡是无感的,不会 Stop-the-World。
我记得有个多租户项目,不同业务线需要隔离。Pulsar 原生支持 Namespace 和策略,比 Kafka 的 ACL 管理方便很多。不过 Pulsar 的生态还在追赶,有些 Connector 需要自己写。
我的建议:如果团队 Kafka 经验丰富,且不需要多租户,继续用 Kafka 没问题。如果追求弹性伸缩和多租户隔离,Pulsar 值得一试。
2.3 存储选型:HBase vs Redis vs ClickHouse
实时指标算出来之后,存哪里?这取决于你的查询场景。我按用途分了三类。
| 存储 | 适用场景 | 延迟 | 数据模型 | 一致性 |
|---|---|---|---|---|
| HBase | 海量 Key-Value 查询、宽表 | 毫秒级 | 列族 | 强一致 |
| Redis | 缓存、计数器、排行榜 | 微秒级 | 多种结构 | 最终一致(集群) |
| ClickHouse | OLAP 分析、聚合查询 | 秒级 | 列式 | 最终一致 |
HBase:海量实时查询的基石
HBase 适合存维度宽表或实时明细。它的 RowKey 设计很关键,直接影响查询性能。我习惯把业务主键和时间戳拼在一起,避免热点。
曾经有个用户画像项目,每天写入几十亿条记录。HBase 的 LSM-Tree 结构扛住了写入压力,查询延迟稳定在 5ms 以内。但要注意,HBase 的运维成本不低,Region Server 的 Split 和 Compaction 需要调优。
避坑指南:HBase 不适合做高频更新。它的更新本质是追加新版本,读时合并。如果指标需要频繁更新,考虑用 Redis 做缓存层。
Redis:缓存与计数器的首选
Redis 的延迟极低,适合做实时指标的缓存层。我常用它存排行榜、UV 去重(HyperLogLog)、限流计数器。
但 Redis 的内存成本高,数据量大了之后,集群扩容和持久化都是问题。我记得有个项目,Redis 集群存了 500GB 数据,RDB 持久化时阻塞了主线程,导致几秒的延迟抖动。后来我们切到了 Redis Cluster + 异步持久化。
ClickHouse:实时 OLAP 的利器
ClickHouse 的列式存储和向量化执行,让聚合查询快得离谱。我习惯用它做实时报表和 Ad-hoc 分析。比如,实时计算出的指标写入 ClickHouse,前端 Dashboard 秒级刷新。
但 ClickHouse 的写入是批量追加,不适合单条更新。如果指标需要精确一次语义,得配合幂等写入。我有个项目用 ReplacingMergeTree 去重,效果不错。
我的组合拳:实时指标场景,我常用「Flink + Kafka + Redis + ClickHouse」。Flink 消费 Kafka 数据,实时计算结果写入 Redis(缓存)和 ClickHouse(分析),各司其职。
2.4 技术选型全景图
下面这张图,是我总结的实时指标技术选型全景。你可以根据业务场景,从下往上选。
2.5 选型决策清单
最后,我整理了一份决策清单。你选型时,可以对照着问自己几个问题。
- 延迟要求多高?毫秒级选 Flink,秒级可接受 Spark Streaming。
- 状态管理复杂吗?复杂(如聚合、去重)选 Flink,简单可考虑 Spark。
- 团队技术栈?已有 Spark 生态选 Spark Streaming,新项目推荐 Flink。
- 消息队列规模?日均百亿级选 Kafka,多租户弹性选 Pulsar。
- 查询模式?点查用 HBase,缓存用 Redis,分析用 ClickHouse。
- 运维能力?团队强可上 HBase + ClickHouse,否则优先托管服务。
总结一句话:实时指标选型,没有银弹。把场景想清楚,把团队能力评估好,选最顺手的组合。我这些年换过好几套,最终沉淀下来的就是「Flink + Kafka + Redis + ClickHouse」这套黄金组合。你可以从它开始,再根据实际情况调整。