Druid评测
Druid 评测最近组里申请了三台机器对Druid进行测试,这里记录一下过程,并对Druid的表现做一下评测环境三台机器- 磁盘:SATA盘 4T- CPU:24核- 内存:128G- 系统:Red Hat Enterprise Linux 7.3- Zookeeper、HDFS、MySQL都用的已有的环境三台机器名称用 t214、t218、t219代替.
Druid 评测
最近组里申请了三台机器对Druid进行测试,这里记录一下过程,并对Druid的表现做一下评测
环境
一共三台机器
- 磁盘:SATA盘 4T
- CPU:24核
- 内存:128G
- 系统:
Red Hat Enterprise Linux 7.3
- Zookeeper、HDFS、MySQL都用的已有的环境
三台机器名称用 t214、t218、t219代替.其中:
- t214部署
coordinator
、overlord
、broker
、middle manager
- t214、t218、t219均部署
historical
安装
安装的时候先尝试了imply-2.2.0,但由于java兼容性问题没有成功,最终部署了druid-0.9.2。下面分别记录,对此部分不感兴趣可以直接跳过
imply-2.2.0 (失败)
由于Druid目前版本还在0.x.x,还处于成长阶段,因此原则上以部署最新版为宜。因此首先尝试部署了imply-2.2.0(*注:刚尝试完没两天imply就发布了2.2.2版本)
部署流程
因为最终没有部署imply-2.2.0
,所以这里就不把部署流程记录的那么详细了。只说遇到的坑吧。
imply-2.2.0
集成了druid-0.10.0
,但是druid-0.10.0
是依赖于Java8的。Java8的本地依赖好解决,但是在做hadoop-indexing的时候,需要将Druid的jar包发布到HDFS集群中作为任务jar运行,这个时候就会出现HADOOP集群的JAVA是1.7,但运行的任务jar是1.8的情况
尝试了重新编译druid-0.10.0
的部分组件至java7版本,但是失败了:
- 首先修改了Druid源码,将java8特性的部分修改为java7风格,这部分好解决
- 但是druid依赖的jetty版本也是用java8编译的,尝试对jetty进行降级,但是druid也使用了jetty的一些新版特性,降级后出现了method not found的问题。再改下去牵扯范围有点广,因此放弃
druid-0.9.2
目前Druid次新的版本0.9.2是依赖于java7的,因此最终部署了0.9.2版本。druid-0.10.0
的部分新特性见附录
部署流程
此部分建议和后面遇到的坑
部分一起看
- 下载并解压安装包
- 修改zookeeper的地址
conf/druid/_common/common.runtime.properties
druid.zk.service.host
- 修改MetaStorage为MySQL
conf/druid/_common/common.runtime.properties
- 注释掉
#For Derby
下面的配置 - 取消注释
#For Mysql
下面的几个配置, 并填写如正确的值 druid.extensions.loadList
增加一项"mysql-metadata-storage"
- 注释掉
- 修改DeepStorage为HDFS
- 将Hadoop的一堆xml配置文件复制到
conf/druid/_common
中 - 修改
conf/druid/_common/common.runtime.properties
druid.extensions.loadList
增加一项"druid-hdfs-storage"
- 注释掉
# For local disk
下面的配置 - 取消注释
# For HDFS:
下面的配置,并填写正确的值
- 将Hadoop的一堆xml配置文件复制到
- (可选) 修改时区。需要修改的包括
/conf/druid
下面所有的模块,以及conf/druid/middleManager/runtime.properties
的-Duser.timezone=PRC
。修改这些其实并没有什么实际的有意义,还可能会导致一些奇怪的bug。修改后查询返回的时区依然是UTC。只是segment路径、名称等东西,druid会用本地时区,类似于2017-05-20T00:00:00+0800
这种形式,做idnexing的时候,也依然需要按照这种格式来指定时间段 - 打包、分发到各机器,可以用
scp
、rsync
等工具 - 启动各组件
- 执行
bin/xxx.sh start
来启动,bin/xxx.sh stop
来停止
- 执行
遇到的坑
- 用MySQL做MetaStorage的话,需要注意:
- 需要在
conf/druid/_common/common.runtime.properties
中配置druid.extensions.loadList
,增加"mysql-metadata-storage"
- MySQL所用的database的Character需要配置为
UTF-8
- 需要在
- 启动broker失败
- broker提示direct memory不足
- 修改
conf/druid/broker/jvm.config
,增大-XX:MaxDirectMemorySize
- 修改
- broker提示direct memory不足
- 启动historical失败
- historical提示direct memory不足
- 修改
conf/druid/historical/jvm.config
,增大XX:MaxDirectMemorySize
- 修改
- historical提示direct memory不足
- 做
hadoop-indexing
的时候mapreduce任务运行失败
- 原因1:集群hadoop版本为2.4.1,与druid提供的版本2.3.0部分jar包不兼容
- 替换
hdfs-extension
:从github
上clone了druid的源码,迁出druid-0.9.2
,修改hadoop的依赖版本为2.4.1,重新编译并替换掉extension/druid-hdfs-storage
文件夹 - 修改
hadoop-dependency
的依赖
- 新建了
hadoop-dependency/client/2.4.1
的空文件夹,因为hadoop集群默认是有hadoo的jar包的,不用重复添加 - 修改
conf/druid/middleManager/runtime.properties
中的druid.indexer.task.defaultHadoopCoordinates
属性为["org.apache.hadoop:hadoop-client:2.4.1"]
- 新建了
- 替换
- 原因2: 数据文件采用lzo压缩,但hadoop默认没有提供lzo的依赖
- 将lzo包复制到
hadoop-dependency/client/2.4.1
中
- 将lzo包复制到
- 原因3: druid的依赖包与hadoop集群的jar包版本冲突 (*注:这里有个大坑)
- 官网介绍了两种on other hadoop version的方法:
- 设置
mapreduce.job.classloader = true
- 设置
mapreduce.job.user.classpath.first = true
- 设置
- 首先尝试了方法1,也是官网推荐的方法。
hadoop-indexing
需要执行两个连续的MR任务,修改后第一个MR任务成功,第二个任务总是报java.lang.ClassNotFoundException: Class io.druid.indexer.IndexGeneratorJob$IndexGeneratorOutputFormat not found
错误。采用包括修改源码加log等各种方法调试无果,发现依赖包确实被加载到classpath中了,但就是无法识别。真的是巨坑无比 - 最终采用了方法2,很容易就过了
- 官网介绍了两种on other hadoop version的方法:
- 原因4: MR任务内存溢出
- 尝试任务配置项的
jobProperties
中,调整如下配置
mapreduce.map.java.opts
mapreduce.reduce.java.opts
mapreduce.reduce.memory.mb
- 尝试调整
tuningConfig
的partitionsSpec
的targetPartitionSize
- 尝试调整
tunningConfig
的maxRowsInMemory
配置项
- 尝试任务配置项的
- 原因5: 文件数据错误
tuningConfig
的ignoreInvalidRows
设置为true
- 控制好ETL流程,扔掉错误行
- 原因6: Hadoop的一些其他配置问题
- 在任务配置中增加了配置项
mapreduce.job.queuename
- kerberos等问题,具体配置
- 在任务配置中增加了配置项
- 原因7:
hadoop-indexing
运行完第一个MR任务之前或之后之提示找不到数据
- 因为Druid用的是UTC时间,所以在任务配置中的
intervals
需要设置为类似"2017-05-20T00:00:00+0800/2017-05-22T00:00:00+0800"
这样的形式,即后面加上+0800
,否则会按照UTC时间处理
- 因为Druid用的是UTC时间,所以在任务配置中的
- 原因1:集群hadoop版本为2.4.1,与druid提供的版本2.3.0部分jar包不兼容
数据导入(hadoop-indexing)
部署好了之后,导入数据做了些测试。具体的Schema、过程等就不细说了,参考官方文档没什么大坑。这里只对Druid的表现做一下评测
所用数据
使用了某段时间的某数据,出于保密考虑略去。原始数据共104个字段,其中维度字段按照基数不同,划分为5类:
t1
基数在70万左右,共2个t2
基数在2万~4万左右,共5个t3
基数在1千~1万之间,共5个t4
基数在1百~1千之间,共20个t5
基数在1百以内,共59个
根据数据的情况,考虑了如下3中导入方式:
- 方案1: 不做
roll up
,导入所有列,跳过错误行 - 方案2: 做
roll up
,导入所有列,跳过错误行 - 方案3: 做
roll up
,去掉两个基数过大的列,跳过错误行
导入后数据情况如下:
数据情况 | 大小 | 条目数 |
---|---|---|
原始未导入 | 184.2 GB | 2.8 亿 |
方案1导入 | 23.5 GB | 2.7亿 |
方案2导入 | 11.1 GB | 2.5亿 |
方案3导入 | 8.8 GB | 2.1亿 |
根据数据情况,安排了若干种查询来测试Druid的性能,单位是秒。以下测试全部通过Json Over Http
查询方式完成:
查询 | 方案1 | 方案2 | 方案3 |
---|---|---|---|
TimeSeries count(*) | 0.464s | 0.741s | 0.347s |
TimeSeries sum(count) | 0.546s | 0.457s | 0.411s |
GroupBy t1 sum(count) limit 10 | 35.841s | 28.459s | |
GroupBy t2 sum(count) limit 10 | 4.512s | 3.686s | 3.574s |
GroupBy t3 sum(count) limit 10 | 4.162s | 4.464s | 3.334s |
GroupBy t4 sum(count) limit 10 | 3.935s | 3.470s | 3.134s |
GroupBy t5 sum(count) limit 10 | 4.044s | 3.195s | 2.734s |
GroupBy t1 sum(count) limit 10 with filter 1.8亿 | 36.475s | 28.431s | |
GroupBy t2 sum(count) limit 10 with filter 1.8亿 | 2.542s | 2.077s | 1.434s |
GroupBy t3 sum(count) limit 10 with filter 1.8亿 | 1.372s | 1.423s | 0.989s |
GroupBy t4 sum(count) limit 10 with filter 1.8亿 | 1.513s | 1.411s | 1.199s |
GroupBy t5 sum(count) limit 10 with filter 1.1亿 | 2.612s | 2.389s | 2.026s |
TopN t1 sum(count) limit 10 | 1.477s | 1.289s | |
TopN t2 sum(count) limit 10 | 1.129s | 1.286s | 0.855s |
TopN t3 sum(count) limit 10 | 0.955s | 0.965s | 0.601s |
TopN t4 sum(count) limit 10 | 1.364s | 0.922s | 0.727s |
TopN t5 sum(count) limit 10 | 1.079s | 0.926s | 0.717s |
结果分析:
基本与根据Druid的设计思路推测出来的适用场景相符:
roll up
- 对Druid的存储空间影响非常明显。在维度基数不是特别大的情况下,做
roll up
节省了50%以上的存储空间 - 对Druid的查询性能有一定影响,但不像存储空间那么明显
- 对Druid的存储空间影响非常明显。在维度基数不是特别大的情况下,做
- 维度基数
- Druid的存储空间受维度基数的最大值影响明显,本例中去掉2个基数较大的字段,存储空间降低为原来的80%以下
- 对查询性能影响非常明显,分为两点:
- 对基数较大的维度进行汇总,响应时间很长
- 对其他维度进行汇总,没有较大维度基数的表查询响应时间明显缩短
- TimeSeries和TopN相对Group做的优化非常明显,在能使用这两种查询的前提下,应当尽量使用这两种查询
Apache Calcite
目前还不能有效的将group by ... order by ... limit ...
这种查询有效的转换为TopN
查询,因此性能方面会有一定影响- 目前使用的是
SATA
磁盘,SSD
磁盘的性能提升待测
附录
druid-0.10.0部分新特性
- 支持numeric dimension,之前的版本要求dimension必须是字符串类型
- 支持内置SQL,虽然依然是
Experimental
,提供了Json over http
以及Apache Calcite Avatica
两种接入方式
更多推荐
所有评论(0)