概述

本文为 HTAP 架构设计提供参考依据,本次调研选取 PolarDB、PolarDB-X、GoldenDB 三款主流产品,从技术架构、核心实现逻辑、实际使用方式等维度展开深度分析。三款产品均以列存索引为核心实现分析型处理(AP)能力,结合行存满足在线事务处理(TP)需求,支持查询的自动路由与手动指定,数据同步均依托日志复制机制实现。其中,PolarDB 采用主从集群架构,通过 IMCI 列存索引、代价估算机制选择执行引擎,列存索引部署于只读节点并基于 Redo 日志异步同步;PolarDB-X 为分布式云原生架构,增设多类功能节点支持 MPP 并行计算,通过独立只读集群实现 TP/AP 负载隔离,列存基于类 LSM 树的 Delta Main 模型存储,依托 Binlog 同步并支持全量 + 增量数据合并;GoldenDB 支持行存、列存及行列混合表三种类型,由 CN 节点统一接入请求并根据表存储类型自动路由,列存数据基于 Binlog 日志复制转换,但其 HTAP 相关技术资料尚不完善。

友商方案

PolarDB

概述

PolarDB 采用分布式集群架构,这里的分布式集群是指主从架构,一个集群版集群包含一个主节点和最多15个只读节点(至少一个,用于保障高可用)。主节点处理读写请求,只读节点仅处理读请求。主节点和只读节点之间采用Active-Active的Failover方式,提供数据库的高可用服务。简单来说 PolarDB=一个单机磁盘超大的 MySQL 。

该产品通过列存索引实现 AP 能力,列存索引对用户可见,支持手动添加与修改,本质是将指定列数据转换为列存压缩存储形式。查询时,系统会通过代价估算机制判定采用 TP 执行引擎还是 AP 执行引擎,也支持用户强制指定 AP 查询。

注意:仅当查询 SQL 语句涉及的所有列均被列存索引完全覆盖时,才能通过列存索引实现查询加速。

架构

PolarDB 整体架构按功能划分为读写节点、TP 读节点与 AP 读节点,其 SQL 执行架构核心为代价估算驱动的执行引擎选择,流程为:SQL 解析→代价评估→生成逻辑执行计划→转换为物理执行计划,最终根据代价结果选择行存执行计划或列存执行计划,分别对应行存执行引擎、列存向量执行引擎,两套引擎搭配不同的算子、调度器与存储访问接口,实现行列混合执行。

总体架构

_scroll_external/attachments/polardb1-f134892da060814b4792024a370c5efdb7eaa14a70a6248251c1ce875c1d5c78.png

sql 执行架构

_scroll_external/attachments/polardb2-62a7778acc6ea19508b08efdd8c20c4eb5ad487ba997f95356610a17d1b76132.png

使用

列存索引支持建表时指定,也可在后续业务中动态修改,同时支持库表级批量配置,具体语法如下:

-- 建表时

-- 为某一列添加列存索引

CREATE TABLE <table_name>(

<column_name_1> INT COMMENT 'COLUMNAR=1',

<column_name_2> VARCHAR(100)

) ENGINE InnoDB;

 

-- 为全表添加列存索引

CREATE TABLE <table_name>(

<column_name_1> INT,

<column_name_2> VARCHAR(100)

) ENGINE InnoDB COMMENT 'COLUMNAR=1';

 

 

-- 动态修改

-- 为指定列添加列存索引

ALTER TABLE <table_name> MODIFY COLUMN <column_name_1> INT COMMENT 'COLUMNAR=1';

 

-- 为整个表添加列存索引

ALTER TABLE <table_name> COMMENT 'COLUMNAR=1';

 

 

-- 库表级批量修改

-- 为整个表添加列存索引

CREATE COLUMNAR INDEX ON <db_name>.<table_name>;

 

-- 为整个库添加列存索引

CREATE COLUMNAR INDEX FOR TABLES IN <db_name>;

ap 查询使用方法

自动选择

新增列存索引只读节点后,需要为SQL语句中所查询的表都增加列存索引,且SQL语句的预估执行代价超过一定阈值,该SQL语句才会使用列索引进行查询。另外,SQL语句需要被转发到列存索引只读节点,才可以使用列存索引进行查询加速。

具体规则:使用集群地址并开启行存 / 列存自动引流后,若 SQL 预估执行代价高于阈值loose_imci_ap_threshold或loose_cost_threshold_for_imci,数据库代理会自动将 SQL 转发至列存索引只读节点,且阈值支持自定义修改。

手动分流

按应用类型做负载隔离,将 OLTP 类应用与不含只读列存节点的集群地址关联,其读请求由主节点或只读行存节点处理;将 OLAP 类应用与仅包含只读列存节点的集群地址关联,其读请求由只读列存节点专属处理。

强制指定

强制指定将SQL转发到列存索引只读节点,例如:

/FORCE_IMCI_NODES/EXPLAIN SELECT COUNT(*) FROM t1 WHERE t1.a > 1;

参考 https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/instructions-for-using-column-index?spm=a2c4g.11186623.help-menu-2249963.d_5_24_1.65ed4e03IHIfQs#9eee4bf184bpp

数据同步

PolarDB 使用读写分离的部署架构,RW 节点(写节点)承担写流量,RO 节点(只读节点)承担读流量。RO 节点通过异步复制的方式回放 RW 节点发送的日志以保持数据实时更新。

为了实现资源隔离,PolarDB 列存索引被部署在 RO 节点上,对列索引的更新是通过 Redo 日志异步物理复制的方式来实现的。

参考 https://help.aliyun.com/zh/polardb/polardb-for-mysql/innodb-physiological-logging?scm=20140722.S_help%40%40%E6%96%87%E6%A1%A3%40%40443298.S_BB2%40bl%2BRQW%40ag0%2BBB1%40ag0%2Bos0.ID_443298-RL_redo-LOC_doc%7EUND%7Eab-OR_ser-PAR1_2102029b17473787063054023dbcae-V_4-P0_0-P1_0&spm=a2c4g.11186623.help-search.i29

存储

采用列压缩存储,选择列式Heap Table作为底层主要存储架构来支持实时更新,SQL Server以及Oracle的Column Index也采用了相同的存储架构。

数据按RowGroup组织,每个RowGroup包含64K行。对于每一列的列索引,其存储都采用的是无序且追加写的格式。因此,IMCI无法像InnoDB的普通有序索引那样,可以精确地过滤掉不符合要求的数据。在读取DataPack时,需要从磁盘中加载进内存并解压缩,然后遍历DataPack中的所有记录,利用过滤条件筛选出符合条件的记录。

针对上述存储特性,PolarDB 引入查询剪枝技术:通过访问分区信息与统计信息,结合查询过滤条件,在查询执行前提前过滤无需访问的 DataPack,减少数据访问量、存储扫描次数,从而降低数据传输与计算消耗,提升查询效率。数据删除采用标记删除方式实现。

关于 ddl

目前未查询到 PolarDB 列存索引相关的 DDL 专属资料,结合产品常见问题整理核心要点:执行加减列等表结构变更操作时,会触发表数据重建;若原表已配置列存索引,数据重建的同时会同步重建列存索引数据,且列存索引重建过程需写入 Redo 日志。由于列存索引通常覆盖多列,重建产生的 Redo 日志量与原表数据量成正比,相较于无列存索引的表,会增加 IO 数据量,导致 DDL 执行时间变长。

PolarDB 的 DDL 同步依托 MySQL 的 binlog 或 Redo 日志实现主从同步。

部分原理

PolarDB 的核心优势为兼顾行列混合执行的优化器,因同时存在行存和列存两套执行引擎,优化器可对比两套引擎的执行代价,选择代价最低的执行计划。

在PolarDB中,除原生MySQL的行存串行执行外,还有能够发挥多核计算能力的基于行存的Parallel Query功能。因此,实际优化器会在行存串行执行、行存Parallel Query、以及IMCI三个之中选择其一。在目前的迭代阶段,优化器按如下的流程执行:

执行SQL的Parse过程并生成LogicalPlan,然后调用MySQL原生优化器,并执行优化操作(join order等)。同时该阶段获得的逻辑执行计划会转给IMCI的执行计划编译模块,并尝试生成一个列存的执行计划(此处可能会被白名单拦截并回滚回行存)。

PolarDB的Optimizer会根据行存计划,计算得出一个面向行存的执行Cost。如果此Cost超过一定阈值,则会尝试下推到IMCI执行器使用IMCI_Plan执行。

如果IMCI无法执行此SQL,则PolarDB会尝试编译出一个Parallel Query的执行计划并执行。如果无法生成PQ的执行计划,则说明IMCI和PQ均无法执行此SQL,则回滚回行存执行。

上述策略是基于这样一个判断,从执行性能上进行对比:行存串行执行 < 行存并行执行 < IMCI。 对比SQL兼容性,IMCI < 行存并行执行 < 行存串行执行。但是实际情况会更加复杂,例如:某些情况下,基于行存有序索引覆盖的并行Index Join会比基于列存的Sort Merge join有更低的Cost。按照当前策略,则会选择IMCI列存执行。

配置参数

https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/column-store-index-parameter-description?spm=a2c4g.11186623.help-menu-2249963.d_5_24_7.5f176cb9aq2VlY

同类产品技术参考

Oracle公司在2013年发表的Oracle 12C上,发布了Database In-Memory套件,其最核心的功能为In-Memory Column Store,即通过行列混合存储/高级查询优化(物化表达式,JoinGroup)等技术来提升OLAP性能。

微软在SQL Server 2016 SP1上,开始提供Column Store Indexs功能,用户可以根据负载特征,灵活的使用纯行存表、纯列存表、行列混合表以及列存表+行存索引等多种模式。

IBM在2013年发布的10.5版本(Kepler)中,增加了DB2 BLU Acceleration组件,通过列式数据存储配合内存计算以及DataSkipping技术,大幅提升分析场景的性能。

相关概念

涉及的mysql 概念:

binlog:逻辑日志,记录所有 SQL 操作(包含 DML、DDL),主要用于主从同步;

redo log:物理日志,记录数据库物理页的修改(包含 DML、涉及页修改的部分 DDL),主要用于数据恢复;

undo log:记录事务修改前的数据快照,主要用于事务回滚与多版本并发控制(MVCC)。

参考资料

https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/imcis/?spm=a2c4g.11186623.help-menu-2249963.d_5_24.4ff26de8nMjnqz

IMCI(In-Memory-Column-Index)HTAP解决方案-蔡畅-阿里.pdf

PolarDB-HTAP.pdf

PolarDB-X

概述

相较于 polardb , polardb-x 在主从基础上,加入分布式,是一个分布式版云原生数据库,同样通过列存索引实现 AP 能力,支持基于代价估算的查询自动路由,也支持用户强制指定 AP 查询。

基于分布式架构特性,PolarDB-X 建表时需指定分区规则,创建列存索引时需与表分区保持一致,查询时通过分布式执行提升效率。

架构

_scroll_external/attachments/polardbx1-75951dac23b136a321af01ec220ec14e7c9f4261642122f422d2631c61af15e2.png

  • 计算节点(Compute Node,CN)是系统的入口,采用无状态设计,包括SQL解析器、优化器、执行器等模块。负责数据分布式路由、计算及动态调度,负责分布式事务2PC协调、全局二级索引维护等,同时提供SQL限流、三权分立等企业级特性。
  • 存储节点 (Data Node,DN)负责数据的持久化(面向行存数据),基于多数派Paxos协议提供数据高可靠、强一致保障,同时通过MVCC维护分布式事务的可见性,另外提供计算下推能力,以满足分布式的计算下推要求(例如Project/Filter/Join/Agg等下推计算)。
  • 元数据服务(Global Meta Service,GMS)负责维护全局强一致的Table/Schema、Statistics等系统Meta信息,维护账号、权限等安全信息,同时提供全局授时服务(TSO)。
  • 日志节点(Change Data Capture,CDC)提供完全兼容MySQL Binlog格式和协议的增量订阅能力,提供兼容MySQL Replication协议的主从复制能力。
  • 列存引擎(Columnar)提供持久化列存索引,实时消费分布式事务的Binlog日志,基于对象存储介质构建列存索引,能满足实时更新的需求,结合计算节点可提供列存的快照一致性查询能力。

为了加速复杂分析型查询,PolarDB-X将计算任务切分并调度到多个计算节点上,从而利用多个节点的计算能力,加速查询的执行。这种方式也称为MPP并行计算。

阻碍HTAP数据库实际应用的一大障碍是分析型查询(AP)对在线业务流量(TP)的影响。为了解决这一问题,PolarDB-X支持部署独立的只读集群,只读集群与原集群在硬件资源上完全分离,从而将AP查询对TP流量的影响降到最低。

PolarDB-X优化器会基于代价估计将请求区分为TP与AP负载,其中AP查询会被进一步改写为分布式执行计划,发往只读集群进行计算,避免它对主实例的TP查询造成影响。

_scroll_external/attachments/polardbx2-7bee7ceb7f5a11573646d7fa4cfb3a25891207cb94979ed841548cca3c566e20.png

使用

示例

创建表,分区:

CREATE TABLE t_order (

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`order_id` varchar(20) DEFAULT NULL,

`buyer_id` varchar(20) DEFAULT NULL,

`seller_id` varchar(20) DEFAULT NULL,

`order_snapshot` longtext DEFAULT NULL,

`order_detail` longtext DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `l_i_order` (`order_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 partition by hash(`order_id`) partitions 16;

 

创建列存索引,分区一致:

CREATE CLUSTERED COLUMNAR INDEX `cc_i_seller` ON t_order (`seller_id`) partition by hash(`order_id`) partitions 16;

使用 ap 查询的方法

根据代价估算自动路由。

利用 FORCE INDEX({index_name}) 语法强制指定 ap :

SELECT a.*, b.order_id

FROM t_seller a

JOIN t_order b FORCE INDEX(cc_i_seller) ON a.seller_id = b.seller_id

WHERE a.seller_nick="abc";

数据同步

PolarDB-X 的列存数据同步基于 Binlog 主从复制实现,对于新建列存索引时表内已有数据,或者历史 binlog 文件已过期不存在,对这种场景有特殊处理逻辑:

当列存引擎在binlog事件流中,检测到创建列存索引ddl事件后,便开始同步该表DML操作,形成的数据称为增量数据,同时会另起线程去PolarDB-X行存通过select逻辑捞取已有的全部数据,称为全量数据。等全量数据捞取完毕,最后将全量数据和增量数据进行合并,便是该列存索引的所有数据,后续继续同步binlog数据即可。

存储

PolarDB-X 的列存存储采用Delta Main 模型(类 LSM 树结构),核心设计思想为:写入时采用顺序写入数据,数据更改以追加记录形式实现,追加记录认为是Delta Data(增量数据),等Delta Data写满阈值,转成Main Data数据(主体数据),一个单位内的数据可以认为是一段范围内的数据、一个分区内的数据或者一个文件内的数据,可根据实际情况进行分隔,这样对读性能进行优化,一段范围内的数据只需要读取Main Data和Delta Data,需要归并的数据大大降低,并且利用后台异步线程尽可能将Delta Data数据转成Main Data,进一步减少读开销。

关于 ddl

通过 binlog实现 同步。

参考资料

https://help.aliyun.com/zh/polardb/polardb-for-xscale/column-store-index/?spm=a2c4g.11186623.help-menu-2249963.d_4_12_4.3a013f50vJzYLF&scm=20140722.H_2618539._.OR_help-T_cn~zh-V_1

https://zhuanlan.zhihu.com/p/2359967708

https://www.polardbx.com/document?type=PolarDB-X

GoldenDB

概述

GoldenDB 可创建行存模式表、列存模式表和行列混合表三种表类型。 GoldenDB 对行列混合表同时在行存存储节点和列存存储节点创建表,并通过 Binlog 日志同步组件自动进行数据准实时同步。

应用的 SQL 请求统一通过 CN 接入,CN 根据 SQL 所访问表的存储类型进行自动路由:CN 可直接访问行式存储,或者通过 AP 的Coordinator/Worker 调度,对行式表或列式表进行查询计算。

说明:GoldenDB 的 HTAP 相关技术资料尚不完善,本次调研仅基于现有公开资料分析。

架构

_scroll_external/attachments/goldendb1-7bea0d4e08552e04a1c6dbac31c6f0331cfdd58a2e2157ab5826cfc8aa8ea90c.png

GoldenDB TP 部分由计算节点(CN)处理,并可增加AP组件(Coordinator 和 Worker)进行 SQL 统计查询。

GoldenDB 可选装列存存储 VEngine 节点,适用于交互式 SQL 数据仓库应用场景。通过 VEngine 节点,可创建行存模式表、列存模式表和行列混合表三种表类型。 GoldenDB 对行列混合表同时在行存存储节点和列存存储节点创建表,并通过日志同步组件自动进行数据准实时同步。
应用的 SQL 请求统一通过 CN 接入,CN 根据 SQL 所访问表的存储类型进行自动路由:CN 可直接访问行式存储,或者通过 AP 的Coordinator/Worker 调度,对行式表或列式表进行查询计算。

使用

目前暂无 GoldenDB 创建与管理列存表 / 列存索引的确切语法,根据现有资料推测:列存相关配置对用户可见,支持手动创建列存表,以及行存、列存、行列混合表的灵活切换_。_

使用 ap 查询的方法

GoldenDB 的 AP 查询采用全自动路由方式,由 CN 节点根据查询涉及表的存储类型、负载特征,自动调度至对应节点 / 组件执行,无需用户手动干预。

数据同步

列存数据基于 MySQL 的 Binlog 日志复制并转换而成。

参考资料

https://goldendb.com/#/docsIndex/docs/GoldenDB/v6.1.03.10/easyOperate_SQLBasicOperations

https://www.zte.com.cn/content/dam/zte-site/res-www-zte-com-cn/goldendb/%E9%87%91%E7%AF%86%E4%BF%A1%E7%A7%91GoldenDB%E6%95%B0%E6%8D%AE%E5%BA%93V6%E6%8A%80%E6%9C%AF%E7%99%BD%E7%9A%AE%E4%B9%A6.pdf

https://www.zte.com.cn/content/dam/zte-site/res-www-zte-com-cn/mediares/golden_db/pdf/report2024010303.pdf

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐