连续两篇文章都聊了不同的存储格式,这篇我们继续深入来看看在存储格式的演变之上有什么新的"黑科技"。华为公司在2016年开源了类parquet的列存格式:CarbonData,并且贡献给了Apache社区。CarbonData仅仅用了不到一年的时间就成功毕业,成为了Apache社区的顶级项目,CarbonData是首个由华人公司主导的Apache顶级项目,(来源自eBay的Kylin算是首个由华人主导的顶级开源项目)笔者这里还是要向华为的小伙伴们致敬,能够完成这样一个从0到1的突破。
本篇笔者尝试从技术细节来梳理CarbonData与其“前辈”到底有何不同之处,我们在实际应用与设计存储格式时有什么可以借鉴汲取之处。

1.CarbonData

首先我们来看看CarbonData本身的定位,如下图所示:

  • 1、支持海量数据扫描并取其中几列;
  • 2、支持根据主键进行查找,并在秒级响应;
  • 3、支持在海量数据进行类似于OLAP的交互式查询,并且查询中涉及到许多过滤条件,这种类型的workload应该在几秒钟内响应;
  • 4、支持快速地抽取单独的记录,并且从该记录中获取到所有列信息;
  • 5、支持HDFS,无缝对接Hadoop生态圈,天生带有分布式基因。

对于OLAP查询来说,存在多种不同类型的查询,存储结构的不同会影响到不同查询的数据表现。所以CarbonData的定位是作为一种通用的查询存储数据,通过Spark SQL来解决海量查询的问题,并且能够与Hadoop生态圈进行无缝对接。CarbonData最初的应用是与Spark SQLSpark DataFrame深度结合,后续由携程团队将CarbonData引入了Presto,滴滴团队将CarbonData引入Hive

其实无论是多维的OLAP查询,还是完整的扫描查询,还是部分范围查询。CarbonData的前辈ORCFile与Parquet都可以同样完成任务,那么作为新人,CarbonData有什么过人之处呢?

快,更快

下图是华为提供进行实测的数据,在绝大多数的测试场景之中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的压缩程度,并且对数据导入的速率影响不大。

笔者建议:对于字典编码的使用,还是要根据具体也业务场景进行分析压测,给出较为合适的使用方式,盲目使用字典编码反而会对性能带来负优化。

2.小结

到此为止,笔者也大致聊完了对CarbonData存储结构的理解以及笔者在简单实践之中所引发的思考。 作为华人圈子之中首个由华人公司主导的Apache的顶级项目,笔者也会继续对CarbonData进行关注与学习,也希望将来华人程序员能够在开源圈之中继续扩大影响力。

大数据小视角3:CarbonData,来自华为的中国力量的更多相关文章

  1. 大数据小视角1:从行存储到RCFile

    前段时间一直在忙碌写毕设与项目的事情,很久没有写一些学习心得与工作记录了,开了一个新的坑,希望能继续坚持写作与记录分布式存储相关的知识.为什么叫小视角呢?因为属于随想型的内容,可能一个由小的视角来审视 ...

  2. 大数据小视角4:小议Lambda 与 Kappa 架构,不可变数据的计算探索

    这个系列文章之前因为私事荒废了很久,继续更新--之前与老大谈论架构时,老大和我聊了聊分布式数据处理之中的Lambda结构,之前在<Designing Data-Intensive Applica ...

  3. 大数据小视角2:ORCFile与Parquet,开源圈背后的生意

    上一篇文章聊了聊基于PAX的混合存储结构的RCFile,其实这里笔者还了解一些八卦,RCfile的主力团队都是来自中科院的童鞋在Facebook完成的,算是一个由华人主导的编码项目.但是RCfile仍 ...

  4. 大数据小视角5:探究SSD写放大的成因与解决思路

    笔者目前开发运维的存储系统的服务器都跑在SSD之上,目前单机服务器最大的SSD容量有4T之多.(公司好有钱,以前在实验室都只有机械硬盘用的~~)但SSD本身的特性与机械硬盘差距较大,虽然说在性能上有诸 ...

  5. 大数据小项目之电视收视率企业项目09--hive环境搭建

    Hive是一个数据仓库基础工具在Hadoop中用来处理结构化数据.它架构在Hadoop之上,总归为大数据,并使得查询和分析方便.并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务 ...

  6. 大数据小项目之电视收视率企业项目08--》MapReduce编写之Wordcount

    编程规范 (1)用户编写的程序分成三个部分:Mapper,Reducer,Driver(提交运行mr程序的客户端) (2)Mapper的输入数据是KV对的形式(KV的类型可自定义) (3)Mapper ...

  7. 《深度访谈:华为开源数据格式 CarbonData 项目,实现大数据即席查询秒级响应》

    深度访谈:华为开源数据格式 CarbonData 项目,实现大数据即席查询秒级响应   Tina 阅读数:146012016 年 7 月 13 日 19:00   华为宣布开源了 CarbonData ...

  8. 华为云BigData Pro解读: 鲲鹏云容器助力大数据破茧成蝶

    华为云鲲鹏云容器 见证BigData Pro蝶变之旅大数据之路顺应人类科技的进步而诞生,一直顺风顺水,不到20年时间,已渗透到社会生产和人们生活的方方面面,.然而,伴随着信息量的指数级增长,大数据也开 ...

  9. Storm 实战:构建大数据实时计算

    Storm 实战:构建大数据实时计算(阿里巴巴集团技术丛书,大数据丛书.大型互联网公司大数据实时处理干货分享!来自淘宝一线技术团队的丰富实践,快速掌握Storm技术精髓!) 阿里巴巴集团数据平台事业部 ...

随机推荐

  1. linux搭建FTP服务器并整合Nginx

    操作系统:Centos7 1.1.服务器配置 # 关闭SELINUX,把SELINUX=enforcing改为SELINUX=disabled,reboot重启服务器生效 vim /etc/sysco ...

  2. linux下python3调用c代码或者python3调用c++代码

    前几篇的blog都是为了这个实验做基础,先说 原因是python调用数据库150w条数据22s,然后处理数据,其实就2个简单的for循环,65s 需求: 1. python调用c++函数 2. c++ ...

  3. 单行显示三级分销记录(同表自join)

    1)首先是一个简单的三级分销(邀请与被邀请),表结构是酱紫的 CREATE TABLE `d_user_invite` ( `invite_id` ) NOT NULL AUTO_INCREMENT, ...

  4. 如何在spring-boot web项目中启用swagger

    swagger的三个项目及其作用 我们打开swagger的官网,会发现有三个swagger相关的项目,它们分别是 swagger-editor 作用是通过写代码,生成文档描述(一个json文件或其他格 ...

  5. passwd命令

    passwd命令用于设置用户的认证信息,包括用户密码.密码过期时间等.系统管理者则能用它管理系统用户的密码.只有管理者可以指定用户名称,一般用户只能变更自己的密码. 语法 passwd(选项)(参数) ...

  6. linux的基本操作(LNMP的基本操作)

    LNMP 的环境搭建 和LAMP不同的是LNMP中的N指的是是Nginx(类似于Apache的一种web服务软件)其他都一样.目前这种环境应用的也是非常之多.Nginx设计的初衷是提供一种快速高效多并 ...

  7. Numpy学习

    决定陆陆续续写一些Numpy的例子.. 1. 如果想表示e的x次,就可以这样用,下面直接写一个sigmod函数: def sigmoid(z): return 1 / (1 + np.exp(-z)) ...

  8. js运用4

    ---恢复内容开始--- 1.函数    关键字function 复习 var  是js的关键字,用于声明变量,声明在内存模块完成,定义(=)是在执行模块完成. var可以在内存模块提前(js代码执行 ...

  9. Exception occurred during processing request: id to load is required for loading

    ERROR Dispatcher:38 - Exception occurred during processing request: id to load is required for loadi ...

  10. 用户场景分析i

    名字 学生(注重饮食选择,挑剔) 年龄 20 收入 无 知识层面 大学 使用这个网站的典型场景 中午或者晚上饿了但是不知道想吃什么,又不想随便吃,还是比较挑剔..这时,他就需要通过我们的网站来看其他人 ...