TL;DR
- 场景:实时 + 历史 OLAP,需要稳定摄入、可扩展查询与可预期的集群运维。
- 结论:按 Master(Coordinator/Overlord)/Query(Broker/Router)/Data(Historical/MiddleManager)拆分,配合 ZK、元库与 Deep Storage,优先治理 Segment 与任务调度。
- 产出:架构要点清单、版本/依赖矩阵(待你确认)、常见故障定位与修复速查卡。


基础架构

Coordinator Node
Druid的Coordinator组件主要负责集群中历史节点(Historical Node)的数据负载均衡和生命周期管理。具体来说,它的核心职责包括以下几个方面:
-
数据负载均衡:
- 监控各历史节点的负载情况
- 根据配置的均衡策略在节点间迁移Segment
- 确保数据均匀分布,避免某些节点过载
- 处理新加入或失效节点后的数据重分布
-
生命周期管理:
- 按照预先定义的规则(Rule)管理数据
- 协调新数据的加载流程
- 定期检查并卸载过期数据
- 根据需要复制重要数据以提高可用性
- 执行数据的冷热分层策略
Coordinator的运行是周期性的,其执行间隔由druid.coordinator.period参数控制,默认值为60000毫秒(60秒)。每次运行时,Coordinator会:
-
集群状态同步:
- 维持与ZooKeeper的持久连接
- 实时获取集群拓扑和节点状态信息
- 监控历史节点的加入、离开或故障情况
-
元数据管理:
- 连接配置的元数据库(通常是MySQL或PostgreSQL)
- 读取和维护所有Segment的元信息
- 获取和处理数据管理规则(Rule)配置
- 记录Segment的分布和状态变更
-
决策执行:
- 根据规则和当前状态生成数据管理计划
- 向历史节点下发加载/卸载指令
- 协调节点间的数据迁移操作
- 处理数据复制和均衡的请求
在实际应用中,Coordinator的这些功能确保了Druid集群能够:
- 自动适应工作负载变化
- 优雅处理节点扩容或故障
- 按需保留有价值的历史数据
- 高效利用集群存储资源
Overlord Node
进程监视MiddleManager进程,并且是Druid数据摄入的主节点,负责将提取任务分配给MiddleManagers并协调Segment发布,包括接受、拆解、分配Task,以及创建Task相关的锁,并返回Task的状态。
Historical Node
加载生成好的数据文件,以供数据查询。Historical Node是整个集群查询性能的核心所在,Historical会承担绝大部分的Segment查询。
- Historical 进程从 Deep Storage 中下载 Segment,并响应有关这些Segment的查询请求(这些请求来自Broker进程)
- Historical 进程不处理写入请求
- Historical 进程采用了无共享架构设计,它知道如何去加载和删除 Segment,以及如何基于 Segment 来响应查询。即便底层的深度存储无法正常工作,Historical 进程还是能针对其已同步的 Segments,正常提供查询服务。
- 底层的深度存储无法正常工作,Historical进程还是能针对其已同步的 Segments,正常提供查询服务。
MiddleManager Node
及时摄入实时数据,生成Segment数据文件
- MiddleManager 进程是执行提交任务的工作节点,MiddleManagers将任务转发给在不同JVM中运行的Peon进程
- MiddleManager、Peon、Task的对应关系是:每个Peon进程一次只能运行一个Task任务,但一个MiddleManager却可以管理多个Peon进程
Broker Node
接收客户端查询请求,并将这些查询转发给 Histo 和 MiddleManagers。当Brokers从这些子查询中收到结果时,它们会合并这些结果并将它们返回给调用者。
- Broker 节点负责转发Client查询请求的
- Broker 通过 ZooKeeper 能够知道哪个 Segment 在哪些节点上,将查询转发给相应节点
- 所有节点返回数据后,Broker会所有节点的数据进行合并,然后返回给Client
Router Node
(可选) 负责将路由转发到Broker、Coordinator、Overlords
- Router进程可以在 Broker、Overlords、Coordinator进程之上,提供一层统一的API网关
- Router进程是可选的,如果集群数据规模已经到达了TB级别,需要考虑启动(druid.router.managerProxy.enable=true)
- 一旦集群规模达到一定数量级,那么发生故障的概率就会变得不容忽视,而Router支持将请求只发送给健康的节点,避免请求失败。
- 同时,查询的响应时间和资源消耗,也会随着数据量的增长而变高,而Router支持设置查询的优先级和负载均衡策略,避免了大查询造成的队列堆积或查询热点等问题
如何分类
Druid的进程可以被任意部署,为了理解与部署组织方便,这些进程分为了三类:
- Master:Coordinator、Overlord 负责数据可用性和摄取
- Query:Broker、Router 负责处理外部请求
- Data:Historical、MiddleManager,负责实际的Ingestion负载和数据存储
其他依赖
Deep Storage 存放生成的 Segment 数据文件,并供历史服务器下载,对于单节点集群可以是本地磁盘,而对于分布式集群一般是HDFS。
- Druid使用 Deep Storage来做数据的备份,也作为Druid进程之间在后台传输数据的一种方式
- 当相应查询时,Historical首先从本地磁盘读取预取的段,这也意味着需要在Deep Storage和加载的数据Historical中拥有足够的磁盘空间。
Metadata Storage
存储Durid集群的元数据信息,如Segment的相关信息,一般使用MySQL。
ZooKeeper
Druid 集群通过以下几个关键机制来确保集群内各节点的协调工作:
1. Coordinator 节点的 Leader 选举机制
- 选举协议:采用基于 Zookeeper 的 Leader 选举算法
- 职责范围 :
- 监控 Historical 节点的 Segment 加载状态
- 协调 Segment 在集群中的分布
- 管理 Segment 的加载和丢弃策略
- 选举过程:当当前 Leader 下线时,所有 Coordinator 节点会参与新一轮选举,最先在 Zookeeper 上创建临时节点的成为新 Leader
2. Historical 节点发布 Segment 的协议
- 发布流程 :
- Historical 节点完成 Segment 加载后,会在元数据存储中更新状态
- 向 Coordinator 发送 Segment 可用通知
- Coordinator 验证元数据一致性后,将该 Segment 标记为可查询
- 容错机制:如果发布过程中失败,Segment 会被标记为失败状态,并由 Coordinator 安排重试
3. Coordinator 和 Historical 间的 Segment 管理协议
- Load Segment 流程 :
- Coordinator 根据负载均衡策略选择目标 Historical 节点
- 发送 HTTP 请求通知 Historical 加载指定 Segment
- Historical 从深度存储下载 Segment 数据并加载到内存
- Drop Segment 流程 :
- Coordinator 发送删除指令给 Historical
- Historical 从内存卸载 Segment 并删除本地副本
- 更新元数据状态
4. Overlord 节点的 Leader 选举机制
- 选举特点:与 Coordinator 类似,同样基于 Zookeeper
- 职责范围 :
- 接收和处理任务提交请求
- 分配任务给 MiddleManager
- 监控任务执行状态
- 故障转移:当 Leader 失效时,新 Leader 会接管所有正在运行的任务状态
5. Overlord 和 MiddleManager 间的任务管理协议
- 任务分配流程 :
- Overlord 接收任务提交请求
- 根据 MiddleManager 的负载情况选择执行节点
- 通过 HTTP 接口将任务描述发送给 MiddleManager
- 状态同步机制 :
- MiddleManager 定期向 Overlord 发送心跳和任务状态更新
- Overlord 监控任务进度,必要时进行重试或重新调度
- 容错处理:当 MiddleManager 失联时,Overlord 会将任务重新分配给其他可用节点
这些协调机制共同确保了 Druid 集群在分布式环境下的可靠运行和数据一致性。
架构演进
初始版本~0.6.0
2012-2013年 
0.7.0~0.12.0
2013年-2018年

集群管理

0.13.0~当前版本

Lambda架构
从大的架构上看,Druid是一个Lambda架构。 Lambda架构是由Storm坐着Nathan Marz提出的一个实时大数据处理框架,Lambda架构设计是为了处理大规模数据时,同时发挥流处理和批处理的优势:
- 通过批处理提供全面、准确的数据
- 通过流处理提供低延迟的数据 从而达到平衡延迟、吞吐量和容错性的目的,为了满足下游的及时查询,批处理和流处理的结果会合并。
Lambda架构包含三层:BatchLayer、SpeedLayer、Serving Layer
- BatchLayer:批处理层,对离线的历史数据进行预计算,为了下游能够快速查询想要的结果,由于批处理基于完成的历史数据集,准确性可以得到保证,批处理层可以用Hadoop、Spark、Flink等框架计算。
- SpeedLayer:加速处理层,处理实时的增量数据,这一层重点在于低延迟,加速层的数据不如批处理层那样完整和准确,但是可以填补批处理高延迟导致的数据空白。加速层可以使用Storm、Spark Streaming和Flink等框架计算。
- ServingLayer:合并层,将历史数据、实时数据合并在一起,输出到数据库或者其他介质,供下游分析

流式数据链路
Raw Data - Kafka - Streaming Processor(Optional 实时ETL)- Kafka(Optional)- Druid - Application/User
批处理数据链路
Raw data - Kafka(Optional) - HDFS - ETL Process(Optional)- Druid - Application/User
错误速查
| 症状 | 根因 | 定位 | 修复 |
|---|---|---|---|
| 查询慢/抖动/热点段 | Segment 过碎、缺 compaction;Broker 合并开销大;缓存命中低 | 查看 Broker/Historical 指标(merge/CPU/缓存命中)、segment 大小与数量 | 启用/优化 compaction,控制 segmentGranularity;调优 Broker 线程与查询并发;开启/优化缓存策略 |
| Segment 无法加载/"丢片" | Deep Storage 读写/权限问题;Coordinator 规则触发 Drop | Coordinator 动作日志、Historical 日志与 Deep Storage ACL | 修正 load/drop 规则与 ACL;重试加载;校验副本与可用空间 |
| 实时摄入堆积 | MiddleManager slot/内存不足;Kafka backlog 增长 | Overlord 任务状态、Peon 日志、Kafka lag | 扩容 MiddleManager/提高 taskSlots 与内存;调小 segment 颗粒度;增加并发/限速 |
| Leader 频繁切换 | ZK 抖动/会话过期 | ZK 日志、会话过期计数、网络抖动排查 | 提高会话超时;稳定 ZK(三/五节点奇数);隔离噪声网络 |
| 查询结果缺失/不一致 | Segment 未发布/未标记可查询;晚到数据未并入 | 元库状态、Coordinator 规则、数据时间窗口 | 校准发布流程;配置 lateMessage 处理与窗口;补跑/重算并 compaction |
| Historical 磁盘打满 | 本地缓存无上限;副本数/保留策略不当 | 磁盘监控、缓存目录与副本策略 | 设定缓存上限与清理策略;收敛副本/保留规则;扩容磁盘/节点 |
| 任务频繁失败/重试 | Peon 内存不足、依赖 JAR/权限问题 | Peon GC/OOM 日志、容器限制、依赖校验 | 上调 Xmx/容器限制;修正依赖与权限;分解大任务,缩短窗口 |
| Broker 502/超时 | 下游节点慢/不可达;聚合超时 | Broker 日志与下游健康检查 | 为慢查询设置专用池/优先级;限流与超时分级;排除故障节点 |
其他系列
🚀 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案例 详解