Article

列式数据库Druid

更新于:2026-07-16

第一章:Druid 概述与核心概念

1.1 什么是 Apache Druid

概念名称说明注意事项
Apache Druid一个开源的、高性能的列式分布式 OLAP 数据库,专为实时分析和低延迟查询设计,支持高并发、亚秒级响应。不适用于事务处理(OLTP)或复杂 JOIN 场景;强调写入后快速可查。
实时分析能力支持从 Kafka、Kinesis 等流式源实时摄入数据,并在秒级内提供查询能力。流式摄入需配置 Supervisor,依赖 MiddleManager 和 Peon 进程。
列式存储数据按列存储,利于压缩和向量化计算,提升聚合查询性能。高基数维度可能导致 Segment 膨胀,需合理建模。
时间序列优先所有数据必须包含时间戳字段(__time),查询围绕时间窗口展开。时间字段不可为空,且必须为 ISO8601 或毫秒时间戳格式。

1.2 Druid 的架构组成

组件名称说明注意事项
Coordinator负责 Segment 的生命周期管理,包括加载、卸载、复制和均衡。依赖 Metadata Storage(如 MySQL/PostgreSQL)和 Deep Storage(如 HDFS/S3)。
Overlord管理数据摄入任务(Ingestion Tasks)的调度与分配。与 MiddleManager 协同工作;可运行在本地模式(local mode)或远程模式。
Broker接收客户端查询请求,路由到 Historical 和 Real-time 节点,并合并结果返回。可启用缓存(Cache)提升重复查询性能;支持 SQL 和原生 JSON 查询。
Historical存储并提供已提交的 Segment 查询服务,数据来自 Deep Storage。启动时从 Deep Storage 加载 Segment;内存映射(MMAP)或堆外内存加载。
MiddleManager负责启动 Peon 任务进程,执行数据摄入(批处理或流式)。每个任务由独立 Peon 进程执行,资源隔离但开销较大。
Router(可选)路由请求到 Broker 或 Coordinator/Overlord 的 UI/API,用于统一入口。非必需组件,适用于多集群或简化客户端配置场景。
Metadata Storage存储 Segment 元数据、任务状态、规则等(通常为关系型数据库)。必须持久化;不存储实际数据,仅元信息。
Deep Storage持久化存储原始 Segment 文件(如 S3、HDFS、本地文件系统)。所有 Historical 节点从此处加载数据;是容灾恢复的关键。

1.3 核心概念解析(DataSource、Segment、Ingestion、Query 等)

概念名称说明注意事项
DataSource类似传统数据库中的”表”,是逻辑数据集合的名称,由多个 Segment 构成。一个 DataSource 可包含不同时间范围的多个 Segment;命名需全局唯一。
Segment数据物理存储单元,按时间分区(如每小时一个 Segment),包含列式数据、索引和元数据。默认最大行数约 500 万;过大影响查询性能,过小增加管理开销。
Ingestion Spec描述如何摄入数据的 JSON 配置,包含 input source、parser、transform、tuning config 等。分为 batch 和 streaming 两类;可通过 POST /druid/indexer/v1/task 提交。
GranularitySpec定义数据的时间粒度(如 HOUR、DAY)和查询 rollup 行为。queryGranularity 控制写入时聚合粒度;segmentGranularity 控制 Segment 切分周期。
Rollup写入时对相同维度+时间桶的数据进行预聚合(如 SUM、COUNT),减少存储和提升查询速度。开启后原始明细丢失;需确保维度组合不会导致高基数爆炸。
Query Types包括 Timeseries、TopN、GroupBy、Scan、Search 等,每种针对特定分析场景优化。GroupBy 功能最全但资源消耗大;TopN 在高基数维度上更高效。
__time特殊时间戳字段,所有数据必须包含,作为主时间维度。必须为 long(毫秒)或 ISO8601 字符串;Druid 自动识别并索引。

1.4 Druid 与其他 OLAP 系统对比(如 ClickHouse、Pinot、Doris)

对比维度Apache DruidClickHouseApache PinotApache Doris
数据模型宽表 + 时间序列,强时间导向宽表,无强制时间字段类似 Druid,支持时间序列宽表,支持主键模型(Unique Key)
实时摄入原生支持 Kafka/Kinesis,秒级可见需通过 MaterializedView 或外部工具原生支持 Kafka/Pulsar支持 Routine Load(Kafka)、Stream Load
查询语言原生 JSON API + SQL(兼容 ANSI)自研 SQL(功能强大)原生 PQL + SQL高度兼容 MySQL 协议和语法
列式存储
预聚合(Rollup)支持写入时 Rollup不支持(需物化视图模拟)支持支持(Aggregate Key 模型)
JOIN 支持有限(仅 lookup join)支持本地字典 JOIN,分布式 JOIN 弱不支持支持 Shuffle Join / Broadcast Join(较新版本)
部署复杂度中高(多组件)低(单进程)中(类似 Druid)中(FE/BE 架构)
适用场景实时监控、用户行为分析、IoT 时序分析日志分析、BI 报表、大规模聚合实时仪表盘、低延迟查询统一 OLAP、替代 Hive + MySQL 场景

第二章:Druid 安装与部署

2.1 单机快速启动(micro-quickstart)

步骤名称操作细节注意事项
下载 Druid 发行包从官网 https://druid.apache.org/downloads.html 下载最新 tar.gz 包(如 apache-druid-26.0.0-bin.tar.gz推荐使用稳定版本;需 JDK 8/11/17
解压并进入目录tar -xzf apache-druid-*.tar.gz && cd apache-druid-*确保磁盘有至少 4GB 可用空间
启动 micro-quickstart执行 bin/start-micro-quickstart该脚本自动启动所有必要服务(Coordinator、Overlord、Broker、Historical、MiddleManager、Router)
验证服务状态访问 http://localhost:8888(Web Console)或检查日志 var/sv/*.log首次启动可能需 30~60 秒;确保 8081、8082、8083 等端口未被占用
停止服务在启动终端按 Ctrl+C,或执行 bin/stop-micro-quickstart强制 kill 可能导致临时文件残留

2.2 分布式集群部署(基于 Docker / Kubernetes / 原生部署)

部署方式操作细节注意事项
Docker Compose 部署使用官方 docker-compose.yml(位于 distribution/docker/)执行 docker-compose up -d仅用于开发测试;不适用于生产;需预先配置 metadata DB 和 deep storage
Kubernetes Helm 部署使用社区 Helm Chart(如 https://github.com/apache/druid/tree/master/distribution/k8s)执行 helm install druid ./chart需提前创建 PVC、ConfigMap、Secret;建议启用 StatefulSet 管理 Historical 节点
原生分布式部署在多台机器上分别启动各角色服务:Coordinator+Overlord(主节点)、Broker(查询节点)、Historical(存储节点)、MiddleManager(摄入节点)所有节点需共享同一 common.runtime.properties;依赖外部 ZooKeeper、Metadata DB、Deep Storage
共享依赖配置ZooKeeper:用于服务发现;Metadata DB:MySQL/PostgreSQL;Deep Storage:S3/HDFS/本地 NFS必须确保网络互通;ZooKeeper 集群建议 3 节点;Metadata DB 需建表(运行 extensions-core/mysql-metadata-storage 中的 DDL)

2.3 配置文件详解(common.runtime.properties、jvm.config 等)

配置文件关键参数用途说明注意事项
conf/druid/single-server/micro-quickstart/_common/common.runtime.propertiesdruid.zk.service.host=localhostdruid.metadata.storage.connector.connectURI=jdbc:derby://...druid.storage.type=localdruid.extensions.loadList=["druid-hdfs-storage", "mysql-metadata-storage"]定义 ZooKeeper 地址、元数据存储、Deep Storage 类型、扩展插件生产环境必须替换 Derby 为 MySQL/PostgreSQL;local storage 仅用于单机
conf/druid/*/runtime.propertiesdruid.server.http.numThreads=30druid.processing.numThreads=2控制 HTTP 线程池和查询处理线程数根据 CPU 核心数调整;避免过度分配
jvm.config-server-Xms4g-Xmx4g-XX:MaxDirectMemorySize=6gJVM 启动参数,控制堆内存和堆外内存Historical 节点需较大 DirectMemory;MiddleManager 每个 Peon 有独立 jvm.config
log4j2.xml<Configuration><Appenders><File name="fileAppender">...</File></Appenders></Configuration>日志输出格式与路径默认日志位于 var/sv/*.log;可配置滚动策略避免磁盘占满

2.4 启动与停止服务的命令行操作

操作名称命令示例说明注意事项
启动单个服务(原生部署)java -cp "conf/druid/coordinator:/lib/*" org.apache.druid.cli.Main server coordinator手动启动 Coordinator 服务需先设置 CLASSPATH;建议使用 bin/run-druid.sh 封装脚本
使用 run-druid.sh 启动bin/run-druid.sh coordinator conf/druid/coordinator官方推荐方式,自动加载 jvm.config 和 classpath脚本位于 bin/ 目录;需赋予执行权限
停止单个进程kill -TERM <pid>pkill -f "Main server coordinator"平滑终止服务避免使用 kill -9,可能导致 Segment 状态不一致
查看运行服务ps aux | grep druidjps -l | grep Main检查各角色是否运行
重启服务先 stop,再 start;或使用 systemd(若配置)适用于配置变更后生效修改 common.runtime.properties 后通常需全集群重启
查看端口占用netstat -tuln | grep :8081验证服务监听状态默认端口:Coordinator: 8081、Overlord: 8090、Broker: 8082、Historical: 8083、MiddleManager: 8091

第三章:数据摄入(Ingestion)

3.1 数据摄入方式概览(本地文件、Kafka、HDFS、S3 等)

摄入源类型支持方式说明注意事项
本地文件(Local File)Batch Ingestion通过 local input source 读取本地 JSON/CSV 文件仅适用于单机或所有 MiddleManager 节点可访问该路径;不适用于分布式集群生产环境
KafkaStreaming Ingestion使用 kafka input source + Supervisor 实现实时摄入需启用 Kafka Indexing Service;支持 Exactly-Once 语义(需配置 transactional.id
HDFSBatch Ingestion通过 hdfs input source 读取 HDFS 上的文件需加载 druid-hdfs-storage 扩展;确保所有节点有 Hadoop 配置(core-site.xml 等)
Amazon S3Batch / Streaming使用 s3 input source(Batch)或从 S3 读取 Checkpoint(Streaming)需配置 AWS 凭据(accessKey/secretKey 或 IAM Role);加载 druid-s3-extensions
HTTPBatch Ingestion通过 http input source 从 URL 下载文件适用于临时调试;不推荐用于大文件或高频率摄入
KinesisStreaming Ingestion类似 Kafka,使用 kinesis input source需加载 druid-kinesis-indexing-service 扩展;依赖 AWS SDK

3.2 批量摄入(Batch Ingestion)命令行操作

操作名称命令/步骤说明注意事项
准备摄入规范(ingestion spec)编写 JSON 文件(如 wikiticker-index.json),包含 type: "index_parallel""index"定义 inputSource、inputFormat、dimensionsSpec、metricsSpec、granularitySpec 等使用 index_parallel 可并行处理;index 为单线程(仅 micro-quickstart)
提交批量任务curl -X POST -H "Content-Type: application/json" --data-binary @wikiticker-index.json http://localhost:8090/druid/indexer/v1/task向 Overlord 提交任务确保 Overlord 正在运行(默认端口 8090)
本地文件示例 inputSource"inputSource": { "type": "local", "baseDir": "quickstart/tutorial/", "filter": "wikiticker-2015-09-12-sampled.json.gz" }读取本地目录下的文件文件路径相对于 MiddleManager 工作目录;压缩格式(.gz/.zip)自动解压
HDFS 示例 inputSource"inputSource": { "type": "hdfs", "uris": ["hdfs://namenode:9000/data/wikiticker.json"] }从 HDFS 读取需在 common.runtime.properties 中启用 druid.extensions.loadList += "druid-hdfs-storage"
验证数据是否加载查询 DataSource 列表:curl http://localhost:8082/druid/v2/datasources检查新 DataSource 是否出现数据通常在任务成功后 1~2 分钟内可查

3.3 流式摄入(Streaming Ingestion)配置与管理

配置项语法/值用途注意事项
Supervisor Spec 类型"type": "kafka""type": "kinesis"定义流式数据源必须部署对应扩展(如 druid-kafka-indexing-service
topic / stream 名称"topic": "my-topic"(Kafka)"stream": "my-stream"(Kinesis)指定数据流Kafka 需提前创建 topic;Kinesis 需存在 stream
Task Count 与 Replicas"taskCount": 2, "replicas": 1控制并行消费者数量taskCount 决定分区分配数;replicas 用于高可用(>=2)
Start Offset"useEarliestOffset": true"specificOffsets": {"0": 1000}控制消费起始位置首次启动建议设为 useEarliestOffset: true
提交 Supervisorcurl -X POST -H "Content-Type: application/json" --data-binary @supervisor-spec.json http://localhost:8090/druid/indexer/v1/supervisor启动流式摄入成功返回 Supervisor ID
停止 Supervisorcurl -X POST http://localhost:8090/druid/indexer/v1/supervisor/<supervisor_id>/shutdown停止并清理任务会终止所有关联的 indexing task
查看 Supervisor 状态curl http://localhost:8090/druid/indexer/v1/supervisor?full获取详细状态(包括 lag、task 状态)lag 字段反映消费延迟

3.4 摄入任务提交与状态查询(使用 curl / CLI)

操作名称命令示例用途注意事项
提交任意 ingestion taskcurl -X POST -H "Content-Type: application/json" --data-binary @task.json http://<OVERLORD_HOST>:8090/druid/indexer/v1/task通用任务提交接口task.json 中 type 决定任务类型(index、index_parallel、kafka 等)
查询所有任务列表curl http://<OVERLORD_HOST>:8090/druid/indexer/v1/tasks查看当前运行/完成的任务返回 JSON 数组,含 id、type、status、dataSource 等字段
查询特定任务状态curl http://<OVERLORD_HOST>:8090/druid/indexer/v1/task/<task_id>/status获取任务状态(RUNNING/SUCCESS/FAILED)可用于自动化脚本判断任务结果
取消运行中任务curl -X POST http://<OVERLORD_HOST>:8090/druid/indexer/v1/task/<task_id>/shutdown终止任务仅对 RUNNING 状态有效;已提交的 Segment 不会回滚
查看任务日志curl http://<MIDDLEMANAGER_HOST>:8091/druid/worker/v1/chat/<task_id>/log获取 Peon 进程日志需知道任务所在 MiddleManager 地址;日志也可在 var/task/ 目录查看
重试失败任务重新提交相同的 task spec(或修改后)手动恢复失败摄入建议先分析失败原因(如 schema mismatch、网络超时)

第四章:数据查询(Query)

4.1 查询类型介绍(Timeseries、TopN、GroupBy、Scan、Search)

查询类型语法结构要点用途注意事项
Timeseries必须包含 "queryType": "timeseries""granularity"(如 "hour")、"aggregations"按时间粒度聚合指标(如每小时总点击量)不支持维度分组;仅返回时间桶 + 聚合值;性能最优
TopN"queryType": "topN""dimension"(排序维度)、"threshold"(返回前 N)、"metric"(排序依据)获取某维度下指标最高的 Top N 记录(如热门商品)仅支持单维度排序;比 GroupBy 更高效(尤其高基数场景)
GroupBy"queryType": "groupBy""dimensions"(数组)、"limitSpec"(可选)多维分组聚合(类似 SQL GROUP BY)资源消耗大;结果集大时需配置 maxResults;支持 post-aggregations
Scan"queryType": "scan""columns"(可选字段列表)、"batchSize"扫描原始数据(类似 SELECT *)不做聚合;用于数据导出或调试;性能较差,避免高并发使用
Search"queryType": "search""searchDimensions""query"(含 "type": "insensitive_contains" 等)在维度值中模糊搜索(如查找包含 “admin” 的用户)仅适用于低基数维度;不支持指标字段;已标记为 deprecated(推荐用 SQL 替代)

4.2 使用 HTTP API 发起查询(curl 示例)

查询类型curl 命令示例说明注意事项
Timeseriescurl -X POST http://localhost:8082/druid/v2/ -H "Content-Type: application/json" --data-binary '{"queryType":"timeseries","dataSource":"wikiticker","intervals":["2015-09-12/2015-09-13"],"granularity":"hour","aggregations":[{"type":"count","name":"rows"},{"type":"longSum","name":"added","fieldName":"added"}]}'每小时统计行数和 added 总和intervals 必须指定;时间格式为 ISO8601
TopNcurl -X POST http://localhost:8082/druid/v2/ -H "Content-Type: application/json" --data-binary '{"queryType":"topN","dataSource":"wikiticker","intervals":["2015-09-12/2015-09-13"],"dimension":"channel","threshold":5,"metric":"edits","aggregations":[{"type":"longSum","name":"edits","fieldName":"count"}],"granularity":"all"}'获取编辑次数最多的前 5 个 channelmetric 可为聚合字段名或预定义排序规则
GroupBycurl -X POST http://localhost:8082/druid/v2/ -H "Content-Type: application/json" --data-binary '{"queryType":"groupBy","dataSource":"wikiticker","intervals":["2015-09-12/2015-09-13"],"dimensions":["countryName","regionName"],"aggregations":[{"type":"count","name":"rows"}],"granularity":"all"}'按国家和地区分组统计行数结果可能很大,建议加 limitSpec 控制返回数量
Scancurl -X POST http://localhost:8082/druid/v2/ -H "Content-Type: application/json" --data-binary '{"queryType":"scan","dataSource":"wikiticker","intervals":["2015-09-12/2015-09-13"],"columns":["__time","channel","cityName"],"resultFormat":"compactedList","batchSize":10000}'导出指定字段的原始数据batchSize 控制每批返回行数;避免全表扫描生产环境
SQL 查询curl -X POST http://localhost:8082/druid/v2/sql/ -H "Content-Type: application/json" --data-binary '{"query":"SELECT channel, COUNT(*) AS cnt FROM wikiticker WHERE __time >= ''2015-09-12'' GROUP BY channel ORDER BY cnt DESC LIMIT 5"}'使用 SQL 语法查询需 Broker 启用 SQL 支持(默认开启);字符串需转义单引号

4.3 使用 druid-cli 或其他命令行工具执行查询

工具名称使用方式说明注意事项
druid sql CLIbin/druid.sh sql --host localhost:8082(进入交互模式后输入 SQL)官方提供的 SQL 命令行客户端需 Druid 0.16+;依赖 Java;自动处理连接和结果格式化
直接调用 Avatica JDBC(通过 sqlline)./sqlline,然后 !connect jdbc:avatica:remote:url=http://localhost:8082/druid/v2/sql/avatica/利用 Apache Calcite Avatica 协议需下载 sqlline 和 avatica driver;适用于 JDBC 兼容工具链
自定义脚本(bash + curl)编写 shell 脚本封装 curl 命令,传入参数动态生成 JSON适用于自动化监控或 ETL 流程需处理 JSON 转义(可用 jq 工具辅助构造 payload)
使用 dsql(社区工具)dsql --broker http://localhost:8082 "SELECT COUNT(*) FROM wikiticker"第三方轻量 CLI(非官方)需单独安装;简化 SQL 调用,但功能有限

4.4 查询性能调优参数说明

参数名称所在配置文件/位置作用注意事项
druid.processing.numThreadsruntime.properties(各节点)控制每个节点用于查询处理的线程数建议设为 CPU 核心数 -1;过高导致上下文切换开销
druid.processing.buffer.sizeBytesruntime.properties单个处理缓冲区大小(默认 500MB)大查询(如 GroupBy)需增大;受 DirectMemory 限制
druid.query.groupBy.maxResultscommon.runtime.propertiesGroupBy 查询最大返回行数(默认 500,000)超限会报错;可根据内存调整,但避免过大
druid.broker.cache.useCache / druid.broker.cache.populateCachebroker/runtime.properties启用/写入查询结果缓存需配置 cache.type(如 local、memcached);对重复查询有效
druid.historical.cache.useCachehistorical/runtime.propertiesHistorical 节点启用缓存与 Broker 缓存协同工作;减少重复计算
druid.sql.planner.maxSubqueryRowscommon.runtime.propertiesSQL 子查询最大行数限制防止爆炸性中间结果;默认 100,000
query context 参数(运行时)在查询 JSON 中添加 "context": {"priority": 10, "timeout": 30000}动态控制单次查询行为timeout 单位毫秒;priority 影响调度顺序(高优先级先执行)

第五章:命令行工具与运维操作

5.1 常用 CLI 工具介绍(druid.sh、indexer.sh、router.sh 等)

工具名称调用方式功能说明注意事项
druid.shbin/druid.sh <role> <config_dir>,例如:bin/druid.sh coordinator conf/druid/coordinator启动任意 Druid 角色服务(coordinator、overlord、broker 等)run-druid.sh 的封装;自动加载 jvm.config 和 classpath;推荐用于开发调试
indexer.shbin/indexer.sh --configFile conf/druid/middleManager/runtime.properties --task task.json本地运行 ingestion task(无需 Overlord)仅用于测试 ingestion spec;不适用于生产流式摄入
router.shbin/router.sh conf/druid/router启动 Router 服务,统一 API 入口非必需组件;适用于多集群路由或简化客户端配置
query.shbin/query.sh --url http://localhost:8082 --query @query.json执行原生 JSON 查询(实验性工具)官方未正式维护;建议优先使用 curl 或 SQL CLI
sql.shbin/sql.sh --host localhost:8082启动交互式 SQL CLI(Druid 0.20+ 内置)支持历史命令、自动补全;等价于 druid sql 子命令

5.2 Segment 管理(加载、卸载、删除、复制)

操作名称命令/HTTP 请求示例说明注意事项
手动加载 Segmentcurl -X POST "http://<COORDINATOR>:8081/druid/coordinator/v1/datasources/<DATASOURCE>/segments/<SEGMENT_ID>/load"强制 Historical 加载指定 SegmentSegment 必须已存在于 Deep Storage;通常由 Coordinator 自动管理
卸载 Segmentcurl -X DELETE "http://<COORDINATOR>:8081/druid/coordinator/v1/datasources/<DATASOURCE>/segments/<SEGMENT_ID>"从集群中卸载 Segment(内存释放)数据仍保留在 Deep Storage;可重新加载
删除 Segment(彻底)curl -X DELETE "http://<COORDINATOR>:8081/druid/coordinator/v1/datasources/<DATASOURCE>/segments?kill=true"(或针对单个:curl -X DELETE ".../<SEGMENT_ID>?kill=true"从 Metadata Storage 和 Deep Storage 中永久删除危险操作;确保无查询依赖;需 Coordinator 配置 druid.coordinator.kill.on 相关参数启用
复制 Segment(增加副本)在 Coordinator UI 或通过规则(Rule)配置:{"type": "loadForever", "tieredReplicants": {"_default_tier": 2}}提高可用性或查询吞吐通过 Rule 管理,非直接命令;副本数由 tieredReplicants 控制
查看所有 Segmentscurl http://<COORDINATOR>:8081/druid/coordinator/v1/datasources/<DATASOURCE>/segments列出 DataSource 下所有 Segment 元数据返回包含 ID、大小、时间范围、副本状态等信息

5.3 任务管理(查看、取消、重试 ingestion 任务)

操作名称命令/HTTP 请求示例说明注意事项
查看所有任务curl http://<OVERLORD>:8090/druid/indexer/v1/tasks列出当前系统中所有 ingestion 任务(运行中/已完成)返回 JSON 数组,含 id、type、status、dataSource、runnerStatus 等
查看特定任务详情curl http://<OVERLORD>:8090/druid/indexer/v1/task/<TASK_ID>获取任务完整 spec 和状态可用于审计或调试失败原因
取消运行中任务curl -X POST http://<OVERLORD>:8090/druid/indexer/v1/task/<TASK_ID>/shutdown终止正在运行的任务仅对 RUNNING 状态有效;已写入的 Segment 不会回滚
重试失败任务重新提交原始 task spec(或修正后):curl -X POST ... --data-binary @fixed-task.json ...手动恢复失败摄入建议先检查日志定位失败原因(如 schema mismatch、网络超时)
查看任务日志(远程)curl http://<MIDDLEMANAGER_HOST>:8091/druid/worker/v1/chat/<TASK_ID>/log获取 Peon 进程的标准输出日志需知道任务所在 MiddleManager 地址;也可在 var/task/<TASK_ID>/log 查看本地文件
清理已完成任务记录curl -X DELETE http://<OVERLORD>:8090/druid/indexer/v1/tasks?state=SUCCESS&olderThan=PT24H删除 24 小时前的成功任务元数据减少 Metadata Storage 负担;不影响实际数据

5.4 监控与日志查看(通过命令行定位问题)

操作名称命令示例说明注意事项
查看服务日志tail -f var/sv/coordinator.loggrep "ERROR" var/sv/broker.log实时跟踪或过滤错误日志日志路径为 var/sv/<service>.log;也可按日期滚动(如 .log.2026-02-01
查看任务日志cat var/task/index_parallel_xxx/log检查 ingestion 任务执行细节每个任务独立目录;包含 stdout、stderr 和 taskStatus.json
检查 JVM 状态jstat -gc <PID>jstack <PID> > thread_dump.txt分析 GC 压力或线程阻塞需安装 JDK 工具;Historical 节点常因 DirectMemory 不足 OOM
查看端口监听netstat -tuln | grep :8082验证 Broker 是否正常监听默认端口:Coordinator: 8081、Overlord: 8090、Broker: 8082、Historical: 8083
检查磁盘使用du -sh var/df -h监控 Segment 缓存和日志占用Historical 节点的 var/druid/segment-cache 可能快速增长
使用 status APIcurl http://<BROKER>:8082/statuscurl http://<COORDINATOR>:8081/druid/coordinator/v1/leader获取服务健康状态和角色信息status API 返回版本、内存、模块等基本信息
检查 ZooKeeper 注册echo dump | nc localhost 2181 | grep druid验证各服务是否成功注册到 ZK需安装 netcat;路径通常为 /druid/discovery

第六章:安全与权限控制(可选)

6.1 启用基本认证(Basic Auth)

操作名称配置步骤 / 参数说明注意事项
启用 druid-basic-security 扩展common.runtime.properties 中添加:druid.extensions.loadList=["druid-basic-security", ...]加载基础安全模块必须在所有节点(Coordinator、Broker 等)统一配置
配置用户凭证conf/druid/*/basic-security.json 中定义:{ "users": { "admin": { "password": "secret", "roles": ["admin"] } } }声明用户名、密码(明文或 SHA256)、角色密码建议使用 SHA256(如 echo -n "secret" | sha256sum);文件需对 Druid 进程可读
启用认证过滤器在各服务 runtime.properties 中添加:druid.auth.authenticatorChain=["MyBasicAuthenticator"]druid.auth.basic.passwordValidator.type=sha256指定认证器链和密码校验方式authenticator 名称(如 MyBasicAuthenticator)需与配置文件中一致
为 Coordinator/Overlord 启用coordinator/runtime.properties 添加:druid.auth.authorizer.type=basic启用基于角色的授权需配合 authorizer 配置(见 6.3 节)
测试认证curl -u admin:secret http://localhost:8081/druid/coordinator/v1/datasources验证是否返回数据而非 401若未授权,返回 HTTP 401 Unauthorized

6.2 配置 TLS/SSL

操作名称配置步骤 / 参数说明注意事项
生成 Keystore(自签名)keytool -genkeypair -alias druid -keyalg RSA -keystore druid.keystore.jks -storepass changeit创建服务器证书存储用于 HTTPS 服务端;生产环境应使用 CA 签发证书
配置 Broker 启用 HTTPSbroker/runtime.properties 添加:druid.server.https.port=8282druid.server.https.keyStorePath=/path/to/druid.keystore.jksdruid.server.https.keyStorePassword=changeit启用 HTTPS 监听HTTP 仍可同时启用;建议禁用 HTTP(设 druid.server.http.port=-1
配置客户端信任(如 Overlord 访问 Broker)在调用方(如 Overlord)配置:druid.client.https.trustStorePath=/path/to/truststore.jksdruid.client.https.trustStorePassword=changeit使内部服务间通信支持 TLS若使用自签名证书,需将公钥导入 truststore:keytool -importcert -file druid.crt -keystore truststore.jks
启用 ZooKeeper SSL(可选)common.runtime.properties 设置 druid.zk.service.host=zookeeper1:2181,zookeeper2:2181 并配置 JVM 参数:-Dzookeeper.client.secure=true -Dzookeeper.ssl.trustStore.location=...加密 ZK 通信需 ZooKeeper 3.5+ 支持 TLS
强制重定向 HTTP → HTTPS(Router)在 Router 配置中启用:druid.router.http.redirectToHttps=true自动升级连接仅当 Router 同时监听 HTTP/HTTPS 时生效

6.3 基于角色的访问控制(RBAC)配置

配置项配置位置与语法用途注意事项
定义角色权限basic-security.json 的 authorizers 部分配置,资源类型包括 DATASOURCE、CONFIG、STATE、SERVICE控制角色对资源的操作权限示例:{"resource": {"type": "DATASOURCE", "name": "sales"}, "action": "READ"}
绑定用户到角色basic-security.json 的 users 部分:"admin": { "password": "...", "roles": ["MyRole"] }用户继承角色权限一个用户可拥有多个角色
启用 Authorizer在各服务 runtime.properties 添加:druid.auth.authorizer.type=basicdruid.auth.basic.authorizer.name=MyAuthorizer激活 RBAC 授权检查必须与 basic-security.json 中的 authorizer 名称一致
权限粒度说明DATASOURCE: 控制查询/写入特定 DataSource、CONFIG: 控制修改 ingestion spec/rules 等、STATE: 控制查看集群状态(如 segments/tasks)、SERVICE: 控制访问 Coordinator/Overlord API精细化权限管理action 取值:READ、WRITE、ALL
验证权限curl -u analyst:pass -X POST http://localhost:8090/druid/indexer/v1/task --data-binary @task.json测试是否拒绝无权限操作若用户无 CONFIG WRITE 权限,将返回 403 Forbidden

第七章:性能调优与最佳实践

7.1 数据模型设计建议(维度 vs 指标、Rollup 优化)

概念/策略说明注意事项
维度(Dimensions)用于过滤、分组的字符串或低基数字段(如 country、status)避免将高基数字段(如 user_id、trace_id)设为维度,否则导致 Bitmap 和字典膨胀,显著增加内存和磁盘占用
指标(Metrics)用于聚合计算的数值字段(如 count、sum、max)支持 longSum、doubleSum、hyperUnique、thetaSketch 等;预聚合可大幅提升查询性能
启用 Rollup在 ingestion spec 中设置 "rollup": true,对相同时间桶+维度组合的数据进行写入时聚合开启后原始明细数据丢失;适用于监控、日志汇总等场景;不适用于需保留每条事件的分析
时间粒度选择queryGranularity 控制写入聚合粒度(如 "minute"),segmentGranularity 控制 Segment 切分周期(如 "HOUR"更粗的 queryGranularity 提升压缩率但损失精度;segmentGranularity 过小导致 Segment 数量爆炸
使用 Sketch 近似去重对高基数去重使用 thetaSketch 或 hyperUnique 而非 exact count distinct显著降低存储和计算开销;误差可控(通常 <2%);需加载对应扩展(如 datasketches extension)

7.2 Segment 大小与分区策略

策略项推荐配置说明注意事项
单个 Segment 行数300 万 ~ 700 万行平衡查询性能与管理开销;过小导致任务碎片化,过大影响 Historical 加载速度和内存使用
Segment 文件大小300 MB ~ 700 MB(压缩后)可通过 tuningConfig.maxRowsPerSegmentmaxTotalRows 控制实际大小受列数、基数、压缩算法影响;建议监控生产环境实际值
分区类型(Partitioning)批处理推荐 hashedsingle_dim;流式使用 dynamichashed 均匀分布;single_dim 按某维度(如 tenant_id)分片,利于局部查询流式摄入默认 dynamic partitioning,自动控制 Segment 大小
时间切分粒度根据数据量选择:小数据量 DAY、中等 HOUR、高吞吐 FIVE_MINUTEsegmentGranularity 控制过细(如 MINUTE)导致元数据压力大;过粗(如 MONTH)影响查询裁剪效率
避免小文件问题设置 tuningConfig.maxRowsInMemory ≥ 500,000;启用 forceGuaranteedRollup=true(批处理)减少生成大量微小 Segment小 Segment 会显著增加 Coordinator 和 Historical 负担

7.3 历史节点与 MiddleManager 资源调优

组件关键参数推荐值 / 说明注意事项
Historical 节点druid.processing.numThreadsCPU 核心数 - 1控制并行查询线程;过高导致上下文切换
druid.processing.buffer.sizeBytes536870912(500MB)或更高单个缓冲区大小;大 GroupBy 查询需增大
druid.server.maxSize总内存的 70%(如 30GB)控制 Segment 缓存上限;超过则触发淘汰
druid.segmentCache.locations指向高速 SSD 目录加速 Segment 加载;避免使用机械盘
MiddleManagerdruid.worker.capacityCPU 核心数 / 2(如 4)控制并发 Peon 任务数;每个任务独占资源
druid.indexer.runner.javaOptsArray["-Xmx4g", "-XX:MaxDirectMemorySize=6g"]单个 Peon 的 JVM 配置
druid.indexer.task.baseTaskDir指向大容量磁盘存放中间文件;摄入期间可能临时占用数倍原始数据空间
共同注意所有节点需配置足够堆外内存(-XX:MaxDirectMemorySize建议 ≥ numThreads × bufferSize不足会导致 OOM 或性能骤降

7.4 查询缓存与 Broker 配置优化

优化项配置参数说明注意事项
启用本地缓存broker/runtime.properties 设置:druid.broker.cache.useCache=truedruid.broker.cache.populateCache=truedruid.cache.type=local缓存查询结果(基于查询 JSON 哈希)仅对确定性查询有效(无 NOW()、RANDOM());缓存命中返回更快
缓存大小控制druid.cache.sizeInBytes=2147483648(2GB)限制本地缓存最大内存过大会挤占查询处理内存;建议 ≤ 20% 堆内存
使用分布式缓存配置 druid.cache.type=memcached 并设置 druid.cache.memcached.hosts=localhost:11211多 Broker 共享缓存需部署 Memcached 集群;网络延迟可能抵消收益
Broker 查询队列druid.broker.http.numConnections=20druid.broker.http.maxQueuedBytes=104857600控制下游连接和排队防止突发查询压垮 Historical
查询超时与优先级在查询 context 中设置:"context": {"timeout": 60000, "priority": 5}动态控制单次查询行为timeout 单位毫秒;priority 越高越优先调度(默认 0)
结果合并优化druid.broker.merge.useParallelMerge=true并行合并多节点结果适用于宽表或大结果集;需足够 CPU 资源
禁用昂贵操作druid.sql.planner.metadataQueryMaxBytesPerDimension=100000限制 metadata 查询开销防止 SELECT * FROM INFORMATION_SCHEMA 导致 OOM

第八章:集成与生态

8.1 与 Superset / Grafana 集成

集成工具配置步骤 / 连接参数说明注意事项
Apache Superset1. 在 Superset 中添加 Database;2. SQLAlchemy URI 填写:druid://<BROKER_HOST>:8082/druid/v2/sql/;3. 测试连接使用内置 Druid SQLAlchemy 方言需 Superset ≥ 1.0;Druid 必须启用 SQL(默认开启);不支持所有 SQL 功能(如 JOIN 有限)
Grafana1. 安装 druid-plugin;2. 添加 Data Source → URL: http://<BROKER_HOST>:8082;3. 支持原生 JSON 查询或 SQL支持时间序列面板(Timeseries、Bar gauge)插件需手动安装;SQL 模式更易用;不支持复杂 GroupBy 可视化
连接验证在 Superset 执行:SELECT __time, COUNT(*) FROM wikiticker GROUP BY TIME_FLOOR(__time, 'PT1H');在 Grafana 使用 Explore 输入相同 SQL验证时间序列查询是否返回数据时间字段必须为 __time;Grafana 要求结果含时间列和数值列
认证配置(如启用 Basic Auth)Superset URI 示例:druid://admin:secret@broker:8082/druid/v2/sql/;Grafana 在 Data Source 设置中填写用户名/密码传递凭证到 Druid Broker明文密码存在风险;生产环境建议配合 TLS
集成系统集成方式配置要点注意事项
Apache Flink使用 Flink SQL + Druid Sink 或自定义 RichSinkFunction 发送 JSON 到 Kafka(由 Druid 消费)推荐路径:Flink → Kafka → Druid(流式摄入)官方无原生 Flink Sink;直写可靠性低;Kafka 中间层提供缓冲和重试
Apache Spark使用批处理写入 HDFS/S3,再由 Druid 批量摄入;或通过 spark-druid-connector(社区项目)示例:df.write.format("druid").option("druid.overlord.url", "http://overlord:8090")...官方不维护 Spark Connector;生产推荐”Spark → Parquet → Druid Batch Ingestion”链路
Kafka Connect使用 Druid Kafka Indexing Service(非 Connect)或第三方 Sink Connector(如 Landoop/kafka-connect-druid)官方方案:Druid Supervisor 直接消费 Kafka,无需 Connect不推荐通过 Kafka Connect 写 Druid;Supervisor 更高效、Exactly-Once 支持更好
数据格式要求所有上游系统输出需为 JSON 或 CSV,含 __time 字段时间字段示例:{"__time": "2026-02-01T12:00:00Z", "user": "alice", "count": 1}时间格式必须为 ISO8601 或毫秒时间戳;Druid 不做 ETL 转换

8.3 使用 SQL 查询 Druid(通过 Avatica 或内置 SQL)

查询方式连接方法 / 示例说明注意事项
内置 HTTP SQL APIcurl -X POST http://<BROKER>:8082/druid/v2/sql/ -H "Content-Type: application/json" --data-binary '{"query":"SELECT channel, SUM(added) FROM wikiticker WHERE __time >= '\''2015-09-12'\'' GROUP BY channel LIMIT 5"}'最简 SQL 调用方式字符串需转义单引号(''\'');支持 EXPLAIN 查看逻辑计划
JDBC via AvaticaJDBC URL:jdbc:avatica:remote:url=http://<BROKER>:8082/druid/v2/sql/avatica/,Driver: org.apache.calcite.avatica.remote.Driver兼容标准 JDBC 应用(如 DBeaver、Tableau)需添加 avatica-client 依赖;连接池建议设置 keep-alive
SQL 功能限制不支持跨 DataSource JOIN、子查询有限(maxSubqueryRows 控制)、不支持窗口函数(如 ROW_NUMBER)功能对标 ANSI SQL-92 + 部分扩展复杂分析建议预聚合或导出到 Spark
启用/验证 SQL默认已启用;检查 Broker 日志含:SqlLifecycleFactory initialized无需额外配置(除非显式关闭)可通过 druid.sql.enable=true 强制开启(common.runtime.properties
查询上下文传递在 SQL 请求中附加 context:{ "query": "...", "context": {"priority": 10, "timeout": 30000} }控制单次查询行为支持 timeout、priority、useCache 等参数