《FusionInsight LibrA Huawei’s Enterprise Cloud Data Analytics Platform》解读

概述

2018年华为在vldb 上发表了论文《FusionInsight LibrA: Huawei’s Enterprise Cloud Data Analytics Platform》。 这篇论文罗列了LibrA 的架构和很多powerful的功能, 整体看下来, 特别亮瞎眼睛的功能到没有,但在工程的角度,介绍很多很接地气的做法, 比起很多列一大堆数据公式, 一大堆机器学习的算法论文,可读性更强, 也更好理解数据库的实现和优化。

FusionInsight MPPDB, 又称Libr, 后来又改名为高斯200, 是针对olap 分析的一款mppdb 数据库。 高斯200 是高斯部门很成功的一款产品。从2012年开始研发, 2014年第一代原型研发出来, 现在已经在全球大量使用, 包括最大的金融企业工行。并且以用户为导向,实现了很多powerful的功能,如在线扩容, 自动tuning, sql on hdfs, 智能jit 编译执行(llvm code gen), 提供行列混存, 数据压缩特性, 智能workload管理, 为提高高可用增加重试失败request, 用sctp 协议替换tcp协议以提高scalability等等。

发展史

最早的原型是基于postgres-xc来实现, 采用share nothing 架构, 支持ansi 2008 sql 语法标准。 2014年第一代原型,完成向量化执行, 并行线程执行, 并且主要用于分布式存储的元数据分析。

第二代推广给金融和电信领域用户, 第二代以后以用户需求为导向, 增加很多实用的功能, 如系统可用性, 自动tuning, query 异构数据(尤其云上), 利用新硬件等。

2016年开始支持sql-on-hadoop, 可以让mpp engine跑在hadoop上, 而不用把数据从hdfs迁移到libr上, 用户对这个需求十分强烈,并让libr 在2016年成为FusionInsight 的产品。

2017年Libr 上云, 四大特性, 1. 系统可用性; 2. 自动tuning; 3. 可以query 大量异构数据模型;4. 充分利用新硬件。

功能介绍

  1. 高可用, 增加节点或升级,通过在线扩容或在线升级, 很少影响客户业务。 系统可以线性扩容, 以支持几百台机器去处理高并发ad-hoc。
  2. 自动tuning, oracle的自驱动数据库强调了数据库的自我管理和自我tuning, 利用机器学习对runtime的反馈进行自我tuning。
  3. 异构存储, 客户存有各种现成的数据, DataLake 变得流行, 2016年提供SQL-ON-HADOOP 后, 这个功能大受欢迎。
  4. 支持新硬件, 现代机器配置大内存, 数据库可以reside in 内存, fast io device如ssd, optane。
  5. 通过在执行引擎上使用jit 动态编译 code generate 的方式来对query 进行加速。 query 产生的特定的runtime机器码可以省掉传统的解析开销(理论上还有大量的出入栈和虚函数调用等开销), 最后对结果进行分析, jit 编译效果由编译带来的开销和优化的可执行代码带来性能提升 来决定。
    支持行存和列存 混存。
  6. 向量化执行引擎使用了最新的simd 指令集。

事务支持

  1. datanode 是分区来管理, 支持本地acid 语义。跨分区一致性由二阶段提交和全局事务管理器来进行管理。
  2. 创新的使用了gtm-lite, 分布式事务管理, 单分区事务可以被加速, 因为避免了获取中心事务id 和全局snapshot。
  3. 支持read committed 事务隔离级别。

高可用强化

连接优化

如果使用tcp/ip 协议, 当几百台机器互联是, connection 急剧增加, 如1000个node集群, node 之间的连接会超过1百万(1000个节点 * 100 个并发 * 10个exchange operator), 研发了一种新的协议, 每个数据交换的提供方和消费方组成一个虚拟连接。 多个虚拟连接可以共享一个物理连接, libr 选择了sctp协议, 它支持可靠传输, 一个物理连接上可以支持64k的逻辑连接, 并且支持带外流控。

分组模式

高可用主动模式和同步机制, 节省存储空间至关重要, 当备机挂了后, 会启动一个节点只做log-copy操作来提升可用性, 当备机挂了, 主节点依旧可执行bulk load和dml。

资源管理器

workload 管理器, 管理query的并发书, 做了限流功能, 分为3个部分, 资源池, workload组和一个controler。 资源池管理内存和磁盘i/o, 设置各种阀值来决定是否执行。workload group 用于分配请求的query到资源池。 用应用名来标示query(估计资源分组)。

控制器,评估query的cost和系统当前的可用资源来决定是否运行query, 当不满足时,query 进入等待队列。 资源的预申请和反馈用于追踪系统的可用资源。

在线扩容

在线扩容, 最大的问题是如何将数据分布到新的节点, 通常是对distribute key 进行计算来决定(hash算法, round-robin, modulo算法), 通常这些算法会依赖节点数, 数据重新分布需要恢复一致性和在分配算法和实际数据位置。 hash算法可能导致数据倾向, 导致有些节点out of space, 这种情况下,需要采用新的hash 算法来进行平衡。 简单的一种做法是使用影子表, 原始表可以继续被查询, 直到 数据被分布到新的节点, 分布属性是不含新节点。 一种让数据可被访问,在重分布过程中, 使用random算法替换hash 算法。 这种方式会让性能下降, 相关查询(collocation join)不支持,另外写或修改也是不允许的。

librA 使用shadow table, 但没有让表只读, 让表append-only, 并阻止存储空间的recycle。 这种方式可以很快识别哪些record是新增的,哪些是历史的, 创建一个表存储删除的数据, 然后lock 表, apply append的delta, 再apply delete的delta, 于此同时, shadow table 会增加一列隐藏列rowid。 这样好处可以一个minibatchi 接着一个minibatch 执行, 并且支持重来和resume。

算法。

  1. 创建T的影子表。
  2. Mark t as append-only
  3. disable garbage collect on T
  4. create delete-delat D for delete on T
  5. redistribute a segment from T 到 S
  6. apply D on S, 并且重试D 当apply D完时
  7. 提交修改
  8. 重复执行执行,直到T的数据小于一个阀值
  9. Lock T, 重复5 和6
  10. 在catalog中, Switch T as S,
  11. 提交修改
  12. rebuild index

自动tuning

  1. 基于 data exchange 的cbo来生成mpp 的plan
  2. cbo 基于vector 执行和多种文件系统如orc
  3. query rewrite engine, 在olap系统中添加一些额外的 rewrite 很关键
  4. 基于机器学习的cutting edge 技术
  5. 早期的优化器的机器学习是基于统计学, 需要大量的资源投入, 不通的数据来源不同的数据格式又要求合适的精度带来很大的挑战。
  6. 可选捕获执行参数,为后续类似提供精确参考, 这种方式比传统数据收集方式代价要小。

SPM

执行器可选捕获执行计划到plan store。 每一个步骤 scan, join, aggregation, 并预估和实际获取的row counts, 一般情况下, 预估值和真实值是有很大出入的。 plan store 另外一个功能是用于sql 审计和离线分析。

  1. 优化器从plan store中获取statics 用于cbo而不是自己评估的, 如果没有找到,则使用自己评估的
    plan store 类似一个cache,可以通过api来高效获取数据。
  2. plan store的cache 封装不同步骤的信息,保护step type, step prediction和input descritption。
  3. 早期, 对于scan和join做了statics learning。这个阶段称为selectivity matching.
  4. 除了抽取之前存取的谓词, 自动tuning可以用于类似谓词。 可以收集predicate selectivity的反馈到谓词cache(不同之前的plan store cache)中, 并用它来评估类似的情况。 许多机器学习或statics learning 算法技术可用在这个阶段, 我们称这第二个learning为similarity selectivity。similarity selectivity模型最初用于复杂的predicate 如x》y+ c, x和y都是column,而c是常数。 在date field经常碰到这种情况 如tpch中。 这种predicates 给query 优化带来一种挑战并且他们是一种好的candidates 来做similarity selectivity。 libra 使用knn(k nearest neighbors)来获取similarity selectivity。

SQL-ON-Hadoop

通过pq foreign data wrapper来访问hdfs, bypass hadoop mr 框架, 引入一个调度器, 动态吧文件的分片分配到mpp的节点上进行计算, 一个hdfs目录被影射到db的外表,这个外表支持分区表。 因为hdfs的分区是基于目录的, 优化器可用做一些优化操作从而跳过一些分区而减少io操作。 支持orc或parque 格式, 这些格式内部保护一些index,充分利用这些信息。 hdfs 客户常常有2个额外的要求, 1. dml和acid 支持; 2. 要求更好的性能(需要知道data collocation)

性能优化

  1. 优化器可用做谓词下推优化操作,减少io。
    query engine支持向量化执行。
    使用动态 多维 runtime 过滤 从start join 到分区裁剪。

  2. better data collocation
    商业数据库通过一致性hash算法来达到data collocation, 标准db 一般要求数据shuffle在join或group by之后。

2种data collocation
mppdb 和hdfs node之间的data collocation, mapp datanode 读取hdfs的data 通过快速的本地读接口。

table collocation在hdfs node, table 被分区到hdfs 不同的data node上,执行co-located join和group 来减少网络shuffle

当把数据通过mppdb data node 导到hdfs上, 用一个本地描述的table 来记录每个节点每个文件的ownership。 datanode 序列号数据到特定的pax 格式文件(orc/parquet)到hdfs。 这个本地table 由一列组成, 如blockid, min/max 一个block每个列, 删除列的bitmap。

通过hdfs hint 来尽可能本地访问。

DML

block map 决定了block中row的可见性, 先把数据插到row base的delta table, 当delta table到了一定量,刷hdfs (orc/parquet), 如果在delta table删除数据,则直接删除数据, 如果数据在pax file时删除,在block map的bitmap中,标记这个行被删除, 当删除的行超过一定阀值, 执行compaction操作。

 # 未完待续
后续讲了一下优化器的优化
以后有机会补充一下