连续两篇文章都聊了不一样的存储格式,这篇咱们继续深刻来看看在存储格式的演变之上有什么新的"黑科技"。华为公司在2016年开源了类parquet的列存格式:CarbonData,而且贡献给了Apache社区。CarbonData仅仅用了不到一年的时间就成功毕业,成为了Apache社区的顶级项目,CarbonData是首个由华人公司主导的Apache顶级项目,(来源自eBay的Kylin算是首个由华人主导的顶级开源项目)笔者这里仍是要向华为的小伙伴们致敬,可以完成这样一个从0到1的突破。
本篇笔者尝试从技术细节来梳理CarbonData与其“前辈”到底有何不一样之处,咱们在实际应用与设计存储格式时有什么能够借鉴汲取之处。程序员
首先咱们来看看CarbonData自己的定位,以下图所示:
性能优化
对于OLAP查询来讲,存在多种不一样类型的查询,存储结构的不一样会影响到不一样查询的数据表现。因此CarbonData的定位是做为一种通用的查询存储数据,经过Spark SQL来解决海量查询的问题,而且可以与Hadoop生态圈进行无缝对接。CarbonData最初的应用是与Spark SQL和Spark DataFrame深度结合,后续由携程团队将CarbonData引入了Presto,滴滴团队将CarbonData引入Hive。分布式
其实不管是多维的OLAP查询,仍是完整的扫描查询,仍是部分范围查询。CarbonData的前辈ORCFile与Parquet均可以一样完成任务,那么做为新人,CarbonData有什么过人之处呢?oop
下图是华为提供进行实测的数据,在绝大多数的测试场景之中CarbonData的性能都略优于Parquet。
性能
固然快速的查询是须要付出代价的,查询的快速所牺牲的是压缩率的减少与入库时间的延长。学习
那咱们接下来就是要详尽讨论CarbonData的性能表现与底层设计之间的逻辑关系。测试
下图展现了CarbonData的数据存储格式:
优化
File Header
文件头的格式比较简单,保存了存储格式的版本和模式信息。(这部分一般是稳定不可变的内容)编码
Blocklet
单Blocklet最大的容量阀值为64M,也就是说单个HDFS的Block能够容纳多个Blocklet(视Block的大小而定)。这块内容与ORCFile与Parquet的设计一脉相承,都是利用Pax的存储模型来优化数据查询时的性能表现。设计
File Footer
在文件尾部保存了存储数据的索引和摘要,索引是CarbonData最为核心的关键实现,正是因为索引的存在,大大提升了CarbonData在不一样查询场景之下的性能表现。
CarbonData经过支持了二级索引,大大的提升了CarbonData数据查询的性能表现。
由上图所示CarbonData在HDFS Block级别与内部的Blocklet级别都分别创建起索引,这样能够大大减小非必要的任务启动与非必要的磁盘IO操做。众所周知,引入索引的的确确可以加快数据的查询速率,可是天下没有免费的午饭。我想CarbonData压缩率缩减与数据导入时间的延长的缘由,想必读者心中也有了答案。
咱们能够看到在CarbonData的文件尾部,经过B+树的方式来实现索引。因为HDFS追加写的特性,因此我想读者应该也能明白为什么这些索引数据与统计数据须要存放在CarbonData的末尾。
上图完整的展示了一次过滤查询的流程,这个过程在二级索引的做用之下,规避了大量非必要的查询交互,由此带来的性能优化是十分明显的。
相对于ORCFile与Parquet相对简要的摘要索引,CarbonData在索引层面颇费心思。经过这样的方式来超越前辈,固然这样的选择设计一样也要付出额外的代价。
这是CarbonData之中颇具争议的功能,在CarbonData以前的版本是默认添加的内容,目前在1.3版本之中是做为可选项加入其中的。(笔者在华为高斯部门工做的师兄也曾经和笔者吐槽过在生产环境之中,全局字典编码的彷佛还存在一些'坑')因此看起来可以运用好字典编码的确是个值得探讨的问题,笔者在此也简单聊一聊:
如上图所示,全局字典编码的方式很简单,就是经过数字和字典来替换表格之中重复出现的数据。 这样的好处很明显:
大大减小了表格数据所须要存储的数据量
某些须要进行group by的字段进行全局字典编码,能够大量减小计算时的shuffle的数据量。以达到性能提高的目的。
可是在将数据导入CarbonData的过程之中,对与重复率较低的列,一旦创建起全局字典,显然会大大拖慢数据的导入速度,而且影响数据的压缩程度。而若是对于数据重复率较高的数据,例如性别,年龄等高重复数据,经过创建全局字典可以大大提高CarbonData的压缩程度,而且对数据导入的速率影响不大。
笔者建议:对于字典编码的使用,仍是要根据具体也业务场景进行分析压测,给出较为合适的使用方式,盲目使用字典编码反而会对性能带来负优化。
到此为止,笔者也大体聊完了对CarbonData存储结构的理解以及笔者在简单实践之中所引起的思考。 做为华人圈子之中首个由华人公司主导的Apache的顶级项目,笔者也会继续对CarbonData进行关注与学习,也但愿未来华人程序员可以在开源圈之中继续扩大影响力。