Page 385 - 《软件学报》2024年第6期
P. 385
胡梓锐 等: HTAP 数据库系统数据共享模型和优化策略 2961
的当前本地事务号与分布式事务号进行映射, 以获取全局快照点. 映射时主节点需要与所有节点进行通信, 开销较
大. Greenplum 架构中使用同一个副本来同时处理 TP 和 AP 任务, 并采取行列混存的模式以保证读写性能, 因此
当 TP 负载对数据版本进行修改后, AP 端的查询可以直接读取对应的数据, 不需要进行多副本之间的同步. 另外,
Greenplum 使用了基于虚拟化技术的单节点资源隔离以保证性能, 但是其不需要等待网络同步, 不存在等待导致
的额外延迟.
[4]
SAP HANA 是基于行列混合存储的单机内存数据库. 在 SAP HANA 中数据存放分为两个部分: 主库 (main
store) 和增量库 (delta store). 其中增量库采用 MVCC 机制对写操作进行了优化, TP 和 AP 请求都是从单机直接获
取时间戳, TP 进行数据更新时只会对增量库进行更新, 增量数据会定期合并到主库中, 而主库中的数据有很高的
压缩比率并对读操作进行了优化. 当 AP 进行读时, 需要同时读取主库和增量库中的数据并进行合并. 因此在数据
版本方面, 主库维护一个只读副本, 增量库基于 MVCC 版本链维护一个读写副本. 由于 AP 端支持直接从增量分
块读取数据, 因此 SAP HANA 无需等待副本同步, 避免了多副本同步的开销和同步延迟.
Hyrise 是单机的内存数据库, 它的存储结构采用行列混存分区. 各分区间的数据互不重合, 且每个分区内划
[3]
分为主库和增量库以存储数据, 不需要进行分区间的数据同步. Hyrise 处理查询与上述两种数据库类似, 基于其单
遇到某一部分单机数据的热点写入, 整个集群的日志写入都将被拖慢. 由于
机特性可以简单地分配事务号, 不需要网络请求. Hyrise 的写入采用类似 SAP HANA 的机制, 在 TP 端进行版本更
新时, 先对增量库通过追加版本实现更新、修改和删除, 再定期将增量库中的内容进行压缩编码并合并到以列存
形式存储的主库中, 从而实现不同副本之间的同步. 在进行 AP 查询时先根据索引定位需要查询的分区, 再基于分
区的存储形式从中提取数据. Hyrise 与 SAP HANA 采用了类似读取机制, 不需要等待完成多副本同步便可以读取
新版本的数据, 因而不存在同步导致的延迟.
[8]
SQL Server 是基于行列混存的单机数据库, 它采用基于内存的行存引擎 Hekaton 和基于磁盘的传统 SQL 引
擎来支持行存, 采用增量库 (tail index) 和主库 (CSI) 的组合来实现列存索引以加速 AP 查询. SQL Server 采用
MVCC 机制进行版本的管理, TP 端和 AP 端都可以直接从单机上获取时间戳. 当发生版本更新时, 数据库同时更
新 Hekaton 和增量库中的数据, 并将主库中的对应数据标记为删除. 随后, 数据库通过后台进程异步地将增量库中
的数据压缩合并到主库中, 从而实现版本同步, 此时数据库会更新 Hekaton 中的相关记录, 使 AP 端查询可以直接
访问更新后的主库, 这一更新过程会影响 TP 负载的执行. 与 SAP HANA 类似, SQL Server 的 AP 读取请求会同时
从增量库和主库中读取数据, 因此不存在等待同步的开销. 为了减少频繁同步带来的资源开销, SQL Server 只同步
冷数据, 将频繁修改的热数据保留在增量库中.
[6]
Oracle 也通过结合内存型列存 (in-memory compression units, IMCU) 和行存缓存 (row-based buffer cache), 扩
展了原有 OLTP 业务以实现对混合负载的支持. 在 TP 负载进行写入时, 缓存通过维护数据多版本, 基于单调递增
的时间戳 (system change number, SCN) 标识事务. 同时会在列存创建一份一致快照下的数据, 并通过 SCN 进行创
建时刻的标识. 当新的 AP 查询到来时, 会通过一个元数据管理模块 (snapshot metadata unit, SMU) 检测列存数据
的有效性, 如有早于当前 AP 查询 SCN 号的更新, 则通过扫描增量的事务日志以保证读取最新数据.
FoundationDB [11] 是单版本的分布式数据库, 采用单机节点集中授时, 它对 HTAP 负载的支持与之前系统不同,
不区分 TP 端和 AP 端, 通过把系统的事务管理和存储解耦, 使读写操作访问不同的路径实现隔离. 对于 TP 负载的
写操作, 提交前会申请 TSO 以确定事务号, 但仅会进行日志预写, 还需要后续存储异步拉取并回放日志, 对应的版
本才对读操作可见. 每次写操作需要等待所有分片所在的日志服务器都收到最新版本写入通知才算提交完成, 若
FoundationDB 采用异步的方式进行同
步, 在 TP 负载的写入提交后对应的版本可能还未完全同步到所有分片的存储中, 因此, 每次执行 AP 读请求时需
要申请 TSO 并判断该 TSO 对应的最新已提交版本是否完成同步, 若未同步完则选择等待或者从已经同步完的副
本上发起二次读, 以保证读版本正确性, 这也会增加读延迟.
MemSQL (于 2020 年 10 月更名为 SingleStoreDB) [10,40,41] 作为分布式数据库, 拥有中心化的主节点用于接收查
询请求, 并对事务进行管理. 其他节点存储不相交的数据并执行主节点所转发的请求. MemSQL 采用较为复杂的
数据存储格式, 具有三副本, 使用行存的二级索引和临时内存块优化 TP 负载性能, 并使用列存形式的 LSM-Tree