大数据-151 Apache Druid 集群落地 [上篇] MySQL 元数据 + HDFS 深存与低配调优

TL;DR

  • 场景:2C4G/2C2G 三节点混部,Druid 30.0.0,Kafka/HDFS/MySQL 协同。
  • 结论:低配能跑,但核心在 DirectMemory 与 processing.buffer 的收敛及基础设施可达性。
  • 产出:按图就班的配置要点、版本矩阵、常见故障速查与定位步骤。

版本矩阵

组件 / 配置 版本 / 参数 已验证 说明
Apache Druid 30.0.0($DRUID_HOME) 进程划分:master(coordinator+overlord)、data(historical+middleManager)、query(broker+router)。混部署于 h121/h122/h123。
Metadata Storage MySQL(连接器 8.0.19) 连接器置于 extensions/mysql-metadata-storage;druid.metadata.storage.* 指向 h122。
深度存储 HDFS(/druid/segments) 依赖 core-site 默认 FS;生产建议使用 hdfs://host:port/ 绝对路径。
Indexing Logs HDFS(/druid/indexing-logs) 需 Hadoop 配置在 _common 生效。
ZooKeeper h121,h122,h123:2181 druid.zk.paths.base=/druid,确保 ACL/网络可达。
Kafka 实时摄取 版本未标注 部分 MiddleManager 可接入;建议压测后再扩容任务槽。
JDK 未标注 未核对 Druid 30 通常建议 Java 11/17;请确认与线上一致。
Coordinator/Overlord JVM -Xms/-Xmx=512m 低吞吐可用;管理面优先稳定。
Historical JVM -Xms/-Xmx=512m;MaxDirectMemory=1g 与 buffer=50,000,000 成对收敛。
MiddleManager JVM -Xms/-Xmx=128m 仅演示负载;任务量上来需调大。
processing.buffer.sizeBytes 50,000,000 需满足 MaxDirectMemory ≈ buffer×(numMergeBuffers+numThreads+1)。

整体介绍

Apache Druid 是一种高性能、分布式的列式存储数据库,专门用于实时分析和查询大规模数据集。它适用于 OLAP(在线分析处理)场景,尤其在处理大数据实时流时表现优异。Druid 的架构由多个组件组成,主要包括数据摄取、存储、查询和管理。

在集群配置方面,Druid 通常由以下节点构成:

  • 数据摄取层:使用 MiddleManager 节点来处理数据的实时摄取,负责从不同数据源(如 Kafka、HDFS 等)读取数据并进行实时处理。
  • 存储层:数据存储在 Historical 节点上,这些节点负责存储和管理较老的数据,支持高效的查询。数据被以列式格式存储,优化了查询性能。
  • 查询层:Broker 节点充当查询路由器,接受用户的查询请求并将其分发到相应的 Historical 或 Real-time 节点,然后将结果汇总返回给用户。
  • 协调层:Coordinator 节点负责集群的状态管理和数据分配,确保数据均匀分布并自动处理节点故障。

Druid 的配置文件允许用户自定义参数,如 JVM 设置、内存分配和数据分片策略,以便根据不同的工作负载和性能需求进行优化。此外,Druid 还支持多种查询语言,包括 SQL,便于用户进行灵活的数据分析。整体上,Druid 提供了一种高效、可扩展的解决方案,适合需要快速实时分析的大数据应用场景。

集群规划

集群部署采用的分配如下:

  • 主节点部署 Coordinator 和 Overlord 进程
  • 数据节点运行 Historical 和 MiddleManager 进程
  • 查询节点 部署Broker 和 Router 进程

我的实机部署情况:

  • h121.wzk.icu 2C4G ZooKeeper、Kafka、Druid
  • h122.wzk.icu 2C4G ZooKeeper、Kafka、Druid、MySQL(之前Hive时搭建)
  • h123.wzk.icu 2C2G ZooKeeper、Druid

环境变量

shell 复制代码
vim /etc/profile

写入的内容如下:

shell 复制代码
# druid
export DRUID_HOME=/opt/servers/apache-druid-30.0.0
export PATH=$PATH:$DRUID_HOME/bin

配置文件

将 Hadoop 配置文件:

  • core-site.xml
  • hdfs-site.xml
  • yarn-site.xml
  • mapred-site.xml

上述文件链接到 conf/druid/cluster/_common 下 执行下面的Shell:

shell 复制代码
cd $DRUID_HOME/conf/druid/cluster/_common
ln -s $HADOOP_HOME/etc/hadoop/core-site.xml core-site.xml
ln -s $HADOOP_HOME/etc/hadoop/hdfs-site.xml hdfs-site.xml
ln -s $HADOOP_HOME/etc/hadoop/yarn-site.xml yarn-site.xml
ln -s $HADOOP_HOME/etc/hadoop/mapred-site.xml mapred-site.xml
ls

执行结果如下图所示:

MySQL

将MySQL驱动链接到:$DRUID_HOME/extensions/mysql-metadata-storage 中

shell 复制代码
cd $DRUID_HOME/extensions/mysql-metadata-storage
cp $HIVE_HOME/lib/mysql-connector-java-8.0.19.jar mysql-connector-java-8.0.19.jar
ls

执行结果如下图所示:

修改配置

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/_common/common.runtime.properties

我们要修改如下的内容:

shell 复制代码
# 增加"mysql-metadata-storage"
druid.extensions.loadList=["mysql-metadata-storage", "druid-hdfs-storage", "druid-kafka-indexing-service", "druid-datasketches", "druid-multi-stage-query"]

# 每台机器写自己的ip或hostname
# 我这里是h121节点
druid.host=h121.wzk.icu
# 填写zk地址
druid.zk.service.host=h121.wzk.icu:2181,h122.wzk.icu:2181,h123.wzk.icu:2181
druid.zk.paths.base=/druid

# 注释掉前面 derby 的配置
# 增加 mysql 的配置
druid.metadata.storage.type=mysql
druid.metadata.storage.connector.connectURI=jdbc:mysql://h122.wzk.icu:3306/druid
druid.metadata.storage.connector.user=hive
druid.metadata.storage.connector.password=hive@wzk.icu

# 注释掉local的配置
# 增加HDFS的配置,即使用HDFS作为深度存储
druid.storage.type=hdfs
druid.storage.storageDirectory=/druid/segments

# 注释掉 indexer.logs For local disk的配置
# 增加 indexer.logs For HDFS 的配置
druid.indexer.logs.type=hdfs
druid.indexer.logs.directory=/druid/indexing-logs

修改截图如下: 修改截图如下所示:

coordinator-overlord

参数大小根据实际情况调整

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/master/coordinator-overlord/jvm.config

原来的配置如下图所示:

shell 复制代码
-server
-Xms15g
-Xmx15g
-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

修改内容如下所示:

shell 复制代码
-server
-Xms512m
-Xmx512m
-XX:+ExitOnOutOfMemoryError
-XX:+UseG1GC
-Duser.timezone=UTC+8
-Dfile.encoding=UTF-8
-Djava.io.tmpdir=var/tmp
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

对应的截图如下所示:

historical

参数大小根据实际情况调整

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/data/historical/jvm.config

原配置内容如下所示:

shell 复制代码
-server
-Xms8g
-Xmx8g
-XX:MaxDirectMemorySize=13g
-XX:+ExitOnOutOfMemoryError
-Duser.timezone=UTC
-Dfile.encoding=UTF-8
-Djava.io.tmpdir=var/tmp
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

修改内容如下:

shell 复制代码
-server
-Xms512m
-Xmx512m
-XX:MaxDirectMemorySize=1g
-XX:+ExitOnOutOfMemoryError
-Duser.timezone=UTC+8
-Dfile.encoding=UTF-8
-Djava.io.tmpdir=var/tmp
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

修改结果如下图: 此外还有一个参数:

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/data/historical/runtime.properties

原配置内容如下:

shell 复制代码
druid.processing.buffer.sizeBytes=500MiB

修改为如下内容:

shell 复制代码
# 相当于 50MiB
druid.processing.buffer.sizeBytes=50000000

修改的截图如下: 备注:

  • druid.processing.buffer.sizeBytes 每个查询用于聚合的对外哈希表的大小
  • maxDirectMemory = druid.processing.buffer.sizeBytes * (durid.processing.numMergeBuffers + druid.processing.numThreads + 1)
  • 如果 druid.processing.buffer.sizeBytes太大的话,需要加大 maxDirectMemory,否则 historical服务无法启动

middleManager

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/data/middleManager/jvm.config

原配置:

shell 复制代码
-server
-Xms128m
-Xmx128m
-XX:+ExitOnOutOfMemoryError
-Duser.timezone=UTC
-Dfile.encoding=UTF-8
-Djava.io.tmpdir=var/tmp
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

配置如下(没有修改):

shell 复制代码
-server
-Xms128m
-Xmx128m
-XX:+ExitOnOutOfMemoryError
-Duser.timezone=UTC+8
-Dfile.encoding=UTF-8
-Djava.io.tmpdir=var/tmp
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

修改的截图如下:

错误速查

症状 根因 定位 修复
Historical 启动即退出/Direct buffer OOM buffer 过大与 MaxDirectMemory 不匹配 查看 historical 日志中 "Cannot allocate memory / direct buffer" 提示;核对 runtime.properties 与 jvm.config 降低 druid.processing.buffer.sizeBytes 或提高 -XX:MaxDirectMemorySize;按公式收敛(buffer ×(merge+threads+1))。
"No suitable driver / 找不到 MySQL 驱动" 连接器未放到正确目录或命名错误 检查 $DRUID_HOME/extensions/mysql-metadata-storage 确保 mysql-connector-java-8.0.19.jar 存在且重启生效。
深度存储写失败 / "No FileSystem for scheme: hdfs" Hadoop 客户端依赖/配置未生效 看 middleManager/historical 日志;核对 _common 下 *-site.xml 确保 druid-hdfs-storage 已加载;软链 Hadoop 配置,必要时补齐 Hadoop 客户端依赖。
Broker 查询 500 / "No servers found" 无可用 Historical/Realtime 节点或段未加载 Web 控制台看 Coordinator Segments/Rules;Broker 日志 启动 Historical/Realtime;确认段已加载与路由规则有效。
ZK 连接超时 / ConnectionLoss zk 地址/端口错误或网络不可达 zookeeper 客户端 zkCli 直连测试 修正 druid.zk.service.host;放通 2181;确保 /druid 存在。
MiddleManager 任务卡住/日志不落 HDFS HDFS 目录权限/配额问题 hdfs dfs -ls/-chmod 检查目录;任务日志报错 赋权/预建目录;必要时调整 fs.permissions.umask-mode。
时间列偏移 8 小时 JVM 时区参数不规范 查询服务与任务日志中的时区信息 将 -Duser.timezone 设为 Asia/Shanghai(或 GMT+08:00),并核对 ingestion spec 的 timestampSpec。
HDFS 路径解析异常 使用相对路径但 defaultFS 未配置 查看 core-site.xml 的 fs.defaultFS 将存储目录改为 hdfs://host:port/... 或补齐 defaultFS。
主机名不可达 / DNS 失败 使用内网域名未解析 ping/host 验证 h121.wzk.icu 等 /etc/hosts 写死映射或改用 IP;同步修改 druid.host。

【续接下篇!】

其他系列

🚀 AI篇持续更新中(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究 ,持续打造实用AI工具指南! AI-调查研究-108-具身智能 机器人模型训练全流程详解:从预训练到强化学习与人类反馈 🔗 AI模块直达链接

💻 Java篇持续更新中(长期更新)

Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础! 🔗 Java模块直达链接

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解 🔗 大数据模块直达链接

相关推荐
小何开发2 小时前
Springboot-WebService 服务端发布与客户端调用
java·spring boot·后端
绝无仅有2 小时前
Redis 面试题解析:某度互联网大厂
后端·面试·架构
weisian1512 小时前
Elasticsearch-4--倒排索引的原理?
大数据·elasticsearch·搜索引擎
绝无仅有2 小时前
某度互联网大厂 MySQL 面试题解析
后端·面试·架构
q***69772 小时前
Spring boot启动原理及相关组件
数据库·spring boot·后端
q***46522 小时前
Spring Boot 整合 Keycloak
java·spring boot·后端
q***07143 小时前
【分布式】Hadoop完全分布式的搭建(零基础)
大数据·hadoop·分布式
月屯3 小时前
平台消息推送(go)
数据库·后端·golang·cocoa·iphone·gin
q***31893 小时前
深入解析Spring Boot中的@ConfigurationProperties注解
java·spring boot·后端