Page 388 - 《软件学报》2024年第6期
P. 388

2964                                                       软件学报  2024  年第  35  卷第  6  期


                 拷贝, 未完成的    AP  会话仍可基于旧数据进行查询, 而新的读会话会在最新                 TP  数据上创建只读快照, 实现了多个
                 会话的独立快照读取.
                    Aurora [15,49] 是一款云原生  HTAP  数据库系统, 主打日志即数据库. Aurora 采用存算分离架构, 计算节点包含一
                 个写节点和多个读节点, 所有计算节点共享同一个多版本存储引擎, 使用                      Quorum  协议  [50] 维持数据一致性. Aurora
                 基于日志号进行数据组织. 首先, 写节点根据事务操作序为其生成日志号, 然后将日志写入存储引擎并传递给读节
                 点. 当写节点产生的日志被超过半数的存储节点记录后即可返回. 之后, 存储节点将日志异步回放到自己的存储副
                 本中, 只读节点将日志异步回放给缓存中存在的数据. 读请求发起时, 只读节点根据缓存中最新的版本快照点确定
                 查询的读取快照, 如果查询的数据只在缓存中, 则直接返回, 否则从存储引擎中读取所需的版本进行补缺. 读取的
                 数据将缓存到只读节点, 并在后续的日志到达时, 由只读节点回放并推进其版本. 为了使缓存需要的版本数据始终
                 能在存储中找到, 缓存中的版本快照点应始终小于存储中已回放的版本快照点.
                    PolarDB [14,51] 也是一款采用存算分离架构的云原生       HTAP  数据库. 其提出    PolarFS [14] 来实现写节点和只读节点
                 的数据共享. PolarFS  基于  Raft 协议可以在应用层和存储块层之间构建高可用的分布式文件系统. 与                      Aurora 类似,
                 PolarDB  同样基于日志号进行数据共享, 写节点需要将日志同时传递给                   PolarFS  和只读节点, 写节点将日志写入

                 PolarFS  后即可返回. 但与  Aurora 不同的是, PolarFS  不具备日志回放能力, 需要写节点将脏数据块本地落盘以实
                 现数据共享, 因此存储中的数据为单版本. 所以, 只读节点无法依据缓存中的版本快照点从存储中获取相同版本快
                 照点的数据. 为了保证缓存与存储的版本一致性, 写节点会对                  PolarFS  中的数据版本标记“日志检查点”, 只读节点
                 从存储中获取数据后, 只需要从该检查点回放日志到缓存中的版本快照点即可对齐版本. 需要注意“日志检查点”
                 不能超过任何只读节点的版本快照点, 否则只读节点有可能查询到未来版本的数据, 使版本无法保证顺序推进. 此
                 外, 当出现写密集负载时, 热点数据块标识号激增, 远超只读节点的版本, 导致该数据块无法落盘. 这种情况下, 当
                 写节点推进“日志检查点”时, 由于存储引擎中缺失该热点数据块的历史版本, 无法形成完整的全局数据快照完成
                 推进检查点. 这样的话, 只读节点需要回放的日志序列越来越长, 降低了查询性能. 为此, PolarDB                       提出了将热点块
                 的历史版本周期性分离为         Shadow Page, 从而可以将其落盘以推进“日志检查点”.
                    综上, 支持会话一致性的        HTAP  数据库系统基本都是采用基于缓存一致性原则进行数据的读取, 所以重点在
                 于如何同步缓存中的数据以达成一致的版本快照. 作为单机数据库系统, 旧版本                         HyPer 通过  COW  机制从内存中
                 创建快照以供缓存使用, 并通过读取当前会话缓存追踪数据版本, 以较小的同步代价发挥了内存型数据库系统的
                 优势. 而对于分布式数据库系统而言, 存储引擎是否支持版本追踪, 对于此类                      HTAP  数据库系统性能和新鲜度的影
                 响较大. 如果缓存不命中的话, Aurora 和       PolarDB  都需要从存储中进行数据读取. 但由于           Aurora 底层存储是有版
                 本的且存储的版本相较于缓存更新, 所以为了不影响读取的延迟, Aurora 会读取与缓存中一致的较旧的版本, 降低
                 了读取的数据新鲜度; 而       PolarDB  因其存储的数据无版本且滞后于缓存版本, 所以往往需要将存储中拉上来的数
                 据回放到与缓存一致的版本快照点, 存在一定的延迟, 但也带来新鲜度上的提升. 值得关注的是, 缓存一致性的数
                 据库对于热点读比较友好, 当有         AP  查询到来时 Aurora 和  PolarDB  都会从缓存中直接读取所需数据.

                  3   HTAP  数据库系统数据共享优化

                    基于对以上各类      HTAP  数据库系统的技术总结, 本节重点阐述目前学术界针对现有的数据共享模型提出的可
                 行的优化方向, 涉及版本同步、追踪、回收的各个阶段, 并归纳总结至表                      3.

                  3.1   版本同步优化
                    对于  HTAP  数据库系统来说, TP     和  AP  端的强隔离可以实现性能的最大化, 但对操作版本的一致性要求会阻
                 碍这一目标的实现, 故而       AP  与  TP  的版本同步的高效实现是核心技术点. HTAP          数据库系统中的版本同步相当于
                 在  AP  端按可串行序进行一次对       TP  事务的回放, 从而保证同一时间点上数据的一致性. 最理想情况下, TP                  对数据
                 的修改实时为     AP  所见, 即版本同步时间为零. 然而, 实际情况下, 由于存储架构的差异, 不同同步方式对性能有着
                 不同的影响.
                    在  3  种一致性模型下, 同步主要有两种形式, 基于日志回放的同步和基于数据拷贝的同步. 但值得注意的是,
   383   384   385   386   387   388   389   390   391   392   393