数据库管理207期 2024-06-19
- 数据库管理-第207期 HTAP核心:列存技术探索(20240619)
- 1 Oracle In-memory
- 1.1 基本概念
- 1.2 基本测试
- 1.3 Exadata增强
- 2 OceanBase
- 3 TiDB
- 4 PolarDB
- 总结
数据库管理-第207期 HTAP核心:列存技术探索(20240619)
作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Pro: Database(Oracle与MySQL)
PostgreSQL ACE Partner
10年数据库行业经验,现主要从事数据库服务工作
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP、认证技术专家、年度墨力之星,ITPUB认证专家、专家百人团成员,OCM讲师,PolarDB开源社区技术顾问,HaloDB外聘技术顾问,OceanBase观察团成员,青学会MOP技术社区(青年数据库学习互助会)技术顾问
圈内拥有“总监”、“保安”、“国产数据库最大敌人”等称号,非著名社恐(社交恐怖分子)
公众号:胖头鱼的鱼缸;CSDN:胖头鱼的鱼缸(尹海文);墨天轮:胖头鱼的鱼缸;ITPUB:yhw1809。
除授权转载并标明出处外,均为“非法”抄袭
HTAP,之前的文章里面介绍了很多次了,简单点就是Online TP+AP,既满足在线交易需求,也满足部分实时数据分析的要求。而解决HTAP场景目前主流的方法就是在行存的基础上通过列存来实现快速分析。
1 Oracle In-memory
以下内容基于Oracle Database 23ai。
1.1 基本概念
Oracle In-memory功能集包括In-Memory列式存储(IM列存储)、高级查询优化和可用性解决方案。In-memory优化使得在数据仓库和混合使用数据库场景中能更快的运行大数据量分析查询。
以下对象可以使用In-Memory:
- 列(包含虚拟列)
- 表分区(内部或外部表)
- 表(内部或外部表)和物化视图
- 表空间
在Oracle数据库中使用In-memory需要现在SGA中分配一个专门用于In-memory的固定大小的内存区域并重启数据库来开启这一功能:
ALTER SYSTEM SET INMEMORY_SIZE = 16G SCOPE=SPFILE;
-- Restart the database
后续如需增加则只需要通过SCOPE=BOTH调整即可,无需重启数据库。然后可以通过自动或手动的方式将上面的对象加载到In-memory内存区域中。
Oracle In-memory还支持不同级别的压缩:FOR DML, FOR QUERY (LOW or HIGH), FOR CAPACITY (LOW or HIGH), or NONE。或者指定为AUTO(需配合数据库参数INMEMORY_AUTOMATIC_LEVEL)由数据库自动判断压缩级别。
CREATE TABLE range_sales
( prod_id NUMBER(6)
, cust_id NUMBER
, time_id DATE
, channel_id CHAR(1)
, promo_id NUMBER(6)
, quantity_sold NUMBER(3)
, amount_sold NUMBER(10,2)
)
PARTITION BY RANGE (time_id)
(PARTITION SALES_Q4_1999
VALUES LESS THAN (TO_DATE('01-JAN-2015','DD-MON-YYYY'))
INMEMORY MEMCOMPRESS FOR DML,
PARTITION SALES_Q1_2000
VALUES LESS THAN (TO_DATE('01-APR-2015','DD-MON-YYYY'))
INMEMORY MEMCOMPRESS FOR QUERY,
PARTITION SALES_Q2_2000
VALUES LESS THAN (TO_DATE('01-JUL-2015','DD-MON-YYYY'))
INMEMORY MEMCOMPRESS FOR CAPACITY,
PARTITION SALES_Q3_2000
VALUES LESS THAN (TO_DATE('01-OCT-2015','DD-MON-YYYY'))
NO INMEMORY,
PARTITION SALES_Q4_2000
VALUES LESS THAN (MAXVALUE));
ALTER TABLE sh.countries INMEMORY MEMCOMPRESS FOR CAPACITY HIGH;
ALTER TABLE sh.countries INMEMORY MEMCOMPRESS AUTO;
ALTER TABLE oe.product_information
INMEMORY MEMCOMPRESS FOR QUERY (
product_id, product_name, category_id, supplier_id, min_price)
INMEMORY MEMCOMPRESS FOR CAPACITY HIGH (
product_description, warranty_period, product_status, list_price)
NO INMEMORY (
weight_class, catalog_url);
数据库根据加载在配置了In-memory的对象的使用情况将对应数据加载到In-memory内存区域中,也可以使用full scan或者对应的PL/SQL来实现:
SELECT /*+ FULL(customers) NO_PARALLEL(customers) */ COUNT(*) FROM customers;
BEGIN
DBMS_INMEMORY.POPULATE( schema_name => 'SH', table_name => 'CUSTOMERS');
END;
/
1.2 基本测试
create table im_test as select * from dba_source;
--将表信息加载至内存buffer cache中
select /*+ full noparallel */ count(*) from im_test;
set timing on
set autotrace on
select /*+ use cache */ max(line) from im_test;
alter table im_test inmemory;
exec DBMS_INMEMORY.POPULATE( schema_name => 'TEST', table_name => 'IM_TEST');
select /*+ use inmemory */ max(line) from im_test;
从执行时间和执行计划来看,In-memory还是带来了十分显著的性能提升,这里由于数据量的问题就不做不同压缩级别下的对比测试了。
1.3 Exadata增强
在Exadata中可以在计算节点使用行存或列存,在存储节点中则可以在PMEM/XRMEM和Flash Cache中实现列存,从而在整体架构中实现行列混存,以统一架构应对HTAP挑战。
2 OceanBase
这里基本上就搬运官方文档了(https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000819423),更多详细内容可以查看:参考指南->系统原理->存储架构->数据存储
在V4.3.0 版本,基于原有技术的积累,OceanBase 数据库的存储引擎继续扩展,实现了对列存的支持,实现存储一体化,一套代码一个架构一个 OBServer,列存数据和行存数据完美共存,真正实现了对 TP 类和 AP 类查询的性能的兼顾。
OceanBase 数据库作为原生分布式数据库,用户数据默认为多副本存储。为了利用多副本的优势,进一步增强用户在数据强校验以及迁移数据重用等方面的体验,自研的 LSM-Tree 存储引擎也做了较多的针对性设计。首先,每个用户数据整体可以分成以下两大部分:
- 基线数据
不同于其它主流 LSM-Tree 存储引擎的数据库,OceanBase 数据库利用分布式多副本的基础,提出了 “每日合并” 的概念,租户会定期或者根据用户操作选择一个全局版本号,租户数据的所有副本均以该版本完成一轮 Major Compaction,最后生成该版本的基线数据。所有副本同一个版本的基线数据物理上完全一致。 - 增量数据
相对基线数据而言,用户数据在最新版本的基线数据之后所有写入的数据均属于增量数据。具体来说,增量数据可以是用户刚写入 MemTable 的内存数据,也可以是已经转储为 SSTable 的磁盘数据。 对于用户数据的所有副本来说,增量数据中的各个副本独立维护,不保证一致,并且不同于基线数据是基于指定版本生成,增量数据会包含所有多版本数据。
基于列存应用场景随机更新量可控的背景,OceanBase 数据库结合自身基线数据和增量数据的特点,提出了一套对上层透明的列存实现方式:
- 基线数据存储为列存模式,增量数据保持行存,用户的所有 DML 操作不受影响,上下游同步无缝接入,列存表数据仍然可以像行存表一样进行所有事务操作。
- 列存模式下,每列数据存储为一个独立的 SSTable,所有列的 SSTable 组合成为一个虚拟 SSTable 作为用户的列存基线数据,如下图所示。
- 根据用户建表时指定的表的存储模式,基线数据可以有行存、列存、行存列存冗余三种模式。
OceanBase实现了SQL一体化、存储一体化、事务一体化。
3 TiDB
这里也基本搬运官方文档(https://docs.pingcap.com/zh/tidb/stable/tiflash-overview)
TiFlash 是 TiDB HTAP 形态的关键组件,它是 TiKV 的列存扩展,在提供了良好的隔离性的同时,也兼顾了强一致性。列存副本通过 Raft Learner 协议异步复制,但是在读取的时候通过 Raft 校对索引配合 MVCC 的方式获得 Snapshot Isolation 的一致性隔离级别。这个架构很好地解决了 HTAP 场景的隔离性以及列存同步的问题。
TiDB主要是在存算分离的存储层面,在TiKV节点之外使用TiFlashTiFlash 提供列式存储,且拥有借助 ClickHouse 高效实现的协处理器层。除此以外,它与 TiKV 非常类似,依赖同样的 Multi-Raft 体系,以 Region 为单位进行数据复制和分散。
TiFlash 以低消耗不阻塞 TiKV 写入的方式,实时复制 TiKV 集群中的数据,并同时提供与 TiKV 一样的一致性读取,且可以保证读取到最新的数据。TiFlash 中的 Region 副本与 TiKV 中完全对应,且会跟随 TiKV 中的 Leader 副本同时进行分裂与合并。
关于OceanBase和TiDB列式存储的对比,来自TiDB社区的表妹也写了一篇文章,可以参考:《我对 TiDB 和 OceanBase 列存的一些思考》https://mp.weixin.qq.com/s/_TDsP2ydsiFczRhrrqmolQ
4 PolarDB
继续继续,源自于PolarDB MySQL版的特性(https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/overview-29?spm=a2c4g.11186623.0.nextDoc.1095b805ivu1Ku)
PolarDB MySQL版的列存索引(In-Memory Column Index,简称IMCI)面向OLAP场景大数据量复杂查询。通过列存索引,PolarDB MySQL版实现了一体化的实时事务处理和实时数据分析的能力,成为一站式HTAP数据库产品解决方案。通过一套数据库系统,即可满足业务的OLTP及OLAP需求。
为了实现OLAP和OLTP的计算资源隔离,当前仅支持在只读节点上实现列存索引,即OLAP查询请求只发给只读节点,而不会发给主节点。
从以上架构图可以看到,PolarDB MySQL版从存储引擎、执行算子、优化器三个层面设计了列存索引的特性:
- 存储引擎:支持实时事务级别一致性的行列混合存储;
- 执行算子:面向列存的向量化并行执行算子,支持极速的单表和多表查询;
- SQL Parser/优化器:面向行列混合存储的CBO优化器,可以根据代价自动选择行存或者列存执行查询请求;
在此架构下,PolarDB MySQL版实现了100%兼容MySQL协议的基础上,同时获得数个数量级的查询加速效果。
总结
本期简单介绍了Oracle、OceanBase、TiDB和PolarDB的列存技术特性。
老规矩,算是知道写了些啥吧。