通过前面的学习,我们已经对 Apache Druid 有了初步的认识,包括它的原理、架构以及数据结构和数据摄取。接下来就得讲讲咱们阿里云 E-MapReduce (EMR) ,作为构建在阿里云云服务器 ECS 上的开源 Hadoop、Spark、HBase、Hive、Flink 生态大数据 PaaS 产品,它集成的 Druid 有什么优势呢,我们一起来看看 ( •̀ ω •́ )✧。
本文整理自阿里云产品文档:https://help.aliyun.com/document_detail/72703.html?spm=a2c4g.11186623.6.779.2335145dtUf8dY
E-MapReduce构建于云服务器ECS上,基于开源的Apache Hadoop和Apache Spark,可以方便地使用Hadoop和Spark生态系统中的其他周边系统(例如,Apache Hive、Apache Pig和HBase等)来分析和处理自己的数据。不仅如此,E-MapReduce还可以与阿里云其他的云数据存储系统和数据库系统(例如,阿里云OSS和RDS等)进行数据传输。
从上图可以看出,E-MapReduce集群是基于Hadoop的生态环境搭建的,可以与阿里云的对象存储服务(OSS)进行无缝数据交换。此外,E-MapReduce集群也可以与云数据库(RDS)等云服务无缝对接,方便您将数据在多个系统之间进行共享和传输,以满足不同业务类型的访问需要。
E-MapReduce Druid 基于Apache Druid 做了大量的改进,包括与E-MapReduce和阿里云周边生态的集成、方便的监控与运维支持、易用的产品接口等等,真正做到了即买即用和 7*24 免运维。
E-MapReduce Druid 目前支持的特性如下所示:
从EMR-3.11.0
版本开始,E-MapReduce支持将E-MapReduce Druid
作为E-MapReduce的一个集群类型。
将E-MapReduce Druid作为一种单独的集群类型,而不再是在Hadoop集群中增加Druid组件,主要基于以下几方面的考虑:
在创建集群时选择Druid集群类型即可,具体创建集群操作请参见创建集群。
说明:在创建E-MapReduce Druid集群时可以勾选YARN和Superset服务,E-MapReduce Druid集群自带的HDFS和YARN仅供测试使用,原因如背景信息所述。对于生产环境,强烈建议您采用专门的Hadoop集群。
对于独立的E-MapReduce Druid集群,如果您需要将索引数据存放在另外一个Hadoop集群的HDFS上,则您首先需要设置两个集群的连通性(请参见下文的与Hadoop集群交互),然后在E-MapReduce Druid配置页面,配置以下两个选项并重启服务即可(配置项位于配置页面的common.runtime)。
hdfs://emr-header-1.cluster-xxxxxxxx:9000/druid/segments
。说明:如果Hadoop集群为HA集群,emr-header-1.cluster-xxxxx:9000需要改成emr-cluster,或者把端口9000改成8020。
E-MapReduce Druid支持以OSS作为deep storage,借助于E-MapReduce的免AccessKey 能力,E-MapReduce Druid不用做AccessKey配置即可访问OSS。由于OSS的访问能力是借助于HDFS的OSS功能实现的,因此在配置时,druid.storage.type需要仍然配置为HDFS。
oss://emr-druid-cn-hangzhou/segments
)由于OSS访问借助了HDFS,因此您需要选择以下两种方案之一:
/etc/ecm/druid-conf/druid/_common/
下新建hdfs-site.xml,内容如下,然后将该文件拷贝至所有节点的相同目录下。<?xml version="1.0"?>
<configuration>
<property>
<name>fs.oss.impl</name>
<value>com.aliyun.fs.oss.nat.NativeOssFileSystem</value>
</property>
<property>
<name>fs.oss.buffer.dirs</name>
<value>file:///mnt/disk1/data,...</value>
</property>
<property>
<name>fs.oss.impl.disable.cache</name>
<value>true</value>
</property>
</configuration>
其中fs.oss.buffer.dirs可以设置多个路径。
默认情况下E-MapReduce Druid利用header-1
节点上的本地MySQL数据库
作为元数据存储。您也可以配置使用阿里云RDS
作为元数据存储
。
下面以RDS MySQL版为例演示配置。在具体配置之前,请先确保:
在E-MapReduce管理控制台,进入E-MapReduce Druid集群,单击Druid组件,选择配置选项卡,找到common.runtime配置文件。单击自定义配置,添加如下三个配置项:
jdbc:mysql://rm-xxxxx.mysql.rds.aliyuncs.com:3306/druiddb
。依次单击右上角的保存、部署配置文件到主机、重启所有组件,配置即可生效。
登录RDS管理控制台
,查看druiddb创建表的情况,如果正常,您将会看到一些druid自动创建的表。
E-MapReduce Druid组件内存设置主要包括两方面:堆内存(通过jvm.config
配置)和direct内存(通过jvm.config
和runtime.properteis
配置)。在创建集群时,E-MapReduce会自动生成一套配置,不过在某些情况下您仍然可能需要自己调整内存配置。
要调整组件内存配置,可以通过E-MapReduce控制台进入到集群组件,在页面上进行操作。
说明 对于 direct 内存,调整时请确保:
-XX:MaxDirectMemorySize >= druid.processing.buffer.sizeBytes * (druid.processing.numMergeBuffers + druid.processing.numThreads + 1)
E-MapReduce Druid自带三个Web页面:
http://emr-header-1.cluster-1234:18090
,用于查看task运行情况。http://emr-header-1.cluster-1234:18081
,用于查看segments存储情况,并设置rule加载和丢弃segments。http://emr-header-1.cluster-1234:18888
,也称之为console,是新版Druid的统一入口。E-MapReduce提供三种方式访问E-MapReduce Druid的Web页面:
说明 您可以使用Knox账号访问Druid Web页面,Knox账号创建请参见管理用户,Knox使用请参见Knox 使用说明。
http://123.123.123.123:18090
(不推荐,请通过安全组设置合理控制公网访问集群权限)。您在创建E-MapReduce Druid集群时如果勾选了HDFS和YARN(自带Hadoop集群),那么系统将会自动为您配置好与HDFS和YARN的交互,您无需做额外操作。下面的介绍是配置独立E-MapReduce Druid集群与独立Hadoop集群之间交互,这里假设E-MapReduce Druid集群cluster id 为1234,Hadoop集群cluster id为5678。另外请严格按照指导进行操作,如果操作不当,集群可能就不会按照预期工作。
对于与非安全独立Hadoop集群交互,请按照如下操作进行:
确保集群间能够通信(两个集群在一个安全组下,或两个集群在不同安全组,但两个安全组之间配置了访问规则)。
在E-MapReduce Druid集群的每个节点的指定路径下,放置一份Hadoop集群中/etc/ecm/hadoop-conf
路径下的core-site.xml、hdfs-site.xml、yarn-site.xml、 mapred-site.xml文件。 这些文件在E-MapReduce Druid集群节点上放置的路径与E-MapReduce集群的版本有关,详情说明如下:
/etc/ecm/druid-conf/druid/cluster/_common
/etc/ecm/druid-conf/druid/_common
说明 如果创建集群时选了自带Hadoop,则在上述目录下会有几个软链接指向自带Hadoop的配置,请先移除这些软链接。
...
10.157.*.* emr-as.cn-hangzhou.aliyuncs.com
10.157.*.* eas.cn-hangzhou.emr.aliyuncs.com
192.168.*.* emr-worker-1.cluster-1234 emr-worker-1 emr-header-2.cluster-1234 emr-header-2 iZbp1h9g7boqo9x23qb****
192.168.*.* emr-worker-2.cluster-1234 emr-worker-2 emr-header-3.cluster-1234 emr-header-3 iZbp1eaa5819tkjx55y****
192.168.*.* emr-header-1.cluster-1234 emr-header-1 iZbp1e3zwuvnmakmsje****
--以下为hadoop集群的hosts信息
192.168.*.* emr-worker-1.cluster-5678 emr-header-2.cluster-5678 iZbp195rj7zvx8qar4f****
192.168.*.* emr-worker-2.cluster-5678 emr-header-3.cluster-5678 iZbp15vy2rsxoegki4q****
192.168.*.* emr-header-1.cluster-5678 iZbp10tx4egw3wfnh5o****
对于安全Hadoop集群,请按如下操作进行:
确保集群间能够通信(两个集群在一个安全组下,或两个集群在不同安全组,但两个安全组之间配置了访问规则)。
在E-MapReduce Druid集群的每个节点的指定路径下,放置一份Hadoop集群/etc/ecm/hadoop-conf
路径下的core-site.xml、hdfs-site.xml、yarn-site.xml、 mapred-site.xml
文件,并修改core-site.xml
中hadoop.security.authentication.use.has
为 false
。
其中,core-site.xml、hdfs-site.xml、yarn-site.xml、 mapred-site.xml文件在E-MapReduce Druid集群节点上放置的路径与E-MapReduce集群的版本有关,详情说明如下:
其中,hadoop.security.authentication.use.has是一个客户端配置,目的是让用户能够使用AccessKey进行认证。如果使用Kerberos认证方式,则需要disable该配置。
说明 默认在安全Hadoop集群中,所有Hadoop命令必须运行在一个本地的账户中,该本地账户需要与principal的name部分同名。YARN也支持将一个principal映射至本地一个账户,即上文第二种做法。
E-MapReduce Druid自带了一个名为wikiticker的例子,位于${DRUID_HOME}/quickstart/tutorial
下面(${DRUID_HOME}默认为/usr/lib/druid-current)
。wikiticker文件(wikiticker-2015-09-12-sampled.json.gz)的每一行是一条记录,每条记录是个json对象。其格式如下所示:
{
"time": "2015-09-12T00:46:58.771Z",
"channel": "#en.wikipedia",
"cityName": null,
"comment": "added project",
"countryIsoCode": null,
"countryName": null,
"isAnonymous": false,
"isMinor": false,
"isNew": false,
"isRobot": false,
"isUnpatrolled": false,
"metroCode": null,
"namespace": "Talk",
"page": "Talk:Oswald Tilghman",
"regionIsoCode": null,
"regionName": null,
"user": "GELongstreet",
"delta": 36,
"added": 36,
"deleted": 0
}
使用Hadoop对批量数据创建索引,请按照如下步骤进行操作:
hdfs://emr-header-1.cluster-5678:9000/druid
)。 在Hadoop集群上执行如下命令。### 如果是在独立Hadoop集群上进行操作,做好两个集群互信之后需要拷贝一个 druid.keytab到Hadoop集群再kinit。
kinit -kt /etc/ecm/druid-conf/druid.keytab druid
###
hdfs dfs -mkdir hdfs://emr-header-1.cluster-5678:9000/druid
hdfs dfs -put ${DRUID_HOME}/quickstart/tutorial/wikiticker-2015-09-12-sampled.json hdfs://emr-header-1.cluster-5678:9000/druid
对于安全集群执行 HDFS 命令前先修改/etc/ecm/hadoop-conf/core-site.xml中hadoop.security.authentication.use.has为false。
请确保已经在Hadoop集群每个节点上创建名为druid的Linux账户。
${DRUID_HOME}/quickstart/tutorial/wikiticker-index.json
,如下所示:{
"type" : "index_hadoop",
"spec" : {
"ioConfig" : {
"type" : "hadoop",
"inputSpec" : {
"type" : "static",
"paths" : "hdfs://emr-header-1.cluster-5678:9000/druid/wikiticker-2015-09-12-sampled.json"
}
},
"dataSchema" : {
"dataSource" : "wikiticker",
"granularitySpec" : {
"type" : "uniform",
"segmentGranularity" : "day",
"queryGranularity" : "none",
"intervals" : ["2015-09-12/2015-09-13"]
},
"parser" : {
"type" : "hadoopyString",
"parseSpec" : {
"format" : "json",
"dimensionsSpec" : {
"dimensions" : [
"channel",
"cityName",
"comment",
"countryIsoCode",
"countryName",
"isAnonymous",
"isMinor",
"isNew",
"isRobot",
"isUnpatrolled",
"metroCode",
"namespace",
"page",
"regionIsoCode",
"regionName",
"user"
]
},
"timestampSpec" : {
"format" : "auto",
"column" : "time"
}
}
},
"metricsSpec" : [
{
"name" : "count",
"type" : "count"
},
{
"name" : "added",
"type" : "longSum",
"fieldName" : "added"
},
{
"name" : "deleted",
"type" : "longSum",
"fieldName" : "deleted"
},
{
"name" : "delta",
"type" : "longSum",
"fieldName" : "delta"
},
{
"name" : "user_unique",
"type" : "hyperUnique",
"fieldName" : "user"
}
]
},
"tuningConfig" : {
"type" : "hadoop",
"partitionsSpec" : {
"type" : "hashed",
"targetPartitionSize" : 5000000
},
"jobProperties" : {
"mapreduce.job.classloader": "true"
}
}
},
"hadoopDependencyCoordinates": ["org.apache.hadoop:hadoop-client:2.8.5"]
}
说明
spec.ioConfig.type设置为hadoop。
spec.ioConfig.inputSpec.paths为输入文件路径。
tuningConfig.type为hadoop。
tuningConfig.jobProperties设置了mapreduce job的classloader。
hadoopDependencyCoordinates 制定了hadoop client的版本。
cd ${DRUID_HOME}
curl --negotiate -u:druid -b ~/cookies -c ~/cookies -XPOST -H 'Content-Type:application/json' -d @quickstart/tutorial/wikiticker-index.json http://emr-header-1.cluster-1234:18090/druid/indexer/v1/task
其中 -negotiate
、-u
、-b
、-c
等选项是针对安全E-MapReduce Druid集群的。Overlord的端口默认为18090。
在浏览器访问http://emr-header-1.cluster-1234:18090/console.html
查看作业运行情况
(${DRUID_HOME}/quickstart/tutorial/wikiticker-top-pages.json)
:{
"queryType" : "topN",
"dataSource" : "wikiticker",
"intervals" : ["2015-09-12/2015-09-13"],
"granularity" : "all",
"dimension" : "page",
"metric" : "edits",
"threshold" : 25,
"aggregations" : [
{
"type" : "longSum",
"name" : "edits",
"fieldName" : "count"
}
]
}
在命令行界面运行下面的命令即可看到查询结果。
cd ${DRUID_HOME}
curl --negotiate -u:druid -b ~/cookies -c ~/cookies -XPOST -H 'Content-Type:application/json' -d @quickstart/tutorial/wikiticker-top-pages.json 'http://emr-header-1.cluster-1234:18082/druid/v2/?pretty'
对于数据从Kafka集群实时到E-MapReduce Druid集群进行索引,我们推荐使用Kafka Indexing Service扩展,提供了高可靠保证,支持exactly-once语义。关于Druid Kafka Indexing Service 实时消费Kafka数据具体步骤,请参见Kafka Indexing Service。
如果您的数据实时打到了阿里云日志服务(SLS),并想用E-MapReduce Druid实时索引这部分数据,我们提供了SLS Indexing Service扩展。使用SLS Indexing Service避免了您额外建立并维护Kafka集群的开销。SLS Indexing Service的作用与Kafka Indexing Service相同,也提供高可靠保证和 Exactly-Once语义。在这里,您完全可以把SLS当成一个Kafka来使用。详情请参见 SLS-Indexing-Service。
Kafka Indexing Service和SLS Indexing Service是类似的,都使用拉的方式从数据源拉取数据到E-MapReduce Druid集群,并提供高可靠保证和 exactly-once语义。
当发现索引失败时,一般遵循如下排错思路: