大数据-152 Apache Druid 集群模式 [下篇] 低内存集群实操:JVM/DirectMemory与启动脚本

TL;DR

  • 场景:三节点(h121/h122/h123)在已有 ZK/HDFS 上部署 Druid 30.0.0,并将 Broker/Historical/Router 压到低内存可运行。
  • 结论:堆与堆外需联动收敛;processing.buffer.sizeBytes 与 MaxDirectMemorySize 同步收口,否则服务起不来或查询抖。
  • 产出:分角色 jvm.config 与 runtime.properties 最小化示例、rsync 分发、启停与 WebUI 验证路径。

版本矩阵

已验证 说明
Apache Druid 30.0.0(三角色:master/data/query) 文中含启动截图与路径 /opt/servers/apache-druid-30.0.0。节点:h121/h122/h123 是 h121 查询、h122 数据、h123 主;对应三套启动脚本。
依赖:ZooKeeper 三节点 先起 zkServer.sh start,作为 Druid 依赖。
依赖:Hadoop/HDFS start-all.shstart-dfs.sh,有启动截图。
Historical:-Xmx512m / Direct 1g 同步将 processing.buffer.sizeBytes≈50 MiB;注意直内存上限关联并发。
Broker:-Xmx512m / Direct 512m 同步 processing.buffer.sizeBytes≈50 MiB;否则易 OOM Direct。
Router:-Xmx128m / Direct 128m 轻量路由,仅转发查询。
时区参数 -Duser.timezone=UTC+8 可运行;如需更规范可后续改为 Asia/Shanghai
分发:rsync-script apache-druid-30.0.0 从 h121 推送至 h122/h123;分发后按节点改 druid.host
备注一致性部分正文备注 正文备注里 durid.processing.* 疑似笔误,应为 druid.*

整体介绍

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

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

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

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

修改配置【续接上篇】

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服务无法启动

broker

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/query/broker/jvm.config

原配置如下:

shell 复制代码
-server
-Xms12g
-Xmx12g
-XX:MaxDirectMemorySize=6g
-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=512m
-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/query/broker/runtime.properties

原参数为:

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

修改为:

shell 复制代码
# 与刚才修改的一样 大约是50MiB
druid.processing.buffer.sizeBytes=50000000

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

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

router

shell 复制代码
vim $DRUID_HOME/conf/druid/cluster/query/router/jvm.config

原配置如下:

shell 复制代码
-server
-Xms1g
-Xmx1g
-XX:+UseG1GC
-XX:MaxDirectMemorySize=128m
-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:+UseG1GC
-XX:MaxDirectMemorySize=128m
-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

修改截图如下:

配置汇总

  • coordinator-overlord:512M
  • historical:512M,堆外1G
  • middleManger:128M
  • broker:512M、堆外512M
  • router:128M,堆外128M

分发软件

你可以用的方式完成,我这里用之前写好的 rsync-script 工具进行分发,刚才我们配置都是在 h121 节点上完成的,所以接下来,我们从 h121 节点分发到 h122、h123

shell 复制代码
rsync-script apache-druid-30.0.0

运行结果如下图所示:

分发之后,要注意你需要修改的东西:

  • common.runtime.properties中的 druid.host 为所在节点的IP
  • h121 h122 h123 上都配置好环境、环境变量等内容

启动服务

ZK启动

在三台节点上都需要启动ZK,并且需要组成ZK集群。 这部分内容之前已经有 ZooKeeper集群环境搭建,且在多个环节中,如Kafka集群环节中已经测试过。

shell 复制代码
zkServer.sh start

启动 Hadoop

shell 复制代码
start-all.sh
# 或者只启动 dfs也行
start-dfs.sh

执行结果如下图所示:

Druid启动

h121 查询节点

这里是查询节点

shell 复制代码
cd /opt/servers/apache-druid-30.0.0
nohup start-cluster-query-server &

运行结果如下图所示:

h122 数据节点

这里是数据节点

shell 复制代码
cd /opt/servers/apache-druid-30.0.0
nohup start-cluster-data-server &

运行结果如下图所示:

h123 主节点

这里是主节点

shell 复制代码
cd /opt/servers/apache-druid-30.0.0
nohup start-cluster-master-no-zk-server &

运行结果如下所示:

日志查看

可以在log下查看,我这里是查看了 nohup 的内容

h121

h122

h123

停止服务

需要在每个节点都执行:

shell 复制代码
# 在各个节点运行
/opt/servers/apache-druid-30.0.0/bin/service --down

查看界面

shell 复制代码
http://h121.wzk.icu:8888

页面结果如下:

错误速查

症状 根因 定位 修复
Historical 启不来,日志含 Direct buffer OOM processing.buffer.sizeBytes 与 MaxDirectMemorySize 不匹配 看 historical 日志首段与 JVM 参数 提升 MaxDirectMemorySize 或下调 buffer;按公式同步。
Broker 起后查询即挂,OutOfMemoryError: Direct buffer memory Broker 堆外偏小(仅 512 m)且并发略高 Broker 日志与查询并发峰值 临时降并发;或把 DirectMemory 提到 1 g,buffer 相应放大/缩小一致。
查询报 Cannot acquire enough memory from processing pool buffer 过小或线程/合并缓冲太多 查看 druid.processing.* 配置 降 numThreads/numMergeBuffers 或抬 buffer/DirectMemory。
Router 启动正常但 8888 无法路由到结果 Broker 未起或 Host 配置不对 router/broker 日志与 druid.host 逐一确认 Broker 端口/健康;修正各节点 druid.host。
时间/时区显示异常 -Duser.timezone 与系统时区不一致 WebUI 与日志时间对比 统一到同一时区;推荐地区名时区(后续再改)。
Connection refused 指向 ZK ZK 未全起或集群未成 zkCli.sh 四字命令与端口探测 先确保 ZK 三节点稳定再起 Druid。
HDFS 路径访问失败 HDFS 未启动或权限/路径不对 hdfs dfs -ls 验证 先起 dfs,校验 NameNode/DataNode 状态及路径。
WebUI 能开但无数据源 MiddleManager/Indexing 未摄取或任务失败 Overlord/Indexing 任务页面 查看任务日志;在低内存下控制并发摄取与段大小。
分发后只有一台能起 未按节点改 common.runtime.properties 的 druid.host grep 每节点 druid.host 分别改为各自 IP/主机名,重启相关角色。
nohup 有日志但进程消失 ExitOnOutOfMemoryError 触发 dmesg/hs_err_pid 依据 OOM 类型拉高对应内存或降并发,重启服务。

到此!顺利完成!一路艰难险阻!

其他系列

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

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

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

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

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

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

相关推荐
demonre2 小时前
阿里云 Debian 13.1 安装 docker 并切换阿里云镜像源
后端·docker
程序猿DD2 小时前
探索 Java 中的新 HTTP 客户端
java·后端
lizhongxuan2 小时前
eBPF性能揭秘 - XDP 和 JIT
后端
用户69371750013842 小时前
Kotlin 协程 快速入门
android·后端·kotlin
南雨北斗2 小时前
kotlin开发中的构建工具gradle
后端
xuejianxinokok2 小时前
深入了解RUST迭代器 - 惰性、可组合的处理
后端·rust
后端小张2 小时前
【JAVA 进阶】Spring Boot 自动配置原理与自定义 Starter 实战
java·spring boot·后端·spring·spring cloud·自定义·原理
想用offer打牌2 小时前
修复seata的HikariCP中加载驱动程序类的问题
后端·架构·开源
q***18842 小时前
搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
开发语言·后端·golang