Page 387 - 《软件学报》2024年第6期
P. 387
胡梓锐 等: HTAP 数据库系统数据共享模型和优化策略 2963
的所有查询后, 两者的数据版本可被清除. IDAA 在系统中实现了查询可选择从 TP 或 AP 端读取的设计方案, 支
持在未同步完全为查询的延迟带来较大优化.
BatchDB [20] 基于数据拷贝实现 HTAP 服务, 即为 TP/AP 端维护独立数据副本. 值得关注的是, 其引入了批处理
这一理念, 即 TP 请求和 AP 查询都会置于一个请求队列批量处理, 实现数据同步和 TP 写入的轻量隔离. TP 端通
过全局 TSO 获取时间戳后, 基于 MVCC 将 TP 写入组织成多个数据版本, 接着将更新置入一个更新队列中, 定期
更新 AP 端唯一的快照版本数据. 而当批量的 AP 查询到来时, 这一批 AP 查询都会访问到该时间点下唯一的快照
数据版本. 这样的批处理设计优势在于分摊了数据同步代价, 避免了遍历版本链的扫描代价, 也减小了存储和垃圾
回收的代价. 当然, 这类批查询处理很容易带来查询短板效应, 即单个慢查询会遏制整体查询的处理性能, 另外,
AP 端查询可能需要等待快照更新造成不可避免的延时.
Vegito [16] 是一款 HTAP 数据库系统原型, 其创新性地提出了一种基于 Epoch 的数据同步机制. Vegito 一方面
为了实现高可用而保持三副本的设计, 将传统三副本划分为主副本, TP 副本, AP 副本, 即本质上仍是利用多个备
份为读写场景分别服务. 另一方面, Vegito 在数据同步中引入了 Epoch 式的时间戳划分方式: TP 主副本端由全局
TSO 主动分配当前事务所处的 Epoch 号, 确定当前事务处于哪一个分段/批次. 接着系统将 TP 端事务操作写入到
本以避免相互干扰且便于优化. 同时, 顺序一致性模型中基于
日志中并行地同步数据, 接着再异步地应用到 AP 端进行数据和索引的更新, 此时 AP 端可以读取到某个 Epoch 下
已经同步完成的稳定版本. 这种将多个事务主动划分为固定分段的方式, 很大程度上缓解了单个事务到来时, 个体
申请全局时间戳竞争的代价.
ByteHTAP [47] 是一款读写分离的 HTAP 数据库系统, 与 TiDB 类似, 采用两套不同的存储引擎分别处理 TP/AP
负载, 并使用 Metadata Service 存储版本信息. 其中, TP 端数据采用行存存储, AP 端通过类似 SAP HANA 的方式,
基于行存的多版本 Delta 分块和行列混存的无版本 Base 分块存储数据版本, 并随着版本的推进定期将旧版本的数
据转化为列存, 存储在 Base 分块中, 以提高 AP 端的查询速度. 当 TP 端产生新数据版本后, 数据库会将版本对应
的 Redo Log 同步到其他存储节点上, 保证在超过多数节点已持久化对应日志的情况下提交事务, 实现高可用. 同
时, 读写节点会根据持久化顺序为每个 Redo Log 分配一个日志序列号 (LSN), 并在提交时交与数据库的 Metadata
Service 保存. 数据库周期性从 Metadata Service 获取当前已提交的最新 LSN, 并令 AP 端读取不超过该 LSN 的最
新数据版本. 当不能保证小于等于这一 LSN 的版本已被完全同步时, 数据库需要等待对应的数据版本完成同步,
因而导致一定的延迟.
MySQL Heatwave [48] 是一个具有单写节点的分布式数据库, 它通过在单机 MySQL 上增加分布式、列式存储、
可扩展的查询处理引擎 Heatwave 节点来提高 AP 端查询的效率. 每个 Heatwave 节点采用列存形式在内存中维护
一部分数据. MySQL Heatwave 数据库与 MySQL 数据库一样, 使用单机 MySQL 上的行存 innoDB 引擎负责处理
所有 TP 端请求和版本戳分发. 当发生版本更新时, 新版本首先会被存储到 innoDB 中, innoDB 实时将数据发送到
Heatwave 节点, Heatwave 节点使用数据驱动的分析策略决定数据列存合并转换的周期. 当一个查询到来时,
MySQL 的查询优化器会自动选择将这个查询本地执行还是将其下推到 Heatwave 中, 由于 Heatwave 是一个云服
务插件, 因此 AP 对 TP 干扰较小.
综上所述, 支持顺序一致性的数据库系统普遍采用分离式的架构, 从而适合为 TP/AP 引擎管理独立的数据副
Epoch 的同步设计较为灵活, 即可以根据业务的需求
均衡性能和新鲜度指标, 选取合适的 Epoch 粒度. 此外, 该类数据库具有阶段性、批量同步的特征, AP 端普遍不再
存版本链, 主流的方案会选择维护 AP 端单版本或是每个 Epoch 的快照以支持读操作. 值得关注的是, 为了提高数
据库的新鲜度, 一些数据库 (如 ByteHTAP [47] ) 也支持读取未更新到 AP 端数据上的日志.
2.3.3 支持会话一致性的数据库系统
[5]
HyPer 是基于内存的单机数据库, 在它的早期版本中, TP 和 AP 使用同一个数据副本, TP 端单线程串行执
行. 当 AP 端读请求到来时, HyPer 通过 fork 系统调用来创建新进程并将其与 TP 进程共享内存映射, 以构建满足
数据一致性的只读快照. 在创建快照时, 如果存在事务正在执行, 则需要通过 undo log 让数据库得到事务开始前的
一致性状态. 由于 TP 和 AP 使用同一个副本, 当 TP 端修改数据后, 需利用 COW 机制对修改的内存页创建旧数据