传统架构里的两套数据
过去要同时支撑在线交易和数据分析,通常要搭两套系统:一套行存数据库扛交易,一套分析型系统扛报表,中间用 ETL 定期抽取。这套 Lambda 架构带来三个长期痛点:
- 链路长:任何一环延迟都会让报表数据变旧,通常只能做到 T+1;
- 口径不一致:交易库和报表库各有一套计算逻辑,对不上数时排查成本极高;
- 维护成本高:同步任务、调度依赖、补数流程都需要专门的人力维护。
HTAP 的思路是让同一份数据同时服务两类负载,从根上消掉 ETL 环节。
行列混算的实现基础
交易负载需要行存:按主键读取整行、频繁更新少量列。分析负载需要列存:只扫描少数列但涉及大量行,列式存储能大幅减少 IO 并提高压缩率。两者需求相反,因此 HTAP 系统通常同时提供两类存储引擎。
以 TiDB 为例,它提供两个存储引擎:行存的 TiKV 与列存的 TiFlash。TiFlash 通过 Multi-Raft Learner 协议从 TiKV 实时复制数据,从而保证列存副本与行存数据保持一致。TiDB Server 会根据查询特征,决定把计算分发到 TiKV 还是 TiFlash,从而在同一个查询框架内完成行列混算。
关键点在于「实时」二字:列存副本是跟随 Raft 日志同步出来的,不是定时批量导出的,因此分析侧看到的数据新鲜度可以达到秒级甚至更低。
查询是怎么被分流的
优化器在生成物理计划时,会根据代价以及表的副本可用性来选择读路径,常见判断依据包括:
- 查询涉及的列数与行数规模,大范围扫描倾向列存;
- 是否存在高选择性的点查条件,点查倾向行存;
- 是否显式指定了读取引擎(部分系统支持通过提示强制走某一路);
- 列存副本的健康状态与同步延迟。
这意味着同一个业务库上的点查和大范围聚合,可以被自动路由到最合适的引擎上,业务 SQL 无需改写。
资源隔离不能忽略
把分析负载引进来,最大的风险是分析查询把交易资源挤占掉。一个不设限的大范围聚合可能吃掉大量 CPU 和内存,直接影响在线订单。因此落地时必须考虑隔离手段:
- 列存副本部署在独立节点上,避免与行存争抢物理资源;
- 对分析类查询设置资源组或并发上限,限制其最大影响面;
- 错峰执行超重报表,或为报表单独规划只读副本;
- 监控列存同步延迟,延迟异常时及时摘除该副本参与查询。
适用场景判断
HTAP 最适合的场景是「对数据新鲜度敏感、但分析复杂度中等」的业务,例如实时看板、风控决策、库存与订单联动分析。如果分析需求是超大规模的历史数据挖掘、复杂的多表关联建模,专业数仓仍有其价值。选型时应先明确数据新鲜度要求与查询复杂度,再决定是否需要 HTAP。
| 行存引擎 | 面向交易,按行组织,适合点查与频繁更新少量列 |
|---|---|
| 列存引擎 | 面向分析,按列组织,适合大范围扫描与聚合,压缩率高 |
| 数据同步 | 列存副本通过 Raft Learner 角色实时跟随行存日志,保证一致性 |
| 读路径选择 | 优化器依据代价、选择性与副本状态自动决定读行存还是列存 |
| 资源隔离 | 独立节点部署、资源组限额、错峰执行、同步延迟监控 |