随着数据爆炸式的增长,传统的OLTP和OLAP解决方案基于简单的读写分离或ETL模型,将在线库的数据以T+1的方式抽取到数据仓库中进行计算,这种方案存在存储成本高、实时性差、链路和维护成本高等缺陷。 为应对数据爆炸式增长的挑战,PolarDB分布式版本基于对象存储设计了一套列存索引(Clustered Columnar Index,CCI)功能,支持将行存数据实时同步到列存存储上,并支持以下功能:
PolarDB分布式版将给您提供低成本、实时性高,完全兼容MySQL的一体化透明的HTAP解决方案。
随着云原生技术的不断普及,以Snowflake为代表的新一代云原生数仓、以及数据库HTAP架构不断创新,可见在未来一段时间后行列混存HTAP会成为一个数据库的标配能力,需要在当前数据库列存设计中面相未来的低成本、易用性、高性能上有更多的思考
PolarDB-X提供列存索引的形态(Clustered Columnar Index,CCI),行存表默认有主键索引和二级索引,列存索引是一份额外基于列式结构的二级索引(覆盖行存所有列),一张表可以同时具备行存和列存的数据。
1.云原生架构(存计分离、低成本)
PolarDB-X 列存索引,采用云原生对象存储OSS作为主要数据存储(成本仅为本地盘的1/6 ~ 1/10),同时结合列存数据本身的高压缩性(3~5倍),可以提供非常有竞争力的低成本优势。在构建HTAP行列混存的场景,额外的列存存储成本,可以控制在行存的存储成本5%~10%。
PolarDB-X 列存索引的存储采用Delta+Main(类LSM结构)二层模型 + 标记删除的技术,确保列存索引使用对象存储OSS也具备高并发更新能力。同时,在列存读取对象存储OSS的链路上,采用多层数据Local Cache、以及多级统计信息机制,尽量减少不必要的远端OSS存储访问。
2.分布式 (线性扩展)
传统分布式数据库,业界常见基于Paxos/Raft的多副本机制构建列存,但OLTP和OLAP各自的查询场景会有不同的诉求,对资源的依赖程度也不同,不同副本之间强一致分区策略/扩缩容机制,使得TP和AP的线性扩容能力容易相互制约,影响性能。
PolarDB-X 列存索引,基于分布式事务的binlog日志实时同步,实现行转列(M:N)的异构转换,同时可以定义列存索引特有的分布式分区键、排序键等,结合分布式的并行技术,提供列存查询的线性扩展能力。同时行存和列存存储介质相互隔离,存储和计算资源也更易弹性,在分布式背景下列存查询更易追求极致的线性扩展能力。
3.读写分离(serverless,按读的使用付费)
PolarDB-X 列存索引,采用组件写和读分离的架构设计,分为列存写和列存读。列存的写节点(Columnar节点),属于有状态的节点,并不直接对外提供写请求,通过Group Commit技术批量更列存索引数据。列存的读节点(CN节点),继承CN节点无状态的设计,通过GMS节点获取列存的元数据,直接访问OSS对象存储上的列存索引数据。
PolarDB-X 实例创建,系统会默认提供列存写的组件(Columnar节点,长期运行并同步列存索引),用户只需通过DDL语法创建列存索引后,列存索引数据就会自动构建并保持实时更新。业务可以通过主实例、或者购买新的只读实例(CN节点),就可以正常访问行存和列存索引,同时无状态的CN节点特别适合serverless模式,用户只需为列存读的使用付费。
4.行列混合 (易用性,一体化向量化SQL引擎)
PolarDB-X 复用CN节点自研的SQL引擎,提供了列存读的完整能力。构建面向行列混合场景的代价优化器,根据代价智能识别路由,将OLTP类查询转发给行存查询链路、以及将OLAP类查询转发列存查询链路,同时支持在SQL算子级别访问不同的行存和列存,全面落实HTAP的行列混合能力,支持一套SQL引擎的统一访问。
PolarDB-X 全面拥抱向量化,针对列存的TableScan读取,采用列式chunk的数据结构,后续中间的算子计算也全面继承chunk的内存列式结构,基于全链路的向量化提升查询性能。同时针对行存的TableScan也会动态转化为列式chunk,基于统一的数据结构实现行列混合查询。
5.库仓一站式(Zero-ETL)
传统数据仓库,会通过数据ETL方式同步数据,采用MPP/BSP等并行计算架构可以很好解决OLAP复杂查询,但面相高并发的数据在线查询(Serving场景)会有明显的资源并发瓶颈,会通过数据回流到OLTP数据库提供在线查询。
PolarDB-X结合ADB提供了库仓一站式的能力,基于“Zero-ETL”的设计理念,采用共享同一份列存索引的数据,基于ADB的数据仓库能力可以满足多方的数据汇总和数据关联查询,提供传统意义上的数仓和湖的分析。同时,针对在线数据的并发查询可以使用PolarDB-X的HTAP行列混合架构,整个过程可以避免传统的数据ETL。
PolarDB-X对MySQL DDL语法进行了扩展,增加定义CCI的语法,使用方式与在MySQL上创建索引一致,可以参考列存索引的语法文档
实际例子:
# 先创建表
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;
列存索引是由列存引擎节点来构造的,构建的数据最终会以CSV+ORC两种数据格式,存储在共享对象上。其中CSV往往存储的是实时的增量数据,过多的增量数据会及时做compaction,转储成ORC格式。不管是CSV还是ORC格式,PolarDB分布式版本对两种存储格式都做了增强,既继承了原生格式的开源开放的特征,又确保了这两类格式可以完全表达MySQL的数据协议。
从数据同步去看,构建过程往往是由全量快照读取+增量同步两条并行的同步链路共同完成的。先建列存索引,再导数据,这个场景下只有增量数据同步,Columnar节点会同时消费Binlog数据,构建索引;先导入部分数据,再建列存索引,继续导数据,这个场景除了有增量同步链路,Columnar节点会同时消费已有的全量数据,增量和全量并行消费,提速列存构建的效率。
从层次结构去看,列存引擎节点采用Delta+Main(类LSM结构)二层模型,采用了标记删除的技术,确保了行存和列存之间实现低延时的数据同步,可以保证秒级的实时更新。数据实时写入到MemTable,在一个group commit的周期内,会将数据存储到一个本地csv文件,并追加到OSS上对应csv文件的尾部,这个文件称为delta文件。OSS对象存储上的.csv文件不会长期存在,而是由compaction线程不定期地转换成.orc文件。
PolarDB分布式版本的流量是由计算节点(CN)承担,做查询分析。
从上图可以看整个查询加速链条分为优化器、执行器、存储引擎三个层面。 从优化器看,PolarDB分布式版本提供了面向行列混合场景的代价优化器,根据代价智能识别路由,将TP类查询转发给行存查询链路;将AP类查询转发列存查询链路。
从执行器看,PolarDB分布式提供的是面向行列混合场景的一体化执行器,一套执行器同时支持HTAP场景。同时算子层做了向量化改造,支持了MPP加速加速技术,在复杂查询场景中,可以充分利用多节点资源并行计算,保证了高吞吐的复杂查询需求。
为了抵消存储计算分离架构带来的网络延迟,执行器层也引入了本地缓存技术,将热数据实时加载到本地磁盘,保证了低延迟的查询需求。 从存储引擎看,列存索引的构建保证了事务提交的原子性,确保查询上可以查询到事务级别一致性的数据。
在引入了列存引擎后,PolarDB分布式版本在原有的主实例和只读实例产品规格之外,增加了列存只读实例产品规格。
PolarDB 分布式版的列存索引特性提供了一站式HTAP产品体验,可以应用于多种业务场景:
对在线数据有秒级的实时数据分析需求的场景,如实时报表业务;
专用数据仓库场景:依托PolarDB分布式提供的海量数据存储能力,汇聚多个上游数据源,将其作为专用数据仓库使用;
ETL计算场景:依托PolarDB分布式基于列存索引提供的强大而灵活的计算能力。
PolarDB分布式版本结合列存索引特性,其优势不仅仅在于一套数据库产品可以同时解决TP和AP的混合场景需求,同时基于云原生的对象存储和智能路由技术,给用户提供的是透明的低成本的HTAP解决方案。
测试集:TPC-H 100GB 硬件环境
软件
涉及TPC-H的表,在线增加列存索引,整个测试操作可以参考列存索引TPC-H性能白皮书
create clustered columnar index `nation_col_index` on nation(`n_nationkey`) partition by hash(`n_nationkey`) partitions 1;
create clustered columnar index `region_col_index` on region(`r_regionkey`) partition by hash(`r_regionkey`) partitions 1;
create clustered columnar index `customer_col_index` on customer(`c_custkey`) partition by hash(`c_custkey`) partitions 24;
create clustered columnar index `part_col_index` on part(`p_size`) partition by hash(`p_partkey`) partitions 24;
create clustered columnar index `partsupp_col_index` on partsupp(`ps_partkey`) partition by hash(`ps_partkey`) partitions 24;
create clustered columnar index `supplier_col_index` on supplier(`s_suppkey`) partition by hash(`s_suppkey`) partitions 24;
create clustered columnar index `orders_col_index` on orders(`o_orderdate`,`o_orderkey`) partition by hash(`o_orderkey`) partitions 24;
create clustered columnar index `lineitem_col_index` on lineitem(`l_shipdate`,`l_orderkey`) partition by hash(`l_orderkey`) partitions 24;
基于列存索引的TPC-H运行,以下结果的时间单位为:秒(s)
上表展示了列存索引 TPC-H 100G 的性能随着规格等比变化的提升比例,体现了分布式的线性扩展能力。
数据库PolarDB-X新人入门一站式页面,快速体验集中分布式一体化新特性!
本文为阿里云原创内容,未经允许不得转载。
|