写点什么

打造次世代分析型数据库(二):这,不只是列存表

  • 2023-09-08
    广东
  • 本文字数:2357 字

    阅读完需:约 8 分钟

打造次世代分析型数据库(二):这,不只是列存表


作者介绍

作者介绍:marklv(吕夫洋),腾讯云数据库高级工程师,专注于数据库存储、事务、高可用方向,具有多年的数据库内核研发经验。曾供职于华为 2012 高斯实验室;加入腾讯后负责 CDW PG 数据库全新存储引擎的设计和研发工作。


Effective Storage Engine 设计背景



传统数据库按行进行表的存储和访问。由于表中每行的数据连续地存储在一起,对于交易性业务(OLTP)这样频繁以行作为单位存储表中数据的负载,行存储性能较好。

但是对于分析性业务(OLAP)这种经常对表中某些列进行查询计算的负载,行存储会将不相关的列数据读入内存中,导致性能欠佳。列存储模型通过将表中的列连续地存储在一起,能够很好地解决这个问题,减少不必要数据的读取与解析带来的磁盘 I/O 代价、数据压缩解压代价以及 CPU 执行代价,提高磁盘存储和使用效率,从而提升查询性能。

在混合的业务负载(Hybrid transaction/analytical processing,HTAP)场景下,针对 OLTP 优势的行存与针对 OLAP 优势的列存都无法很好地同时应对两种类型的业务,大多需要牺牲其中一种场景下的表现,或是最终造成两种场景下的能力都无法达到业务的预期。

应对两种完全不同的业务负载的实现往往无法避免以下问题:

  • 需要额外的系统资源(存储资源、计算资源);

  • 难以兼顾数据的实时性和强一致性;

  • 需要业务/应用层面针对特殊配置进行识别和适配。

为了满足 CDW PG 在 OLAP 传统数仓场景超大集群下的目标业务负载,并且具备能够良好处理数据混合负载的能力,Effective Storage Engine(下文简称“Estore”存储引擎)应运而生。


Effective Storage Engine 基础架构设计

Estore 的基础“三角形”组



Estore 表基础架构由元信息表(“registry”表)、列文件(”silo”组成的文件)以及临时区表(”stash”表)组成。

在创建表 create table 时于 reloptions “orientation”处填写”column”即可创建,创建后以上基础组成部分会自动创建。


  1. Silo 是 Estore 表中基本的数据存储单元,承载存储数据的基本职责。

    每个 Silo 包含一组数据中其中一列的数据,方便系统对其进行批量操作、压缩、存储。Silo 自身存储与行存储的数据页面不同,不是固定的存储空间,而是存储固定的行数,实际存储空间大小可变。

    Silo 存储的是一组数据中的一列内容,同列数据能够提供更接近的数据特征以及更好的数据筛选,进而提供更好的压缩率。同时由于 Silo 的概念是固定行数而不是固定空间的概念,因此在尽量满足 Silo 填充至上限的情况下,Silo 可以为压缩提供更大的上下文空间,以便提高数据的压缩率。

    同时,Silo 可以根据自身的数据类型、数据特征以及表级别/列级别,指定使用最合适的压缩算法或压缩算法的组合。


  2. registry 表实际上是一张行存表,承担一张 Estore 表的存储引擎的主体组织结构与核心角色,存储了一张表中承载数据的各个 Silo 的相关信息。


  3. stash 则是为了应对碎片数据、流数据以及混合负载下 OLTP 负载而准备的一张行存表,也可以认为是一个使用行存储承载数据的临时区域。


Effective Storage Engine 混合负载

混合负载设计背景

在分析性数据库的使用场景中,除去分析型业务常见的大数据量批量导入操作(bulkload)之外,数据库也常常会承接来自用户应用逻辑、数据管道或者 ETL 工具端的碎片化增量数据,亦或是流数据的持续输入。不同于批量数据操作中单个事务内 GB-TB 数量级的数据规模,碎片化的增量数据往往由多个小事务组成,每个事务中仅含有 KB 以下的数据量。

同时,在部分客户的应用场景中,用户逻辑会针对特定数据/近期数据/部分热数据进行类交易型的调用与处理,包括频繁的增删改;在完成相关业务后,又希望针对这部分数据或针对全部历史数据进行进一步的 BI 分析。

业界常见的支持混合负载的数据库,大部分都是采用两套或更多套存储引擎或组件来实现,中间通过 COW 或 Raft 协议副本的方式来进行数据的同步。有没有办法可以用一份数据搞定两种业务呢?

以 Stash 表为核心的混合负载基础理念

Stash 表的设计初衷即是应对以上场景。Stash 表是 Estore 表创建后同步创建的一张行存表,与原表有着相同的表定义,但使用行存表作为存储。Stash 表的作用是充当 Estore 表的“临时区“角色,针对单次行数在一定阈值下的操作,其相关数据会先被放入 Stash 表中,以行存储的形式存储起来,避免碎片化数据对 Estore 表的 registry/silo 存储模式的直接冲击。

同时,由于放在 Stash 表中的都是近期单条/小批量插入或更新的数据,Stash 表也就在实际上起到了 Estore 表类似“热数据分片”的概念。通过 Stash 表作为行存储的机制支持,Estore 存储引擎自身就可以为混合负载中的 OLTP 部分提供良好的支持,而不需要额外在其他存储方式上创建副本。后续按照用户配置或通过用户主动执行,用户可以按照自己的应用逻辑将 Stash 表数据合并入 registry/silo 的存储模式中,获得更好的分析性业务负载性能。

用户操作中对数据的归属性质不进行感知,即发起 query 或 DML 时无需对 stash 进行特殊处理,底层逻辑会自动扫描 registry/silo 以及 stash 中的数据。

Stash 表的“自动沉降“ —— Auto Stashmerge



为了保证表中数据能够借助高效存储组织结构以及各类优化对应用提供优秀的分析性业务负载性能,Estore 存储引擎在数据库实例中实现并封装了 Estore 表的自动合并机制,定期合并 stash 数据至 silo 中。用户可以根据不同应用场景对“沉降”进行配置,业务无需感知, 后台进程的动作也不会影响用户对表正常的增删改查。

Stash 表的“手动沉降” —— Vacuum Stashmerge

适用于部分用户或业务在交易性与分析性间存在较为明确的分水岭的场景,执行时会将指定表或库中所有 Estore 表的 Stash 全量数据合并至其对应的 registry/silo 存储结构中,可以近似地理解为系统中“flush buffer”一样的操作。


总结

综上,为大家介绍了 CDW PG 的新型列存储引擎 Effective Storage Engine 的整体设计,以及 Estore 引擎如何同时为传统的 OLAP 数仓场景以及 HTAP 混合负载的业务提供稳定且优质的存储支持与保障。

用户头像

还未添加个人签名 2020-06-19 加入

欢迎关注,邀您一起探索数据的无限潜能!

评论

发布
暂无评论
打造次世代分析型数据库(二):这,不只是列存表_数据库_腾讯云大数据_InfoQ写作社区