写入先落行存:事务路径的起点
一条插入或更新语句进来,SQL计算层做完解析与计划生成,先打到行存节点。行存节点是支持分布式事务的键值存储引擎,数据按范围分片,每个分片多副本靠共识协议保一致。事务提交时走行存的主副本,写成功多数派才算提交返回客户端,这一步和单机事务库体验一致:低延迟、点查快、索引命中直接。
行存里数据按行组织,适合单次读写少量字段、频繁更新、走主键或二级索引定位。订单行、账户余额、库存扣减这类高并发短事务,全程只在行存里完成,不碰列存。这也是HTAP链路里事务侧零额外开销的关键——列存的存在对写入路径是异步负担,不是同步阻塞。
行存节点写下去的数据,会带全局时间戳打版本,供后面的多版本并发控制使用。这个时间戳由集群内的授时服务发放,严格单调递增,是整条链路一致性的锚点。如果没有这个全局时间戳,后续列存回放时无法判断哪些版本已经提交、哪些还在进行中,一致性就会崩溃。
行存写入的性能调优主要集中在三个方面。其一分片键的选择直接影响写入分布均匀性,热点分片会导致单节点成为写入瓶颈。其二事务批量提交的大小需要权衡——太大增加单次提交延迟,太小增加共识协议开销。其三行存缓冲池的大小决定了热数据的命中率,命中率高则写入路径短,不需要每次都落盘。
行到列的实时同步:学习者副本的角色
行存提交后,变更不会立刻进列存,而是通过一个轻量角色——学习者副本——实时复制事务日志。学习者不参与行存多副本的投票,只异步追日志,把行存里新增、修改、删除的行按列的格式重组写进列存区。
天翼云官网提到的借助共识协议学习者角色实现实时同步,本质是把共识协议的日志通道复用起来。行存分片每提交一个条目,学习者就能拿到,然后在列存侧按列切块、做字典编码或差值编码压缩落盘。因为学习者的同步不阻断事务提交,所以同步延迟可以压到亚秒甚至更低,又不会拖慢订单写入。
同步不是简单镜像。行存里的单行更新,到列存侧可能只影响某几列的块;删除靠版本标记;大事务靠日志流式回放。列存内部还会按时间或主键做微分区,热数据在内存列缓存、冷数据在磁盘列文件,查询时按列裁剪读取。这套转换让列存天生适合扫描某几列做聚合,而它和行存之间靠全局行标识关联,保证同一行在两个视图里能对上号。
同步延迟是衡量这条链路健康度的核心指标。延迟持续扩大说明学习者回放线程的CPU配额不足,或者列存写入IO带宽被其他查询挤占。调优时可以把学习者的CPU配额与事务线程分开设,确保写入高峰期同步不被饿死。另一个调优点是学习者副本的数量——太多会增加行存节点的日志分发负担,太少则单点故障时同步中断。
SQL解析与智能选路:一条语句怎么分叉
应用发来的SQL不区分事务还是分析,统一进SQL计算节点。解析器生成逻辑计划后,优化器基于代价做两件关键事:估算查询特征、选存储访问路径。
点查、带主键等值的查询、小范围索引扫描、插入更新删除操作,优化器判为事务型,计划里访问路径指向行存分片,走行存索引定位,结果直接返回。全表扫描、多列聚合、分组聚合、大表关联、时间区间统计,判为分析型,计划改写时把扫描算子下到列存节点,利用列存只读相关列的特性砍掉大量IO。还有混合查询——比如按主键过滤出某商户的订单,再按列存聚合金额——优化器会拆成两阶段:行存先按主键筛出小结果集,再拿这批行标识去列存拉相关列做聚合,避免全列存扫或全行存聚合。
选路对应用完全透明,业务代码不需要写提示或切数据源。天翼云在SQL层与执行层之间放的智能路由模块,就是把这个决策固化成优化器规则集:统计信息新鲜、表存储属性显式、资源组水位当前可控,三者齐了选路才准。统计信息过期是选路错配的头号原因——优化器以为表很小走行存全扫,其实表已经很大该走列存。
选路错误是HTAP排障中最常见也最难排查的问题。一条本该走行存索引的点查,因为统计信息过期被优化器送去列存全扫,延迟从毫秒级变成秒级,业务方会投诉数据库变慢了。排查方法是在慢查询日志里看执行计划,确认访问路径是否与预期一致。如果发现错配,先手动收集统计信息,再检查表存储属性是否显式指定。
执行下推与MPP并行:列存侧怎么跑快
分析查询选到列存后,执行不是把列存数据全拉到SQL计算节点再算,而是尽量下推。过滤、投影、局部聚合、部分关联在列存节点本地完成,只把中间结果按MPP模式在多个列存节点间交换,再做全局聚合。向量化执行贯穿其间——按列批量取数、批量比较、批量算和,CPU缓存命中率高,指令流水不被单行解析打断。
行存节点在这一步基本旁观,除非混合计划里需要它提供主键过滤集。列存节点之间走内部高速通道,不占应用连接带宽。最终SQL计算节点拿到的是已经缩小过的结果集,序列化返给客户端。
这条执行链路的实时性体现在两点:列存数据本身是亚秒级新鲜的,执行又是并行向量化的,因此即便面对大规模明细数据,聚合查询也能压到秒级返回。对比传统抽取再建Cube的方式,链路长度从小时级管道缩成提交即同步、查询即最新。
MPP并行执行的关键在于数据分布的均匀性。如果分区键选得不好,某些列存节点上的数据量远大于其他节点,就会出现木桶效应——整个查询的完成时间由最慢的那个节点决定。调优时可以根据查询特征选择合适的分区键,或者在建表时显式指定分布策略。
向量化执行也有其适用边界。对于点查和短事务,向量化的初始化开销反而比逐行处理更大,因此优化器会自动为这类查询关闭向量化。如果在监控中发现点查走了向量化路径,说明统计信息或路由规则有问题,需要排查。
一致性快照:分析不阻塞事务的代价控制
列存数据是历史某一时刻的快照,不是行存实时指针。分析查询进来时,从授时服务取一个快照时间戳,只能读该时间戳及之前已提交的行版本。多版本并发控制在这里起作用:行存里新事务继续写新版本,不影响列存正在服务旧快照;列存学习者回放时也不会把未提交事务漏进去。
代价有两个。其一,列存新鲜度取决于学习者回放速度,写入峰值高时快照可能落后行存零点几秒到几秒,实时大屏要接受这个固有延迟。其二,长事务不提交会拖住快照水位,版本链变长,行存垃圾回收和列存回放都更累。调优时把批量写拆小、长事务拆短,对链路整体吞吐的帮助常被低估。
天翼云HTAP强调的强一致不是指分析读到和事务同一微秒,而是指分析读到的快照内部自洽、包含所有该时间戳前已提交事务、不会出现半笔订单。这是快照隔离的强一致,不是行级锁的强一致。理解这个区别很重要——如果你需要分析查询看到事务提交后下一秒的最新数据,HTAP可以做到;如果你要求看到事务提交后同一微秒的数据,那需要走行存直接查,不能走列存快照。
快照时间戳与行存最新提交时间戳之间的差距,是衡量分析新鲜度的核心指标。这个差距应该纳入监控告警体系,当差距持续扩大超过业务可接受阈值时触发告警,让运维人员及时介入排查。
链路观测:怎么证明它真的实时
排障时不能只看SQL跑完了,要拆链路各段耗时。
写入侧看行存提交延迟、学习者日志追赶延迟。行存最新条目与列存回放条目之间的差距持续扩大,说明同步线程CPU不够或列存IO跟不上。解析侧看优化器选路是否如预期,点查走没走行存索引、聚合走没走列存,错误选路会让延迟翻倍。执行侧看列存扫描行数、向量化占比、MPP各节点数据倾斜,倾斜严重说明分区键选错或统计信息歪了。一致性侧看查询快照时间戳与行存最新提交时间戳的差距,这个差就是分析新鲜度。资源侧看事务组和分析组的CPU、IO是否互踩,事务尾部延迟抬头先怀疑分析查询占满IO而非SQL本身慢。
常见三类病象。写入快但分析看到的还是几分钟前数据——学习者同步断流或回放线程死锁,检查学习者日志和回放线程状态。同一条聚合SQL有时快有时慢——列存缓存命中率随其他查询波动或统计信息过期导致重选路,检查缓存命中率和统计信息收集时间。点查偶尔慢——优化器误把点查送列存全扫,查表存储属性是否生效。
链路观测的工具链包括慢查询日志、执行计划可视化、资源组监控面板和一致性差距曲线。把这些工具整合到一个统一的观测平台上,可以大幅降低排障时的认知负荷。
结语
天翼云实时数据库行列混存的实时查询链路,是一条从行存提交、学习者异步同步、优化器智能选路、列存向量化下推、快照隔离读到结果的连续管道。它的实时不是单点魔法,而是每一段都把延迟压到极致后的叠加:事务写行存不等多副本外角色,学习者借共识日志旁路追数据,优化器把SQL送进对的存储,列存用向量化和MPP把扫描压缩成秒级,快照隔离让分析永远不锁事务。开发工程师落地时最容易把HTAP当加个列存副本来用,结果选路错、同步断、快照旧,实时性名存实亡。正确做法是按这条链路逐段对账——写入落哪、同步多快、选路对不对、执行下不下推、快照差多少、资源隔没隔离——把每条都钉在可接受阈值内,行列混存才真正变成业务侧的实时能力,而不是架构图上的标签。