技术专栏丨Carbondata研究与阶段性压测


一、CarbonData简介

Apache CarbonData 是一种有索引的列存储格式。它非常适合于做即席 OLAP 查询。因为独特的 MDK 索引设计,能达到的极好的剪枝效果。相比于 parquet 等其他的列存储格式,性能有极大的提升。
Apache CarbonData 是由华为贡献给 apache 社区,目前已经是 apache 顶级项目。CarbonData 目前应用于华为的多个解决方案中,用于分析运营商的海量的信令面、用户面、控制面的详单数据。详单数据数据量达到数千亿,每条记录都是多维度的。CarbonData 用于这些海量数据的实时聚合分析。
除了华为之外,在美团、滴滴、hulu 等公司的生产环境中也得到了使用。目前 CarbonData 项目 intel、ebay、VMWare、美团、Talend等公司也有人积极参与贡献。比如 CarbonData 的 flink connector、spark streaming connector 等功能都是由华为之外的其他人贡献的。
 

二、CarbonData架构

2.1. CarbonData文件格式
CarbonData 文件格式如下:
 
一个 HDFS block 中会分为多个 blocklet。Blocklet 是文件内的列存数据块,是最小的 IO 读取单元。Column chunk 是 Blocklet 内的列数据。Page 是 Column chunk 内的数据页,是最小的解码单元。
File header 中存放元数据信息,包括 version 和 schema。
Footer 中存放 Blocklet offset、索引、统计信息。统计信息包括 blocklet的 min 和 max, page 的 min 和 max。索引存放的是 blocklet 的 startkey 和 endkey。
下图更为详细:
 
2.2. MDK索引原理
 
CarbonData 索引叫做 MDK 索引,即 Multi Dimension Key。如上图所示,year,Quarter,month,territory,country 这五个是 dimension,quantity 和 sales 是度量。维度进行字典编码,并对进行排序。然后存放到 blocklet 中。
存放于 blocklet 时,会同时把刚才提到的 startkey 和 endkey 存放好。如下图所示:
 
 
2.3. 索引查找过程
CarbonData 有两级索引。第一级索引是 block index ,存放于 spark driver 中。是一个 global B+ 树。使用这个索引避免扫描不必要的文件,可以减少95%的扫描量。
第二级索引是 blocklet 索引,用于过滤掉不必要的 blocklet。
一个完整的过滤如下图所示:
 
以我们的测试结果为例,我们的 action 表是18.55亿条记录,我们的 profile 表是415万条记录。做一个复杂的查询,做3个join和3个 group by。CarbonData 需要扫描的数据量仅为53.1 MB,而 parquet 需要扫描的数据量则为 5.5G。而且 action 表数据量翻了3倍,CarbonData 需要扫描的数据量仍然为 53M。所以说,数据量越大,CarbonData 相比 parquet 的性能优越性越大。
 
CarbonData:
Parquet:
2.4. CarbonData其他优化
CarbonData 还有些其他优化,这里只简单列举。延迟解码、向量化处理、预聚合表、partition 表(比 hive/spark 中的 partition 功能要强大很多,可以理解为索引,这里不详细讲解)、compaction、bucket、segment(我理解 segment 对优化意义不大,partition 更强大)等等。
2.5. CarbonData中对我们有用的新功能
Streaming Ingestion
目前支持 spark structured streaming,可以支持流式处理完数据后流式写入到 CarbonData 表中,这个功能是对我们有用的,需要后续研究。
Update &delete
CarbonData 目前支持 update 和 dalete。对我们也是有意义的。经过测试,update 可以运行,但是结果不对。可能需要跟社区讨论。

三、我们的性能测试结果

环境:
用了3台 40C128G,磁盘的 iops 在2000多。
不过我没用全部,总共用了 91vcore 264 GB。
第一次性能测试:
Action 表6亿多,profile 表200多万。从 ES 中通过代码导入到 CarbonData 中。
测试例子:
按学历统计近半年事件“event7”的触发次数。
且触发此事件的访客的性别需要为男,最近所在城市为“北京”;
且触发此事件的访客最近一个月访问了“com.android.dazhihui.view.screen.NewInitScreen10”活动页面(至少有1次访问时长超过10s);
且触发此事件的访客最近一周触发了“event7”事件(至多触发100次 label 为“label8”)
该语句翻译为了3个 join 和3个 group by。
需要8s左右,scan 数据量为 53M。
第二次性能测试:
Action 表18.55亿,profile 表415万。从 ES 中通过代码导入到 CarbonData 中。
语句同测试一。
该语句翻译为了3个 join 和3个 group by。
还是需要8s左右,scan 数据量仍然为 53M。
第三次性能测试:
在第二次性能测试基础上,同时并发6个同样的查询。
每个查询在8s-14s之间,性能稳定。
相比 ES 的存储,CarbonData 只使用约8.X%的存储。

四、Streaming ingest

把es的数据导出为 parquet,然后使用 structured streaming 流式写入到 CarbonData 中。经过调试,最终能调试通过。使用1个 executor 2C6G 进行性能测试。1S能够写入10万条记录到 CarbonData中。性能还是不错的。
同时,CarbonData 也支持 spark streaming ingest。
五、Update
CarbonData 有 update 的能力。但是 CarbonData 的目标是 OLAP/small scan/full scan。不适合于做 OLTP。
所以 profile 功能不能直接部署于CarbonData.目前想到的办法是 profile 功能放到 kudu 中。然后从 kudu 中周期性加载到 CarbonData 中。这个功能后续还需要继续研究。

六、兼容性

CarbonData 是基于 spark。CarbonData 1.3 可以兼容 spark 2.1 和 spark 2.2。
只要大数据发行版支持 spark 2.1 和 spark 2.2,就可以兼容 CarbonData.
1)与 CDH 兼容性
CDH 版本和 spark 是松耦合的。CDH 出的 spark 2 parcel 包可以用于多个 CDH 版本。
同时,CDH 还可以支持 apache spark 作为他的 gateway。
所以 CDH 与 CarbonData 是兼容的。
2)与华为兼容性
华为 fusioninsight 本身就包含 CarbonData。
所以华为与 CarbonData 是兼容的。
3)与星环兼容性
星环中包括两个 spark。Inceptor 是他们的定制 spark。
Discover 是完全开源的 spark。
我们 的CarbonData 可以运行于 discover spark 之上。

七、后续工作

后续还要增加工作:
action 表记录数达到百亿级别,继续进行性能测试。
目前我觉得应该还有性能优化的空间。

发表评论

电子邮件地址不会被公开。 必填项已用*标注