原本不知道啥时候才有时间写,没想到在等高铁的时候就顺带写了。这篇文章谈谈我对目前存储和计算该如何结合的一些看法。
交代下背景,之前花了半天时间试用了下,主要想解决ElasticSearch历史数据查询的问题,之前出现过在ES上查询一个月数据直接把一些节点跑挂了。然后我打算把历史数据单独出来,这个时候有三个选择:
- 将历史数据导入到Apache kylin,这是一个风头还不错的产品
- 使用Spark Parquet,我测了了下,几百万条数据使用Spark SQL 做个count,处理过一次后接着再查也就两三秒,性能还是不错的
- 华为新推出的 CarbonData,类似Parquet,是一种文件存储格式,但是数据结构更加丰富和复杂,支持列存,索引,向量化等。
Kylin是一个独立的,基于HBase的Ad-hoc查询引擎,可以应对海量数据并且拥有优秀的响应时间。不过我现在重心在Spark上,并不愿意引入一个新的独立的系统。
自然的,Parquet 可能是更好的选择,只是作为一种数据存储格式,显然更轻,我只要利用Spark 将ES数据导出并且存成parquet就可以进行查询了。
但是Parquet 应对查询显然还是不够理想,依然有点靠算力的。这个时候CarbonData 似乎更符合我的要求了:
- 轻量化,只是一个存储结构,而不是一个独立的拥有计算和存储,并且能够对外提供服务的引擎。当然,CarbonData似乎也提供了Thrift接口供外部调用。
- 可以和Spark 计算引擎更好的结合
- 因为基于HDFS,所以天然就是分布式的
或许是因为项目刚刚进入Apache 孵化器,有太多的工作要做,代码在不断更新导致文档略有些滞后,所以用起来并不是很顺,不过CarbonData团队很热情,我也能感受到开源文化带来的魅力。
当然,这篇文章并不是为了鼓吹CarbonData的,而是为了说明存储和计算的关系,以及未来的发展方向:
传统的系统,譬如NoSQL领域的MongoDB,数据库里的Oracle/Mysql,搜索的ES,他们都是计算绑定在存储上的。根据存储的结构已经确定了计算逻辑。而类似Parquet,CarbonData,则实现了存储和计算逻辑上的分离,理论上你可以使用任何计算引擎,譬如Spark或者MR。而且存储和计算可以物理接近,从而保证了性能。
我们先来简单以ES为例子,谈谈目前存储和计算绑定的一些系统的情况。
ES 用来做聚合运算的优势在于Lucene优秀的列式存储实现,也就是其DocValues,而且数据进入具有一定的实时性。这个是目前一些大数据组件所欠缺的。ES缺点也比较明显:
- Lucene天然就是单机的,ES需要花费大量精力完成存储的分布式
- ES 需要绑定Lucene,实现定制的查询(计算)
这两点其实哪点都不好做。而且自成体系的系统,很多东西都需要重新实现。
类似Parquet/CarbonData则不存在这类问题,他只要优化好存储结构就行了,然后暴露类似HDFS的基础API,真实的写入和查询都可以交给通用的计算引擎来完成。
而且他们无需担心分布式相关的问题,因为都是基于HDFS实现的,天然就是分布式。所以整件事情就变得简单了。当然这种较为通用的存储格式,有大量额外的结构化元信息存储,不过问题并不大,现在大量的存储本来也是被浪费掉的,大家细心点,就能腾出额外的空间给这些元信息存储。
Spark 计算引擎其实是一个标准的master-slave模式,当然专业的术语是 driver-executor,和CarbonData的交互模式是每个Executor 都会加载CarbonData的元数据,从而在查找和过滤的时候变得更快。
记得早先说过,Hadoop刚兴起的时候,大家就像一个穷人突然获得了一笔巨大的财富,突然拥有了这么大的存储和算力,大家就有点大手大脚了,所以早先直接就存成了普通文本了,后面有了SequenceFile好了点,再后面ORC/Parquet等则更好些,而到CarbonData则是更完美些了。显然,整个分布式存储文件格式是越来越面向查询了,因为已经过了仅仅是积攒数据的时代,我们现在要求更好的查询效率以及一定的实时性。所以这个时候大家开始在入库效率和查询效率得到一个更合理的平衡。
从这两年的各种Ad-Hoc查询引擎的风起云涌也可以看出,人们对于查询的要求越来越高。CarbonData的思路,我觉得是符合趋势的,所以非常看好。当然,也希望未来有更多类似的项目诞生。