首页 > 其他分享 >YashanDB混合存储大揭秘:行式存储设计如何为高效TP业务保驾护航(上)

YashanDB混合存储大揭秘:行式存储设计如何为高效TP业务保驾护航(上)

时间:2023-09-14 17:05:55浏览次数:50  
标签:存储 YashanDB 行式 查询 并发 MVCC 数据

上一篇文章《揭秘YashanDB融合存储引擎》https://mp.weixin.qq.com/s/yipJcEAH3fVA-_hnUvOiKA从存储结构、事务引擎、高可用等方面介绍了YashanDB存储引擎的整体架构。本篇为大家详细解读YashanDB行式存储技术。


背景


数据库底层组织数据的方式主要分为行式存储和列式存储两大类。YashanDB在存储引擎设计上采用融合架构,基于统一存储底座构建了不同的存储结构,支持In-place Update行式存储,适应在线事务处理场景(OLTP);支持原位更新(In-place Update)和追加式(Append-only)两种列式存储,具备原生混合负载处理能力(HTAP)和海量数据分析能力(OLAP)。

YashanDB的堆表(Heap Table)在结构上采用的是行式存储,以行为粒度将数据随机存储在最小存储单元数据块上。行式存储的优势是数据以行汇聚,随机增删改查操作效率高,通常配合Btree等类型索引使用,提供高效的事务处理能力。缺点是查询时需要整行读出,如果只需要部分列的数据,就会扫描不必要的数据,同时很难利用向量化计算来进行加速,压缩率也没有列式存储高。


行式存储关键技术


在线事务处理(OLTP)是最常见的业务模型之一,通常具有以下特点:

  • 要保证实时性,对数据库的响应时延要求很高;
  • 要保证数据一致性,要求数据库提供强一致事务保证;
  • 并发量高,要求数据库并发能力强。

YashanDB行式存储主要用于在线事务处理场景,在设计上根据其场景特点进行了针对性优化,本文将重点介绍其中的几个关键技术实践:

  • 事务并发控制:优化传统MVCC机制,采用In-place Update的块级MVCC,提供事务高并发处理能力;
  • 插入性能优化:通过提升并发性、批量化处理、减少日志产生等优化,降低事务处理过程中插入响应时延;
  • 行存储结构:尽管In-place Update原位更新带来了性能的显著提升,但是宽行的存储设计成为了面临的关键挑战之一。因此,我们针对宽行设计行链接和行迁移机制,以确保对宽行的处理性能不受影响。


事务并发控制


YashanDB使用业内主流的MVCC机制(Multi-version Concurrency Control,多版本并发控制)实现事务并发控制,但MVCC的实现在不同的数据库差异较大,主要包含以下两种:

Append-only行级MVCC:更新数据时新增一条数据。这种方式的缺点是,历史版本数据与最新版本存储在一个空间,导致空间膨胀,最新版本的查询代价高,历史版本垃圾回收开销大,修改时需要拷贝整行。

YashanDB混合存储大揭秘:行式存储设计如何为高效TP业务保驾护航(上)_并发控制


图1 Append Only的行级MVCC

In-place Update 行级MVCC:更新记录时对原始数据进行覆盖。这种有独立的Undo空间存储历史数据,最新数据的更新是In-Place Update(原位更新),但由于每一行都要关联对应的历史版本记录,存储开销大。

YashanDB混合存储大揭秘:行式存储设计如何为高效TP业务保驾护航(上)_数据块_02


图2 In-place Update的行级MVCC

YashanDB针对主流MVCC机制存在的问题,在设计上采用了In-place Update的块级MVCC。块级MVCC与行级MVCC最大的差别是,与历史版本(undo数据)关联的是事务而不是行,当需要查询行的历史版本(一致性版本)时,不再按行构建,而是通过数据块上的事务信息,构建整个数据块级别的历史版本,通常称之为一致性数据块(Consistent Read Block)。

块级MVCC优化了数据块内行的Undo空间开销,同一事物在同一数据块中修改不同行时产生的Undo可以进行合并,有效节省了存储空间开销。按块构建一致性版本提升了历史数据访问效率,同时在全局对一致性数据块进行缓存之后,可以跨会话共享,避免不同会话之间重复构建。

YashanDB混合存储大揭秘:行式存储设计如何为高效TP业务保驾护航(上)_并发控制_03


图3 In Place update的块级MVCC

基于MVCC机制,我们实现了行式存储的行级事务并发控制,主要分为三种场景:

  1. 写写并发:写操作之间不会产生冲突,可以并发执行;
  2. 读写并发:读操作不会被写操作所阻塞,读操作可以读取到之前的数据版本,保证了读的一致性;
  3. DDL和查询并发:多个读操作或者DDL操作之间不会产生冲突,可以并发执行。

1、写写并发


行存的并发控制单元就在行上,通过行与事务绑定,实现行数据的写写并发控制。行数据被事务修改,事务提交之前,其他事务不能修改该行。


2、读写并发


事务修改了一行数据,未提交之前,其他会话都不能修改这行数据,但是可以查询这行数据,查询的版本是本次查询时间对应的数据快照。查询通过最新数据块以及关联的历史版本(Undo),构建一致性数据块,作为本次查询可见的历史版本快照。

对于索引过滤之后再回表查询的场景,如果每行数据都构建一致性数据块,代价比价大。因此我们通过引入行级可见性判断对这个场景进行了优化,使得大多数索引回表的查询都不需要构建一致性数据块。

针对Nest Loop Join这种外表驱动内表,对内表进行多次查询的场景,我们将内表构建的一致性数据块缓存在全局数据缓存中,以供下一轮内表查询的时候直接使用,这种方式在数据量较大时可以大大减少查询时间。


3、DDL和查询并发


YashanDB实现的是无锁查询,即查询表数据时不加表锁,可以在查询期间并发地对表做Drop/Truncate/Shrink等DDL操作。查询需要保证:要么查到的是一致的数据集,要么在查询过程中检测到对象的数据块被复用而报错。

YashanDB能精准识别数据块是否已经被复用,全方位保证了单个表查询的一致性,以及分区表各个分区之间的一致性。


因文章篇幅过长,本文内容在下篇文章继续解读。

标签:存储,YashanDB,行式,查询,并发,MVCC,数据
From: https://blog.51cto.com/u_16065869/7471532

相关文章

  • YashanDB混合存储大揭秘:行式存储设计如何为高效TP业务保驾护航
    接上篇内容插入性能优化YashanDB行式存储主要从提供并发度、批量化处理以及减少日志产生三方面对事务处理过程中的插入性能进行了优化:1提高并发度单线程插入的速度是有限的,在资源充足的场景下,我们希望通过增加线程来提高导入数据的速度。由于数据块不能同时写入,如果两个线程要在同......
  • nacos服务多级存储模型
       ......
  • 7、数据库在磁盘上的存储
    数据库在磁盘上的存储首先弄清楚磁盘的几个概念磁盘面:磁盘一般会由多个磁盘片组成,一般都控制在5片以内,每个磁盘片包含两个面。磁盘片从下向上从0开始,比如最下边的磁盘块是0面和1面,依次往上走。磁头:通过磁性原理读取磁盘数据的部件,每个磁盘面都对应有个读/写磁头。3.内存......
  • 修改了虚拟机名称后,数据存储上的文件名称如何同步修改
    更改虚拟机名称虚拟机的名称在虚拟机所在的文件夹中必须是唯一的。如果将某虚拟机移至其他数据存储文件夹或移至具有相同名称的现有虚拟机的主机,则可以更改该虚拟机的名称以使其保持唯一。 更改某虚拟机的名称时,应更改 vCenterServer 清单中用于标识该虚拟机的名称。该操作......
  • 七牛云存储____qshell的使用
    //新建一个qshell.conf文件内容编译下//qshell执行account命令加上aksk命令如下//qshell执行该命令//qdownload命令如下qshellqdownload命令线程10配置文件qshell.conf//运行结果//工具项目和代码下载七牛云存储资源http://pan.baidu.com/s/1bJok2M......
  • 七牛云存储____qshell简介
    ......
  • 七牛云存储____容灾备份策略
    ......
  • 七牛云存储____官方js上传(基于pupload插件)
    <%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><%Stringpath=request.getContextPath();StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getS......
  • 七牛云存储____js打水印加上传图片
    <%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><% Stringpath=request.getContextPath(); StringbasePath=request.getScheme()+"://" +request.getServerName()+":"+......
  • 七牛云存储____生成永久性token
    //MyHtml.html<!DOCTYPEhtml><html><head><title>MyHtml.html</title><metaname="keywords"content="keyword1,keyword2,keyword3"><metaname="description"content="thi......