个人介绍
2021开源之夏的小伙伴们大家好啊,我是来自广州的小伙伴陈政羽,所学方向主要是大数据计算 和 Java,目前是作为Flink中文社区志愿者的一员,协助社区整理大数据实时计算引擎相关知识点和文章。欢迎各位多多与我交流大数据技术(文章末尾有我的个人联系方式)
有幸在开源之夏选上课题基于CarbonData 之 Presto 优化课题,这个课题主要是针对Presto使用CarbonData查询上做更多的一些优化。这个课题对于我来说十分有挑战点,涉及大数据领域的组件十分多,首先CarbonData作为大数据的一种文件存储格式,在OLAP计算引擎上的查询加速实现有助于数据更快的查询和产出;其次大数据涉及的组件和版本比较广泛,在测试、兼容各种方面带来的挑战会很多,例如Hadoop、Spark、Presto(Trino)、Hive等多个开源大数据组件的协同运行和调试,给项目的协同运行带来十分多挑战,如何把这些组件兼容完美的运行在CarbonData上面也是我的其中挑战点之一;最后开发我们是以课题性能优化为目标,提升用户的查询速度为主要目的去实现相关代码。明确了开发目标后,我们开始动手,首先我们先从了解这2个主要组件开始入手。
CarbonData 是什么?能干嘛?
CarbonData是一种新型的Apache Hadoop本地文件格式,使用先进的列式存储、索引、压缩和编码技术,以提高计算效率,有助于加速超过PB数量级的数据查询,可用于更快的交互查询。同时,CarbonData也是一种将数据源与Spark集成的高性能分析引擎。CarbonData作为Spark内部数据源运行,不需要额外启动集群节点中的其他进程,CarbonData Engine在Spark Executor进程之中运行,运行架构如下
CarbonData特性
- SQL功能:CarbonData与Spark SQL完全兼容,支持所有可以直接在Spark SQL上运行的SQL查询操作。
- 简单的Table数据集定义:CarbonData支持易于使用的DDL(数据定义语言)语句来定义和创建数据集。CarbonData DDL十分灵活、易于使用,并且足够强大,可以定义复杂类型的Table。
- 便捷的数据管理:CarbonData为数据加载和维护提供多种数据管理功能。CarbonData支持加载历史数据以及增量加载新数据。加载的数据可以基于加载时间进行删除,也可以撤销特定的数据加载操作。
- CarbonData文件格式是HDFS中的列式存储格式。该格式具有许多新型列存储文件的特性,例如,分割表和数据压缩。CarbonData具有以下独有的特点:
- 伴随索引的数据存储:由于在查询中设置了过滤器,可以显著加快查询性能,减少I/O扫描次数和CPU资源占用。CarbonData索引由多个级别的索引组成,处理框架可以利用这个索引来减少需要安排和处理的任务,也可以通过在任务扫描中以更精细的单元(称为blocklet)进行skip扫描来代替对整个文件的扫描。
- 可选择的数据编码:通过支持高效的数据压缩,可基于压缩/编码数据进行查询,在将结果返回给用户之前,才将编码转化为实际数据,这被称为“延迟物化”。
- 支持一种数据格式应用于多种用例场景:例如,交互式OLAP-style查询,顺序访问(big scan),随机访问(narrow scan)
CarbonData关键技术和优势
- 快速查询响应:高性能查询是CarbonData关键技术的优势之一。CarbonData查询速度大约是Spark SQL查询的10倍。CarbonData使用的专用数据格式围绕高性能查询进行设计,其中包括多种索引技术和多次的Push down优化,从而对TB级数据查询进行最快响应。
- 高效率数据压缩:CarbonData使用轻量级压缩和重量级压缩的组合压缩算法压缩数据,可以减少60%~80%数据存储空间,很大程度上节省硬件存储成本。
从以上上述描述可以发现,CarbonData作为大数据的一种文件格式,通过一些压缩算法和快速查询索引技术提升查询速度和加速Spark查询,在交互式查询上面具有十分大的优势,下面我自己也做了个表格,通过简单对比目前开源社区上面已有的文件格式(ORC和Parquet)进行对比这3者的一些功能异同点
Presto(Trino)是什么?
Presto是什么是Facebook开源的,完全基于内存的并⾏计算,分布式SQL交互式查询引擎.是一种Massively parallel processing (MPP)架构,多个节点管道式执⾏,⽀持任意数据源(通过扩展式Connector组件),数据规模GB~PB级使用的技术,如向量计算,动态编译执⾏计划,优化的ORC和Parquet Reader等 ,它的查询架构如下:
Presto查询引擎是一个Master-Slave的架构,由下面三部分组成:
- 一个Coordinator节点
- 一个Discovery Server节点
- 多个Worker节点
Coordinator: 负责解析SQL语句,生成执行计划,分发执行任务给Worker节点执行
Discovery Server: 通常内嵌于Coordinator节点中
Worker节点: 负责实际执行查询任务,负责与HDFS交互读取数据
Worker节点启动后向Discovery Server服务注册,Coordinator从Discovery Server获得可以正常工作的Worker节点。如果配置了Hive Connector,需要配置一个Hive MetaStore服务为Presto提供Hive元信息
一些数据模型划分的基本概念如下:
与hive的对比:
hive是一个数据仓库,是一个交互式比较弱一点的查询引擎,交互式没有presto那么强,而且只能访问hdfs的数据
presto是一个交互式查询引擎,可以在很短的时间内返回查询结果,秒级,分钟级,能访问很多数据源
与Spark对比的优缺点如下:
通过以上对比可以看出Presto擅长的领域主要在OLAP查询以及多数据的联邦查询上,可以进行跨库跨数据源查询
适合:PB级海量数据复杂分析,交互式SQL查询,⽀持跨数据源查询
不适合:多个大表的join操作,因为presto是基于内存的,多张大表在内存里可能放不下
社区Presto®商标之争
2019年中,由于Presto社区给FaceBook抢占了商标,导致了PrestoSQL社区不得不更换名字为Trino并且基于原有的PrestoSQL继续发展社区。这个仅仅是更改名字,之前的社区和软件都还在那的,这个项目还是由 原创始人和创造者以及主要贡献者支持。Presto 的新 GitHub 地址为 https://github.com/trinodb/trino
关于为什么取名为 Trino,Presto 创始人 Martin 解释到:
It was inspired from neutrinos (subatomic particles), which are light and travel very fast. And then we made the name smaller by shortening it to trino.
也就是 Trino 的灵感来自中微子,中微子是一种光速很快的粒子,然后大佬们把这个名字缩短为 trino
详细可以查看下面链接的相关情况描述:
https://trino.io/blog/2020/12/27/announcing-trino.html
开发所需环境搭建
我们按照官方文档QUICK START说明,我们可以看到 如果想运行Presto + CarbonData ,我们首先要使用Spark 生成CarbonData文件,并且使用Presto依赖Hive的元数据进行查询对应生成的数据。整体流程是比较复杂的。所以我们首先本地需要先有Hadoop、Hive、Spark环境,以上这些软件还依赖Java和Scala环境。需要完成上面这些环境才能再去运行Presto查询CarbonData数据。
搭建Hadoop环境因为我是本地开发,所以我以伪分布式的模式去运行Hadoop,我这边选择使用的JDK版本是1.8,选择Hadoop版本是2.7.7。这个版本选择会影响后续使用Maven编译CarbonData,因为我们编译时候是需要指定编译的对应Hadoop版本的,我们尽量选择与其兼容版本。我们可以查看POM文件查看默认的版本
看以看到我红线框框的,我就基本上开始基于这些相近的版本进行开发。最终我选择的版本如下:
开发环境:Mac BigSur 11.5
JDK:1.8 和 11
Maven:3.8.1
Scala:2.11.8 和 2.12.11
Hadoop:2.7.7
Hive:3.1.0
Presto:316
Spark:2.4.5
基于这些版本的编译命令,参考官网README文档 https://github.com/apache/carbondata/blob/master/docs/quick-start-guide.md
之后进行修改后如下:
mvn -DskipTests -Pspark-2.4 -Pprestosql -Dspark.version=2.4.5 -Dhadoop.version=3.1.1 -Dhive.version=3.1.0 clean package
通过这条命令成功编译,当然中间经历了许多坎坷过程,首先在编译时候发生以下错误:
Could not resolve dependencies for project org.example:myhiveself:jar:1.0-SNAPSHOT: Failure to find org.pentaho:pentaho-aggdesigner-algorithm:jar:5.1.5-jhyd
e in http://maven.aliyun.com/nexus/content/groups/public was cached in the local repository,
经过排查是缺少中央库,默认中央库没有此依赖。需要添加中央库地址,于是在Maven的conf目录Setting.xml添加以下中央库地址,解决
<mirror>
<id>aliyun-maven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<!-- <url>https://maven.aliyun.com/repository/public</url> -->
<url>https://repo1.maven.org/maven2</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</mirror>
<mirror>
<id>aliyun-maven-spring</id>
<mirrorOf>*</mirrorOf>
<name>spring-plugin</name>
<url>https://maven.aliyun.com/repository/spring-plugin</url>
</mirror>
<mirror>
<id>repo2</id>
<name>Mirror from Maven Repo2</name>
<url>https://repo.spring.io/plugins-release/</url>
<mirrorOf>central</mirrorOf>
</mirror>
然后Carbondata文档依赖Apache Thirft 0.93版本,我们需要提早在机器安装好相关依赖,这一步也是比较繁琐的一个步骤
至此我们看到Maven-Build Sucessful提示后就证明我们的编译步骤已经顺利完成了
Spark使用CarbonData
编译成功后,我们按照官网文档去对应的路径复制对应的JAR包到Spark安装目录下,并且创建carbon.properties文件,并且在Spark安装目录下配置对应的Spark配置和复制Hive相关配置
spark-env.sh
export SPARK_MASTER_IP=localhost
export SPARK_WORKER_MEMORY=1GB
export master=spark://chenzhengyudeMacBook-Pro.local:7070
export SPARK_CLASSPATH=$SPARK_HOME/carbonlib/*
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home
export HADOOP_HOME=/Users/chenzhengyu/software/hadoop-2.7.7
export HADOOP_CONF_DIR=/Users/chenzhengyu/software/hadoop-2.7.7/etc/hadoop
spark-default.conf
spark.master spark://chenzhengyudeMacBook-Pro.local:7077
spark.eventLog.enabled false
spark.driver.memory 512m
spark.driver.extraJavaOptions -Dcarbon.properties.filepath=$SPARK_HOME/conf/carbon.properties
spark.executor.extraJavaOptions -Dcarbon.properties.filepath=$SPARK_HOME/conf/carbon.properties
carbon.properties
#################### Performance Configuration ##################
######## DataLoading Configuration ########
#File read buffer size used during sorting(in MB) :MIN=1:MAX=100
carbon.sort.file.buffer.size=10
#Number of cores to be used while data loading
carbon.number.of.cores.while.loading=2
#Record count to sort and write to temp intermediate files
carbon.sort.size=100000
#enable prefetch of data during merge sort while reading data from sort temp files in data loading
#carbon.merge.sort.prefetch=true
######## Alter Partition Configuration ########
#Number of cores to be used while alter partition
carbon.number.of.cores.while.alterPartition=2
######## Compaction Configuration ########
#Number of cores to be used while compacting
carbon.number.of.cores.while.compacting=2
#For minor compaction, Number of segments to be merged in stage 1, number of compacted segments to be merged in stage 2.
carbon.compaction.level.threshold=4,3
#default size (in MB) for major compaction to be triggered
carbon.major.compaction.size=1024
完成之后,电脑需要启动以下组件:
- 在Hadoop目录下启动./sbin/start-all.sh
- 在Hive目录下启动 Metastore服务
- 在Hive目录下启动 HiveServer2服务
- 在Spark目录下启动 ./sbin/start-all.sh 启动standalone
上面的组件我们都开启后,如下图
然后我们启动Spark-SQL-Cli查询时候
./bin/spark-sql --conf spark.sql.extensions=org.apache.spark.sql.CarbonExtensions
观察到HiveMeta服务日志输出Error,而且Spark控制台也输出了以下错误信息:
NoClassDefFoundError org/json4s/jackson/JsonMethods$
很明显这个是包缺乏的信息,根据思路,我们需要依赖Hive元数据进行查询,且观察Spark目录下已经有jackjson相关依赖,很明显就是Hive和Hadoop环境缺乏相关依赖。于是把相关jackjson依赖copy到hive的lib目录下面
然后重启所有组件,再次尝试查询,问题得以解决!!我们再次执行查询可以看到数据已经出来了
可以看到数据准确查询出来
创建表也没问题了~
Hive使用CarbonData
但是我们创建的数据只是在Spark-SQL/Spark-Shell上成功建表,如果我们需要使用Hive生成CarbonData表还需要以下步骤
https://github.com/apache/carbondata/blob/master/docs/hive-guide.md
根据步骤我这边大概总结了一下步骤流程:因为使用Hive创建Carbondata表需要借助一些Spark-Api,故需要复制scala、Spark-catalyst*.jar 等相关依赖,并且把一个snappy文件复制到java安装目录下,以及将所有carbon开头的依赖复制到hive/lib和yarn/lib目录下,这样在提交yarn任务执行时候能够找到对应依赖。按照步骤操作后,最终在Hive上成功操作CarbonData表,结果如下:
运行建表语句查看表类型,我们可以看到是CarbonData表,然后对应创建的Spark版本号,路径等信息一一列举了出来
Presto使用CarbonData
到了上面,我们距离胜利已经很近了。我们这时候前往Presto社区按照文档下载对应的316版本和对应客户端进行操作
https://github.com/apache/carbondata/blob/master/docs/prestosql-guide.md
把这个编译好之后的目录Jar包重命名后复制到Presto-316 的 Plugin 文件夹下面,Presto后面会借助Java SPI机制加载这个插件
于此同时我们配置好Presto 单节点的一些相关配置
carbondata.properties
connector.name=carbondata
hive.metastore.uri=thrift://localhost:9083
hive.config.resources=/Users/chenzhengyu/software/hadoop-2.7.7/etc/hadoop/core-site.xml,/Users/chenzhengyu/software/hadoop-2.7.7/etc/hadoop/hdfs-site.xml
这个配置了元数据的通信地址,hive、hadoop文件的一些基本配置即可 然后我们使用命令启动Presto服务端
./bin/launcher run
看到如下图字样证明已经启动成功了
然后我们使用客户端Jar启动进行查询
java -jar presto.jar --server localhost:8086 --catalog carbondata
查询结果如下:
可以看到我们Presto已经成功查询了,并且能够正确的连接到Hive元数据
总结
看到上面步骤对于我来说大概花费了10天左右,期间还有各种奇奇怪怪的错误没有一一列举出来,例如编译时候版本冲突解决;不兼容Hadoop3.x、Hive2.3.x等问题,这些问题都是要自己逐步去探索和尝试的。上面的流程只是自己在遇到一些问题比较深刻的从而记录下来的一部分,从这次环境搭建的流程中大大的提升了自己的动手和解决问题能力。知道了如何借助开源工具去解决各种问题
于此同时经过和我的导师陈亮以及项目小伙伴、社区协商后认为开源社区最重要是开源,公开透明的,而不是被商业利益所捆绑。所以我们选择的是Trino社区路线,第一步是去替换陈旧的Presto316组件,替换为Trino358版本。CarbonData目前集成了Presto316,Presto316是比较旧的版本,在最新的358版本中,加入了许多优化,包括加入了动态过滤、Rubix数据缓存和一些性能改进,这也与我们初衷一致,第一步首先替换Presto(Trino)版本通过版本更新优化带来查询的性能提升,然后再实现一些版本里面的一些新特性去兼容CarbonData这个文件格式,提升查询速度。
欢迎各位持续关注CarbonData,在Apache Asia Cron大会上,Apache CarbonData将有2个议题参与会议,关于 星展银行[新加坡发展银行]的数据平台如何利用Apache CarbonData推动实时洞察和分析 和 通过使用Apache CarbonData的索引加快大数据分析的速度 的相关演讲,也欢迎大家积极报名观看线上演讲,让更多人了解 Apache CarbonData。
欢迎关注我的阿里云开发者社区和CSDN https://blog.csdn.net/qq_30438573, 大家多多交流技术