Apache Druid 数据摄入排障实战指南从事件丢失到 Segment 交接的完整排查手册【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址: https://gitcode.com/gh_mirrors/druid7/druid本指南基于 Apache Druid 仓库的官方摄入 FAQdocs/content/ingestion/faq.md整理而成围绕数据摄入ingestion全链路中最常见的高频问题展开实时摄入事件被拒、批量摄入零事件、事件丢失、Segment 落盘位置、流式摄入不交接、HDFS 深度存储配置、Historical 节点无 Segment、查询返回空结果以及如何通过重新索引reindex完成 Schema 变更与粒度调整。读完本文你将掌握一套可复现的排查命令、关键配置参数和底层原理含源码级证据能够独立定位并解决 Druid 摄入链路上的绝大多数故障。一、Druid 摄入的两条主路径与排障总览在进入具体问题之前先明确 Druid 数据摄入的两条主路径因为几乎所有 FAQ 问题都围绕它们展开实时摄入Realtime Ingestion事件以流如 Kafka、HTTP push 或 pull方式进入 Realtime 节点或索引服务任务先经过内存缓冲in-memory buffer与中间持久化intermediate persist最终在 Segment 交接handoff时交给 Historical 节点加载并提供查询。批量摄入Batch Ingestion通过 Index Task本地或 Hadoop 任务index_hadoop从静态文件、已有 SegmentIngestSegmentFirehose或dataSourceinputSpec中读取数据直接产出 Segment 写入深度存储Deep Storage。两条路径的公共失败模式都可以从三处获取证据摄入进程日志、摄入指标ingest 系列 metrics与Coordinator 控制台。下表是本 FAQ 涉及问题与排查入口的速查问题现象首选排查入口对应章节实时摄入无事件 / 事件被丢弃日志中ingest/events/*指标第二节批量摄入零事件检查 ingestion spec 的intervals是否覆盖数据时间范围第二节部分事件未摄入ingest/events/thrownAway、ingest/events/unparseable指标第三节Segment 上传到哪druid.storage.type配置第四节流式摄入不交接元数据存储、Historical 容量、深度存储配置第五节Historical 上无 SegmentCoordinator 控制台 容量配置第八节查询返回空结果Segment Metadata Query 聚合器名 查询区间第九节需要改 Schema / 粒度IngestSegmentFirehose 或 HadoopdataSourceinputSpec第十、十一节实时摄入卡住检查 persist / handoff 是否超时、列构建耗时第十二节二、数据没有被加载My Data isnt being loaded2.1 实时摄入windowPeriod之外的乱序事件被拒绝实时摄入最常见的失败原因是事件时间落在 Druid 配置的windowPeriod之外。Druid 实时摄入只接受“距离当前时间在可配置窗口内”的事件——这一机制用于防止乱序out-of-order或过期事件无限期占用内存。从源码可以确认该行为的具体实现。RealtimeTuningConfig.java 定义了默认配置private static final int defaultMaxRowsInMemory 75000; private static final Period defaultIntermediatePersistPeriod new Period(PT10M); private static final Period defaultWindowPeriod new Period(PT10M);即默认windowPeriod为 10 分钟在 tuningConfig 中通过windowPeriod: PT10M覆盖。而实际拒绝判定逻辑位于 MessageTimeRejectionPolicyFactory.javaOverride public boolean accept(long timestamp) { long maxTimestamp this.maxTimestamp; if (timestamp maxTimestamp) { maxTimestamp tryUpdateMaxTimestamp(timestamp); } return timestamp (maxTimestamp - windowMillis); }从代码可以推断该策略以已见到的最大事件时间为基准只接受落在maxTimestamp - windowMillis之后的事件更早的事件一律拒绝。这正是“迟到事件被丢弃”的根源。如何确认查看实时进程日志中带有ingest/events/*的行这些指标会告诉你事件的 ingested已摄入、rejected被拒等情况。如果被拒事件大量存在说明你的数据带时间戳与当前系统时间偏离过大或需要调大windowPeriod。生产建议官方明确推荐历史数据请使用批量摄入方式batch ingestion不要走实时摄入——实时摄入的窗口机制天然不适合回填历史。2.2 批量摄入intervals未覆盖数据时间范围如果批量加载历史数据时没有任何事件被加载首先确认 ingestion spec 中granularitySpec.intervals是否真正包含数据的时间范围。Druid 会直接丢弃区间之外的事件。一个典型正确示例见 batch-ingestion.mdgranularitySpec : { type : uniform, segmentGranularity : DAY, queryGranularity : NONE, intervals : [ 2013-08-31/2013-09-01 ] }intervals是 ISO-8601 区间start/end必须覆盖你数据中事件时间戳的实际范围否则事件在摄入阶段就被静默丢弃。三、并非所有事件都被摄入Not all of my events were ingested3.1 用摄入指标定位被拒事件Druid 会拒绝windowPeriod之外的事件最可靠的判断方式是查看Druid ingest 指标完整指标表见 docs/content/operations/metrics.md。下表为与“事件被拒”直接相关的指标指标含义正常值ingest/events/thrownAway因超出windowPeriod被拒绝的事件数0ingest/events/unparseable因无法解析被拒绝的事件数0ingest/events/processed每个上报周期内成功处理的事件数等于周期内事件数ingest/rows/output持久化的 Druid 行数rollup 后事件数含 rollupingest/events/messageGap事件数据时间与当前系统时间的差距取决于事件携带时间这些指标的实现在 RealtimeMetricsMonitor.java 中且仅当 Realtime 节点的 monitors 列表包含RealtimeMetricsMonitor时才会输出配置时需注意。此外ingest/persists/backPressure创建 persist 任务并阻塞等待的毫秒数正常应为 0 或极低若持续偏高说明持久化链路存在瓶颈。3.2 摄入数正确但查询结果不对聚合器陷阱如果摄入的事件数看起来正确请确认你的查询是否构造正确。如果你在 ingestion spec 中定义了count聚合器查询时必须用longSum聚合器去聚合这个字段。若在查询中直接使用count聚合器统计的是 Druid 行的数量而不是原始事件数——因为 Druid 摄入时会进行roll-up按维度聚合压缩行数。关于 rollup 对行数的影响可参考 docs/content/design/segments.md 中关于 Segment 结构与 rollup 的说明。四、摄入完成后 Segment 去了哪里Where do my segments end upSegment 的去向完全取决于druid.storage.type的取值。摄入完成后Druid 会把 Segment 上传到深度存储Deep Storage。默认深度存储是本地磁盘local mount配置项见 docs/content/dependencies/deep-storage.md属性说明默认druid.storage.type深度存储类型必须设置localdruid.storage.storageDirectory存放 Segment 的目录必须设置深度存储的持久性决定了数据的安全性只要 Druid 节点能访问到该存储层中的 Segment无论丢失多少个 Druid 节点数据都不会丢一旦 Segment 从该存储层消失其代表的数据即永久丢失。生产环境建议使用 S3druid-s3-extensions、HDFSdruid-hdfs-storage等分布式存储详见 扩展列表。五、流式摄入不交接 SegmentMy stream ingest is not handing off segments实时摄入的最后一环是Segment 交接handoffRealtime 节点把 Segment 推送到深度存储并通过元数据存储与 Zookeeper 通知 Historical 节点加载。如果交接失败先确认两件事摄入进程日志中无异常运行分布式集群时druid.storage.type不能是local——本地存储只适合单机/测试环境分布式集群下 Historical 无法跨节点访问本地磁盘。其余常见交接失败原因官方 FAQ 明确列出以下四类Druid 无法写入元数据存储metadata storage检查 MySQL / PostgreSQL 等元数据存储的配置是否正确。元数据存储承载 Segment 的版本、加载状态等信息是交接成功的前提。Historical 节点容量不足无法下载更多 Segment此时 Coordinator 日志会出现异常Coordinator 控制台也会显示 Historical 节点接近容量上限。需要调大 Historical 的容量配置见第八节。Segment 损坏无法下载Historical 节点日志中会出现异常。深度存储配置不当确认 Segment 确实存在于深度存储中且 Coordinator 日志无报错。交接相关指标同样在 docs/content/operations/metrics.md包括指标含义正常值ingest/handoff/failed交接失败次数0ingest/handoff/count已发生的交接次数每个 Segment 粒度周期至少 1 次ingest/sink/count未交接的 sink 数1~3ingest/persists/failed持久化失败次数0从源码看交接由 RealtimePlumber.java 中的SegmentHandoffNotifier驱动它负责等待 Historical 节点确认加载完成后才推进数据生命周期。六、如何启用 HDFS 深度存储How do I get HDFS to work要让 HDFS 作为深度存储工作官方 FAQ 给出三条硬性要求把druid-hdfs-storage扩展包含进 classpath按 including-extensions 的说明加载扩展把全部 Hadoop 配置和依赖放进 classpath——在一台已配置 Hadoop 的机器上执行以下命令即可获得依赖清单hadoop classpath按深度存储文档提供必要的 HDFS 设置见 docs/content/dependencies/deep-storage.md 与 HDFS 扩展文档属性可能值说明druid.storage.typehdfs必须设置druid.storage.storageDirectory存放 Segment 的目录必须设置druid.hadoop.security.kerberos.principaldruidEXAMPLE.COMKerberos 主体可选druid.hadoop.security.kerberos.keytab/etc/security/keytabs/druid.headlessUser.keytabkeytab 路径可选如果使用 Hadoop indexer把输出目录设置为 Hadoop 上的路径即可直接工作。若集群开启了 Kerberos 安全认证可通过设置druid.hadoop.security.kerberos.principal与druid.hadoop.security.kerberos.keytab主动认证替代周期性执行kinit的 cron 方案。该扩展还支持将 Google Cloud Storagegs://bucket/...作为深度存储使用。七、Coordinator 控制台检查 Segment 分配的第一现场Coordinator 控制台位于http://COORDINATOR_IP:PORT默认端口 8081它是检查 Segment 是否被分配到 Historical 节点的第一入口。Coordinator 的核心职责是维护全局拓扑它周期性druid.coordinator.period默认PT60S对比“可用 Segment 集合”与“正在服务的 Segment 集合”并决定 Segment 的加载/卸载/复制/均衡相关参数见 docs/content/configuration/coordinator.md。Historical 节点的加载流程详见 docs/content/design/historical.md为Coordinator 在 Zookeeper 中为 Historical 创建 load queue 条目 → Historical 检查本地磁盘缓存segment cache→ 若无缓存则从深度存储下载 Segment 元数据与数据 → 加载完成后在 Zookeeper 的 served segments 路径上宣布 → 该 Segment 立即可查询。Historical 还提供两个有用的 HTTP 端点GET /druid/historical/v1/loadstatus返回本地缓存中的所有 Segment 是否都已加载可用于判断节点重启后是否已就绪GET /druid/historical/v1/readiness判断节点是否可查询。八、Historical 节点上看不到 SegmentI dont see my Druid segments on my historical nodes在 Coordinator 控制台确认 Segment 是否真的已加载到 Historical 节点。若 Segment 未出现检查 Coordinator 日志中关于容量capacity或复制replication错误的消息。一个常见原因是Historical 节点的maxSizes太小导致无法下载更多数据。官方 FAQ 给出调整示例-Ddruid.segmentCache.locations[{path:/tmp/druid/storageLocation,maxSize:500000000000}] -Ddruid.server.maxSize500000000000对应配置的完整定义见 docs/content/configuration/historical.md属性说明默认druid.server.maxSize该节点希望被分配的 Segment 总字节数上限。注意这不是 Historical 实际强制执行的硬限制而是发布给 Coordinator 供其规划分配的值0druid.segmentCache.locations分配给 Historical 的 Segment 先落到本地文件系统磁盘缓存这些位置定义本地缓存落在哪里无默认不缓存同时Historical 节点还有一组健康指标可监控见 docs/content/operations/metrics.mdsegment/maxSegment 最大字节限制、segment/used已用字节、segment/usedPercent已用百分比应 100%、segment/count已服务 Segment 数、segment/pendingDelete待清理的磁盘字节数。segment/usedPercent接近 100% 就意味着容量吃紧。另外官方推荐 Segment 文件大小控制在300MB–700MB之间见 docs/content/design/segments.md过大时应调整segmentGranularity或在partitioningSpec中调小targetPartitionSize建议从 500 万行起步这也与容量规划直接相关。九、查询返回空结果My queries are returning empty results查询为空时按以下三步排查用 Segment Metadata Query 检查 datasource 实际建了哪些维度与指标。示例查询见 docs/content/querying/segmentmetadataquery.md{ queryType:segmentMetadata, dataSource:sample_datasource, intervals:[2013-01-01/2014-01-01] }analysisTypes默认为[cardinality, interval, minmax]还可指定size、timestampSpec、queryGranularity、aggregators、rollup等分析类型完整说明。特别地aggregators分析会返回“可用于查询指标列”的聚合器列表——用它核对聚合器名最直接。确认查询中使用的聚合器名称与上述指标名完全一致。名称不匹配是“有数据但查不到”的高频原因。确认查询区间intervals落在存在数据的有效时间范围内。Segment 按时间分区区间对不上自然查不到。十、如何用新 Schema 重新索引已有数据Reindexing with schema changes需要修改 Segment 的名称、维度、指标、rollup 等属性时使用IngestSegmentFirehose Index Task把已有 Druid Segment 按新 Schema 重新摄入。它允许你从 Druid 已有 Segment 读取数据、按新 Schema 聚合后写回 Druid。IngestSegmentFirehose 的 spec 格式与参数见 docs/content/ingestion/firehose.md{ type : ingestSegment, dataSource : wikipedia, interval : 2013-01-01/2013-01-02 }属性说明必填type固定为ingestSegment是dataSource要读取行的数据源类似关系型数据库的表是intervalISO-8601 区间定义要读取的数据时间范围是dimensions要选取的维度列表为空数组则返回空维度为 null 或不定义则返回全部维度否metrics要选取的指标列表为空数组则返回空指标为 null 或不定义则选取全部指标否filter维度过滤器DimFilter可在回灌时过滤掉想删除的行是这些参数与 IngestSegmentFirehoseFactory.java 的JsonProperty定义一一对应dataSource、interval、filter、dimensions、metrics。Index Task 通过firehoseFactory.connect(parser)建立读取管道逐行读取已有 Segment 的数据并重新聚合IndexTask.java。如果使用 Hadoop 批量摄入则改用dataSourceinputSpec 做 reindexing详见 docs/content/ingestion/batch-ingestion.md 与 update-existing-data.md。reindex 是数据治理的兜底手段官方同时提醒建议始终保留一份原始数据副本以备未来再次 reindex。十一、如何改变已有数据的粒度Changing granularity of existing data常见场景希望降低老数据的粒度——例如超过 1 个月的数据只保留小时级粒度而新数据保持分钟级粒度。这与第十节的 reindexing 本质上是同一件事操作方式完全一致使用IngestSegmentFirehose运行一个 Indexer Task。该 Firehose 会把已有 Segment 读出来、按新粒度聚合aggregate再写回 Druid回灌过程中可以用filter过滤掉想删除的行例如清理有问题的数据通常以批量任务方式运行例如每天喂入一块数据并聚合。Hadoop 批量摄入路径则使用dataSourceinputSpec 完成同样的重索引详见 docs/content/ingestion/batch-ingestion.md。需要注意粒度调整的成本降低粒度意味着跨 Segment 合并与重算聚合耗时与数据量成正比建议在低峰窗口执行并提前评估目标 Segment 规模300MB–700MB 区间。十二、实时摄入看起来卡住了Real-time ingestion seems to be stuck实时摄入“卡住”在多数情况下是有意的背压backpressure机制在起作用。Druid 会在以下两种情况下主动限流throttle以防止 OOM中间持久化intermediate persist耗时过长交接handoff耗时过长。源码证据ingest/persists/backPressure指标衡量“创建 persist 任务并阻塞等待其完成”的毫秒数RealtimeMetricsMonitor.java正常情况下应为 0 或极低偏高即代表背压正在生效。排查建议如果节点日志显示某些列构建耗时极长例如 Segment 粒度是小时级但构建某一列就花了 30 分钟则应重新评估配置或扩容实时摄入节点。列构建慢通常意味着高基数high cardinality维度、过大的内存行缓冲或过小的 persist 周期可从以下 tuningConfig 参数入手默认值见 RealtimeTuningConfig.java参数默认值说明maxRowsInMemory75000内存中聚合的最大行数rollup 后行数用于控制 JVM 堆占用intermediatePersistPeriodPT10M中间持久化周期windowPeriodPT10M实时摄入接受事件的时间窗口maxPendingPersists0最多可排队的未完成持久化数十三、结语把 FAQ 变成你的排障 SOP本 FAQ 覆盖的十二个问题本质上是同一套排障循环在不同环节的投影先看日志与指标确认“数据到底有没有进来”ingest/events/*、ingest/persists/*、ingest/handoff/*再看存储与容量确认“数据落到了哪”深度存储、元数据存储、Historical 磁盘缓存最后回到查询层核对 Schema 匹配Segment Metadata Query、聚合器名、查询区间。官方 FAQ 的末尾也强调数据摄入对初次使用者确有门槛遇到问题可以到社区交流渠道IRC、Druid 用户 Google Group求助同时掌握本文所列的日志、指标与配置检查点绝大多数摄入问题都能在 10 分钟内定位到根因。延伸阅读仓库内路径摄入指标全表docs/content/operations/metrics.md批量摄入与 inputSpecdocs/content/ingestion/batch-ingestion.mdFirehose 与 IngestSegmentFirehosedocs/content/ingestion/firehose.md更新已有数据reindex / deltadocs/content/ingestion/update-existing-data.md深度存储配置docs/content/dependencies/deep-storage.mdSegment 结构与 rollupdocs/content/design/segments.mdHistorical 加载流程docs/content/design/historical.mdSegment Metadata Querydocs/content/querying/segmentmetadataquery.md【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址: https://gitcode.com/gh_mirrors/druid7/druid创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
Agent五层架构:从执行层到接入层的工程故障定位指南 1. 这张图谱不是“未来预测”,而是当下正在发生的产业切片你点开任何一篇讲Agent的公众号文章,十有八九开头就是:“2026年,AI Agent将彻底重构人机交互范式……”——这种话术我听了三年,也写了两年。直到去年底&#… · 2026/9/23 2:57:18
基于Flask和Vue的电子书阅读器系统开发实践 1. 项目概述这个基于Python Flask框架开发的电子书阅读器系统,是一个典型的Web应用开发项目。它采用前后端分离架构,后端使用Flask提供RESTful API接口,前端采用Vue.js构建用户界面,实现了电子书的管理和阅读功能。系统特别强调了… · 2026/9/23 2:57:12
专科生必看!8个降AI率工具实测,论文稳过AIGC检测 专科生写毕业论文、课程报告、顶岗实习总结的时候,最头疼的往往不是没话写,而是写完之后学校会用AIGC检测系统扫一遍,给你一个刺眼的"AI率"。我见过太多人明明是自己熬夜写的,就因为用了AI辅助查资料、列提纲࿰… · 2026/9/23 2:57:12
大分辨率遥感道路分割数据集:切片策略、U-Net训练与避坑指南 简介:这份资源面向深度学习图像分割方向的学习者与研究者,提供大分辨率遥感影像道路提取的完整数据集,适合训练与评测分割网络、验证模型在复杂遥感场景下的泛化能力。数据集已预先划分训练集与测试集:训练集含4981张图像及4981张… · 2026/9/23 3:38:00
一条命令自托管多智能体:Octop 1.0 架构解析与部署实战 1. 项目概述与核心思路拆解腾讯云近期发布的AI助手Octop 1.0,放在了"自托管多智能体"这个赛道上。如果你接触过几家主流的开源智能体框架,大概能感受到这类产品通常卡在两个地方:要么安装配置流程太长,要么对云资源的要… · 2026/9/23 3:38:00
3分钟搞定:如何查看445端口是否关闭的实战项目经验 3分钟搞定:如何查看445端口是否关闭的实战项目经验 满屏红色的 StackTrace 报错,看着就头疼?别慌,这往往是端口被占用或策略拦截的“遮羞布”。在做 实战项目… · 2026/9/23 3:38:00
娃哈哈股票代码性能优化实战:3个高频面试考点拆解 娃哈哈股票代码性能优化实战:3个高频面试考点拆解 刚把 Python 的 async/await 啃完,转头面对真实业务场景时,是不是脑子一片空白?很多转岗的朋友都有这种痛苦: 学会语法却不知怎么搭项目… · 2026/9/23 3:38:00
Quectel CMUX驱动实战:Linux/Android多路串口复用与排错 简介:面向嵌入式Linux与Android底层驱动开发者的Quectel EC20模块CMUX驱动资源包,版本为V2.0.1,对应ec20cmux与gsm0701标准。该驱动采用通道复用技术,将单个UART物理通道按时分复用拆分为多个逻辑子通道,使数据、语音、… · 2026/9/23 3:38:00
Nginx转发配置实战:从反向代理到常见报错排查 先交代一下我自己的情况:我手里的服务器上有不少业务系统,有的跑在Tomcat上,有的挂在Docker容器里,还有一个是同事自己用Node.js起的服务,端口五花八门。要让人记住每个端口号根本不现实,所以我基本都用ngi… · 2026/9/23 3:37:54
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29