Huawei FusionInsight LibrA (FI-MPPDB)是OLAP系统,从《openGauss数据库核心技术》这本书上的描述看LibrA就是GaussDB200,从openGauss的代码上看,openGauss的OLAP特性也是来自这个产品。
ABSTRACT
本文讲述FI-MPPDB的4个方面:
- system availability:online expansion和online upgrade;
- auto tuning:runtime feedback+machine learning;
- SQL on HDFS解决方案;
- modern computer systems:cost-based JIT;
1.INTRODUCTION
FI-MPPDB是sharenothing的MPP系统,基于Postgres-XC开发。支持行列混存,压缩,向量化等OLAP的典型技术。
2012年开始研发,2014年具备prototype。
- V1版本:向量化和线程模型;
- V2版本:支持列存,压缩,智能query调度,使用SCTP协议替换原来的TCP;
2016年FI-MPPDB支持SQL on Hadoop特性。类似HAWQ,FI-MPPDB直接读取HDFS和分区表这样能避免数据移动,兼容2008SQL标准,支持完整的ACID(借助本地heap表来实现)。
2017年FI-MPPDB在华为云售卖,也就是LibrA。
2. TECHNICAL DETAILS
2.1 System Overview
可以看到跨partition时通过2PC和GTM完成事务,这里有个fastpath的优化:只涉及到单个parition时无需过一次GTM。
2.1.1 Communication
为了避免连接风暴,每个节点上启动Communication Service:多个逻辑连接共享物理连接。
使用SCTP协议替代TCP:
- message based的多地址连接协议;
- 65535个streams共享一个SCTP连接;
- 支持out-of-band的控制协议;
2.1.2 High Availability and Replication
为了高可用,每个DN节点都对应一个从节点, 此外,还多了一个log-only的副本:
- 当secondary节点宕机,primary节点仍然可以继续服务,因为log-only节点仍能保证log的副本数;
- 当secondary节点恢复后无需从primary上catchup;
2.1.3 Workload Management
- 避免不同query竞争导致雪崩;
- 调度:resource pools, workload groups, and a controller:所有query和resource pool关联,workload group负责管理workload并发新进来的query加入到resource pool中;如果query执行代价大于系统的剩余负载,当前query进行排队;
2.2 Online Expansion
2.2.1 Solution Overview
目标:在数据重分布过程中,原库仍然能够执行DML和查询
方法:
- 原表进入appendonly模式;
- 重分布过程中:append-delta数据;delete-delta数据;
- 查询时使用上述3部分数据构造出真正可见的数据;
2.2.2 Core Algorithm
shadow表中新增隐藏列:original_tuple_key,用于删除迁移期间被删除的Tuple。
- 原表T按照ctid分成一个个的segment,新增数据追加在T后面;
- 对T逐个segment重分布到S中,过程中被删除的Tuple在D中,当迁移完这个segment时对D中记录的tuple进行删除,并清空D。注意:可能在复制后续segment时出现对前面segment中数据的删除;
2.3 Auto Tuning in Query Optimizer
FI-MPPDB的优化器能够:
- 基于cost产生MPP的计划;
- 感知向量化执行和不同底层存储的不同代价(ORC);
- 基于运行时反馈+machine learning适配更多优化场景(估算predicate selectivity);
基于运行时反馈进行machine learning,这么做效果好的一个假设是OLAP的业务SQL都比较固定。
优化估算的行数和实际执行时反馈的行数收集是算子级别的:scan,join,agg。
PlanStore存储算子的反馈信息:算子类型+参数+predicate
如何使用PlanStore:
- selectivity matching:对scan和join算子的统计数据估算;
- similarity selectivity:对相似predicate估算
predicate cache;
KNN算法,K个最近邻居的平局值;
2.4 MPPDB over HDFS (aka SQLonHDFS)
2.4.1 SQLonHDFS using Foreign Data Wrapper
- Gauss MPPDB Coordinator接收SQL;
- Planner生成分布式计划,期间需要从HDFS的name node读取表的分布信息;
- 分发plan fragment和task map;
- data node从本地和HDFS远端读取;
HDFS上的优化:
- HDFS一个目录对应一个FDW表;
- 可以对表进行分区,一个子分区一个HDFS目录,因此可以做分区裁剪;
- 对于ORC等格式,可以做下推;
- 支持向量化;
- 星型join做runtime filter优化;
2.4.2 Advanced Data Collocation and Hash Partitioning
(类似HAWQ)
- FI-MPPDB的datanode在HDFS上的data node上,通过short-circuit直接读取HDFS数据;
- 借助hash分区表对于co-locate的join能进一步减少网络;
每个datanode上的DB实例通过本地的表记录文件的owner和min/max元信息:block id, min/max, bitmap of deleted, block locater。
由于HDFS数据3副本存储,因此该本地的表也是3副本
2.4.3 DML support
通过block map表支持完整的ACID。
- 写入:为了提高写入性能,小批量数据先写入本地的delta表,当积累到一定数量时再转成PAX根式写入HDFS中;
- 删除:如果删除的数据在本地delta表中则立即删除;如果在PAX中,在block map表中的delete map做标记;
- 定期做compaction;
2.5 Intelligent JIT Compiled Execution
3种执行模式:
- 普通解释执行,没有JIT;
- 有JIT,低级别优化;
- 有JIT,O3级别优化;
JIT编译IR本身需要耗时,因此需要对JIT进行精确的cost计算,这样优化器才能决定是否对一个函数或者一段代码片段进行JIT。PostgreSQL的JIT目前还是静态的基于cost阈值来判断是否需要JIT,FI-MPPDB的处理算是一个创新性工作。
P = (T1− T2) × N − Tjit_cost
T1:没有JIT的代价;
T2:使用JIT优化后的代价;
N:数据集大小;
Tjit_cost:JIT本身消耗的代价,和待生成代码大小成正比;
如果P为正,则说明使用JIT之后仍然有收益;
3. EXPERIMENTAL RESULTS
3.1 Online Expansion
运行TPC-DS期间进行扩容
结论:
- online expansion整体比offline方式慢,但是期间仍然能够查询和DML;
- hash分布比随机分布快20%;
3.2 Auto Tuning in Query Optimizer
select o_orderpriority, count (∗) as ct from lineitem, orders where l_orderkey = o_orderkey and l_receiptdate <op> l_commitdate + date ':?';
大多数优化器在预测predicate selectivity时采用固定的比例,比如使用1/3做为selectivity。
下图是实际的selectivity数值:
3.2.1 Hash join plan problem
对于hashjoin,选择正确的表来build hash是优化器的关键所在。
基于machine learning之所以能提升性能:不同的predicate会导致scan出来的数据有很大的差异,进而会影响join的顺序。可能很大的表在经过predicate之后scan出来的结果集很小。
3.2.2 Unnecessary data shuffle
HDFS的数据分布是按照round robin来进行的,因此,不具备co-located。数据需要shuffle:
- 对其中一个表broadcast;
- 两个表都hash分布;
predicate selectivity的估算影响数据shuffle的策略。
3.2.3 Insufficient hash buckets for hash aggregation
predicate selectivity的估算还会影响hashjoin时bucket的预分配。如果bucket不足时就需要重分布,2倍的性能差距。
3.2.4 Join Selectivity Experiment
前面讲述了Table scan selectivity learning的效果,此外,该方法还能用于评估join predicate selectivity。
在join时对join的条件selectivity 的估算也很重要,影响多个表的join顺序。
3.3 Cache Model-based Selectivity Estimation
结论:
- 单个参数,评估的错误比率不超过4%;
- 2个参数,评估的错误比率不超过6%;
- 即使predicate cache很小,错误比率也不高;
3.4 Advanced Data Collocation Performance Improvement for SQLonHDFS
结论:在HDFS上支持hash partition之后能显著减少shuffle,TPCH测试能提升30%。
3.5 Intelligent JIT Compiled Execution
结论:
- 基于cost的JIT能够选择出最后的优化级别;
- TPCH整体29%的提升;
4. RELATED WORK
Online Expansion
- Greenplum:扩容时提供queyr,但阻塞DML;
- Amazon Redshift:老clsuter进入readonly;
Auto Tuning
SQL Server和DB2也有autotuning的功能,专注在predicate selectivity和column correlation。没有支持通用算子的selectivity,比如:join。
FI-MPPDB基于learning的方式更加简介:基于运行时真实的反馈来估算每个算子,使用predicate cache和KNN提供了similarity selectivity的估算。
SQL on HDFS
- HAWQ:实现了直接读写HDFS和YARN的库来提高性能;
- SQL Server PDW:支持SQL直接管理和读取Hadoop集群,同时支持索引来加速查询;
- Spectrum:支持广泛的数据源,比如:ORC,Parquet,CSN;
Intelligent JIT Compiled Execution
- Amazon Redshift and MemSQL:SQL转成 C/C++;
- Cloudera Impala and Hyper:使用LLVM IR,没有精细化的代价模型;
- Spark 2.0’s Tungsten:通过运行时字节码优化将query转成单个函数;
- FI-MPPDB:使用LLVM,并且有精心化的代价模型;
5. FUTURE WORK AND CONCLUSION
- 云原生:支持多种云存储,SQL on OBS/S3;
- 智能调优:selectivity learning和parameter learning;