部署准备
Apache Druid依赖深度存储、元数据库和分布式协调器。
深度存储主要是解决数据高可靠问题,也就是说,如果Druid数据节点的持久化数据出现丢失,可以从深度存储中恢复。深度存储可以使用本地文件、Hadoop HDFS、Amazon S3等方式,我们这里选择HDFS。
元数据库存储集群元数据,包括Datasouce、Segments、Supervisors、Tasks、Rules等前期配置元数据与运行期产生的各项元数据。我们可以使用Derby、MySQL、PostgreSQL等方式,我们这里选择PostgreSQL。
分布式协调器是Apache Druid的核心部件,应用于Druid集群不用子服务之间的状态协调。Druid使用的分布式协同器为Zookeeper。
关于CentOS 7、Hadoop HDFS 3、Zookeeper的部署
我们可以在网上找到很多免费文章,帮助你完成这些基础依赖系统的部署,如果仍无法得到解决,可以考虑通过订阅我的CSDN付费专栏,获取最细致的CentOS7、Hadoop3高可用集群及Zookeeper集群的安装文章:
从零开始安装、配置CentOS 7
从零开始部署Hadoop3高可用集群(基于CentOS7,含Zookeeper集群安装)
关于PostgreSQL的安装与配置
我们可以选择MySQL或者PostgreSQL作为元数据库,对于PostgreSQL11的安装,也可以参考:
CentOS7下安装PostgreSQL11数据库
我们需要创建Druid角色数据库:
1. create role druid login password 'YOUR_PASSWORD'; 2. create database druid with owner= druid;
部署Druid
硬件配置
Apache Druid是个吃计算资源的巨兽,由于我们首先需要满足的是学习实验需求,因此本次部署旨在探索出集群正常运行并可以进行数据实验的最低硬件配置方案。
硬件宿主机为一台MacBook Pro Intel i7 6核 2.2 GHz,物理内存 16GB,SSD 512GB(USB3.0 外接),运行VMware Fusion 12.0.0,并分配三个虚拟节点,虚拟资源配置如下:
主节点:datanode-1,CPU:2核心,内存:4GB,磁盘最大容量:50GB
数据节点:datanode-2,CPU:2核心,内存:5GB,磁盘最大容量:50GB
查询节点:datanode-3,CPU:2核心,内存:4GB,磁盘最大容量:50GB
总计: CPU 6核心,内存 14GB,磁盘 150GB
从上述资源需求可以看出来,我的Mac笔记本运行起3节点后,基本上占用了大部分的计算资源。不过宿主机依然还能正常工作。
对于实验需求的另外一种方式,可以考虑使用按量计费的云计算服务,最低计算资源需求可以参考上述列表。
部署Druid包和Hadoop配置
首先,进入Apache Druid官网
下载Druid 0.22版本:
https://dlcdn.apache.org/druid/0.22.1/apache-druid-0.22.1-bin.tar.gz
分别解压到datanode-1,datanode-1,datanode-1的/opt目录下,顺便做个软链:
ln -s /opt/apache-druid-0.22.1 /opt/druid
如果当前节点已经安装了Hadoop,那么我们需要使用到Hadoop所在的目录,如果没有安装Hadoop,我们需要从有Hadoop的节点复制Hadoop目录到本机。
分别复制Hadoop目录到datanode-1,datanode-1,datanode-1节点,顺便在/opt目录下做个软链:
ln -s $HADOOP_PARENT_DIR/hadoop-3.3.1 /opt/hadoop
其次,在/opt/druid/hadoop-dependencies/hadoop-client目录下面需要具有Hadoop3.3.1的客户端依赖Jar包集合,那么我就用maven的方式构建出来。
因此最好你的本地配置好Maven环境,具体Maven下载与配置,这里不在赘述。
(1) 构建Maven工程,下面是pom.xml示例,主要是为了配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>hadoop-client-jar</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>3.3.1</version> </dependency> </dependencies> </project>
(2) 在$Project目录下执行MVN命令,当前目录下就会生成lib目录
mvn dependency:copy-dependencies -DoutputDirectory=lib
(3) 上传lib目录
scp -r lib root@datanode-1:/opt/druid/hadoop-dependencies/hadoop-client/3.3.1 scp -r lib root@datanode-2:/opt/druid/hadoop-dependencies/hadoop-client/3.3.1 scp -r lib root@datanode-3:/opt/druid/hadoop-dependencies/hadoop-client/3.3.1
也就是说我们在/opt/druid/hadoop-dependencies/hadoop-client目录下面创建了3.3.1子目录,将本地lib目录下面所有的jar复制到了3.3.1目录里面。
最后,我们还需要将Hadoop的配置文件f分别链接到Druid的集群配置目录:
ln -s /opt/hadoop/etc/hadoop/core-site.xml /opt/druid/conf/druid/cluster/_common/ ln -s /opt/hadoop/etc/hadoop/hdfs-site.xml /opt/druid/conf/druid/cluster/_common/ ln -s /opt/hadoop/etc/hadoop/mapred-site.xml /opt/druid/conf/druid/cluster/_common/ ln -s /opt/hadoop/etc/hadoop/yarn-site.xml /opt/druid/conf/druid/cluster/_common/
至此,Hadoop与Druid之间通过配置就衔接上了。
配置Druid集群
在$DRUID_HOME/conf/druid/cluster下面有四个目录,分别是:_common、data、master、query,代表了通用性配置、数据节点配置、主节点配置、查询节点配置。
由于我们是按照最少的硬件资源配置,分配了3个节点,因此,每个节点都只具有1个功能服务。
通用配置,对应了_common目录。
主节点配置:datanode-1,对应master/coordinator-overlord目录,运行coordinator服务、overlord服务。
数据节点配置:datanode-2,对应data/historical,data/middleManager目录,运行historical服务、middleManager服务。
查询节点配置:datanode-3,对应query/broker,query/router目录,运行broker服务、route服务。
1)通用配置
我们先在datanode-1节点上编辑/opt/druid/conf/druid/cluster/_common/common.runtime.properties文件,我将其中需要配置的地方进行列出:
#加入外部扩展项,包括了PostgreSQL元数据库<postgresql-metadata-storage>,HDFS深度存储<druid-hdfs-storage> #流式摄取<Kafka-indexing-server>,数据流算法库<druid-datasketches> druid.extensions.loadList=["postgresql-metadata-storage", "druid-hdfs-storage", "druid-kafka-indexing-service", "druid-datasketches"] #当前Druid节点的主机地址 druid.host=datanode-1 #Hadoop客户端依赖库地址 druid.extensions.hadoopDependenciesDir=/opt/druid/hadoop-dependencies/hadoop-client/3.3.1 #外连Zookeeper集群地址以及Druid在ZK中的基础目录 druid.zk.service.host=datanode-1:2181,datanode-2:2181,datanode-3:2181 druid.zk.paths.base=/druid #注销derby作为元数据库 #druid.metadata.storage.type=derby #druid.metadata.storage.connector.connectURI=jdbc:derby://localhost:1527/var/druid/metadata.db;create=true #druid.metadata.storage.connector.host=localhost #druid.metadata.storage.connector.port=1527 #启用PostgreSQL作为元数据库 druid.metadata.storage.type=postgresql druid.metadata.storage.connector.connectURI=jdbc:postgresql://datanode-1:5432/druid druid.metadata.storage.connector.user=druid druid.metadata.storage.connector.password=123456 # 注销本地磁盘作为Segments深度存储 #druid.storage.type=local #druid.storage.storageDirectory=var/druid/segments # 启用HDFS作为Segments深度存储 druid.storage.type=hdfs #druid.storage.storageDirectory=/druid/segments druid.storage.storageDirectory=hdfs://fsnss/druid/segments # 注销本地磁盘作为Indexing-logs日志存储 #druid.indexer.logs.type=file #druid.indexer.logs.directory=var/druid/indexing-logs # 启用HDFS作为Indexing-logs日志存储 druid.indexer.logs.type=hdfs #druid.indexer.logs.directory=/druid/indexing-logs druid.indexer.logs.directory=hdfs://fsnss/druid/indexing-logs # # 注销安全策略 # #druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"
完成配置,我们将其分发到其他两个节点的相同位置:
scp /opt/druid/conf/druid/cluster/_common/common.runtime.properties root@datanode-2:/opt/druid/conf/druid/cluster/_common scp /opt/druid/conf/druid/cluster/_common/common.runtime.properties root@datanode-3:/
需要注意的是:我们必须在另外两个节点中编辑common.runtime.properties文件,修改druid.host,等于当前节点的主机地址。
2)主节点配置
我们依旧在datanode-1节点进行主节点配置,将datanode-1打造成主节点,主要运行coordinator和overlord服务,目前两者已经整合为一个服务进程。前者主要协调Segments的深度存储,后者主要接收新任务提交与协调任务下发。
其实主要是对内存的限制调整,保证Druid启动时不会因为内存不够而导致启动和运行失败。
vi /opt/druid/conf/druid/cluster/master/coordinator-overlord/jvm.config
如下参考配置:
-server -Xms1g -Xmx2g -XX:+ExitOnOutOfMemoryError -XX:+UseG1GC -Duser.timezone=UTC -Dfile.encoding=UTF-8 -Djava.io.tmpdir=var/tmp -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -Dderby.stream.error.file=var/druid/derby.log
XMs最小堆内存设置为1GB,XMx最大堆内存设置为2GB
vi /opt/druid/conf/druid/cluster/master/coordinator-overlord/runtime.properties
如下参考配置:
druid.service=druid/coordinator druid.plaintextPort=18081 druid.coordinator.startDelay=PT10S druid.coordinator.period=PT5S # Run the overlord service in the coordinator process druid.coordinator.asOverlord.enabled=true druid.coordinator.asOverlord.overlordService=druid/overlord druid.indexer.queue.startDelay=PT5S druid.indexer.runner.type=remote druid.indexer.storage.type=metadata
修改了coordinator端口,改为18081,主要是在实验环境,防止与其他应用端口冲突,若独立部署,则不存在问题。
3)数据节点配置
我们登陆datanode-2节点,进行数据节点配置,将datanode-2打造成数据节点,主要运行historical服务和middleManager服务,前者主要负责已经是历史数据的Segment的管理,后者主要负责新摄取数据的任务管理。
我们先开始配置historical:
vi /opt/druid/conf/druid/cluster/data/historical/jvm.config
如下参考配置:
-server -Xms1g -Xmx2g -XX:MaxDirectMemorySize=3g -XX:+ExitOnOutOfMemoryError -Duser.timezone=UTC -Dfile.encoding=UTF-8 -Djava.io.tmpdir=var/tmp -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
XMs最小堆内存设置为1GB,XMx最大堆内存设置为2GB,最大非堆内存设置为3GB
vi /opt/druid/conf/druid/cluster/data/historical/runtime.properties
如下参考配置:
druid.service=druid/historical druid.plaintextPort=18083 # HTTP server threads druid.server.http.numThreads=60 # Processing threads and buffers druid.processing.buffer.sizeBytes=250MiB druid.processing.numMergeBuffers=2 druid.processing.numThreads=5 druid.processing.tmpDir=var/druid/processing # Segment storage druid.segmentCache.locations=[{"path":"var/druid/segment-cache","maxSize":"20g"}] # Query cache druid.historical.cache.useCache=true druid.historical.cache.populateCache=true druid.cache.type=caffeine druid.cache.sizeInBytes=256MiB