Apache Druid 查询指南:REST 协议、查询类型、取消与错误处理
数据库数据分析OLAP大数据实时分析数据仓库后端【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址https://gitcode.com/gh_mirrors/druid7/druid点击查看免费下载Druid 的原生查询语言是基于 HTTP 的 JSON所有查询都通过 HTTP REST 风格的请求发送到可查询节点Broker、Historical 或 Realtime。本文是 Druid 查询的总览手册你将掌握查询的 HTTP 协议格式、九种原生查询类型的适用场景、查询 ID 的生成与取消机制以及查询失败时的错误响应结构——这些知识是后续深入阅读各类查询文档、编写客户端或排查线上问题的基础。Apache Druid 数据流架构示意图查询的 HTTP 协议JSON over HTTPDruid 查询使用 HTTP REST 风格请求发送到可查询节点Broker、Historical 或 Realtime。查询体以 JSON 表达且这三种节点暴露的是同一个 REST 查询接口。在正常运维场景下查询应统一发往 Broker 节点只有在排查特定节点行为或做内部调试时才直接查询 Historical / Realtime。发起查询的标准方式是使用curl向查询接口 POST 一个 JSON 文件curl -X POST queryable_host:port/druid/v2/?pretty -H Content-Type:application/json -d query_json_file几个关键点端口差异Broker 与 Router 的默认 HTTP 端口是8082Historical 是8083Realtime实时索引任务是8084。实际端口以各自节点的runtime.properties配置为准例如 examples/conf/druid/broker/runtime.properties 中 Broker 的druid.port8082。?pretty参数可选加上后返回的 JSON 会以缩进格式输出便于阅读调试。Content-Type请求头必须设置为application/json。Druid 同样支持 Smile 的Produces/Consumes声明中有明确体现。从源码角度印证io.druid.server.QueryResource类以Path(/druid/v2/)注解暴露查询端点见 QueryResource.java其doPost方法接收输入流、用 JSON/Smile 对应的ObjectMapper反序列化为Query对象再交给QuerySegmentWalker执行最终以流式StreamingOutput方式把结果写回客户端。Historical 与 Peon 注册的是基础版QueryResource而 Broker 注册的是其子类BrokerQueryResource见 CliBroker.java 与 CliHistorical.java后者额外提供了/druid/v2/candidates调试端点用于查看某查询会被路由到哪些服务器BrokerQueryResource.java。Druid 的原生查询是相对底层的它与 Druid 内部的执行模型紧密对应设计目标就是轻量、快速完成。这意味着对于更复杂的分析或更复杂的可视化往往需要把多个 Druid 查询组合起来使用而不是在一个查询里塞进全部逻辑。说明由于原生查询语言是 JSON over HTTP社区已经为其他语言贡献了大量客户端库Java、Python、JavaScript 等方便以编程方式查询 Druid。原生查询类型总览Druid 针对不同使用场景提供了多种查询类型每种类型由一组 JSON 属性构成属性含义在各查询类型的专项文档中详细描述。所有查询类型共享queryType、dataSource、intervals等公共字段其中queryType是 Druid 判断如何解释查询的第一依据。分类查询类型核心用途专项文档聚合查询Timeseries按时间粒度做聚合不按维度分组timeseriesquery.md聚合查询TopN对单个维度按指标排序取前 N 名topnquery.md聚合查询GroupBy最灵活的聚合查询支持多维度分组与排序groupbyquery.md元数据查询Time Boundary返回数据源中数据的时间边界timeboundaryquery.md元数据查询Segment Metadata返回某个时间段内的 Segment 元数据segmentmetadataquery.md元数据查询Datasource Metadata返回数据源的元数据如更新时间戳datasourcemetadataquery.md搜索查询Search返回匹配搜索规范的维度值searchquery.md所有查询都共享一组上下文参数query context用于配置超时、优先级、缓存、调试行为等详见下文查询上下文一节dataSource、granularity、filter、intervals等公共概念则分别由 datasource.md、granularities.md、filters.md 等文档定义。下面通过三个示例快速感受查询 JSON 的形态。Timeseries 查询——按小时聚合page_views数据源中的added指标{ queryType: timeseries, dataSource: page_views, granularity: hour, aggregations: [ { type: count, name: rows }, { type: longSum, name: added, fieldName: added } ], intervals: [ 2015-09-12T00:00:00.000Z/2015-09-13T00:00:00.000Z ] }TopN 查询——按维度page分组、以added求和降序取前 10{ queryType: topN, dataSource: page_views, granularity: all, dimension: page, metric: added, threshold: 10, aggregations: [ { type: longSum, name: added, fieldName: added } ], intervals: [ 2015-09-12T00:00:00.000Z/2015-09-13T00:00:00.000Z ] }Search 查询——在dim1、dim2上查找包含子串Ke的维度值不区分大小写完整字段说明见 searchquery.md{ queryType: search, dataSource: sample_datasource, granularity: day, searchDimensions: [ dim1, dim2 ], query: { type: insensitive_contains, value: Ke }, sort: { type: lexicographic }, intervals: [ 2013-01-01T00:00:00.000/2013-01-03T00:00:00.000 ] }如何选择查询类型在可能的情况下官方推荐优先使用Timeseries和TopN而不是 GroupBy。三者的定位差异非常明确场景推荐查询原因只需要按时间聚合、不需要按维度分组Timeseries远快于 GroupBy需要按单个维度分组并排序取前 NTopN针对单维度做了大量优化明显优于 GroupBy需要多维度分组、复杂排序、过滤后的深度分析GroupBy最灵活但性能也最差简而言之GroupBy 是 Druid 最灵活的查询但也是性能最差的。如果查询不需要维度分组请选择 Timeseries如果只需要单个维度上的排序取 topN请选择 TopN。需要指出上述灵活性最高、性能最差是相对同仓库内 Timeseries / TopN 实现而言的官方建议原文出处见 querying.md并非与其他数据库产品的横向对比。TopN 的实现之所以高效是因为它采用了分段局部 topN 全局归并的策略每个数据段先各自算出局部 topN段内结果数由上下文参数minTopNThreshold控制默认 1000再把局部结果归并得到全局 topN——这与 GroupBy 需要维护全量分组哈希表的开销形成鲜明对比。查询上下文Query Context查询 JSON 中可以携带一个context对象用于配置各项运行参数。以下参数适用于所有查询类型完整定义见 query-context.md属性默认值说明timeout0无超时查询超时时间毫秒超过后未完成的查询将被取消。priority0查询优先级高优先级查询在计算资源竞争中获得优先处理。queryId自动生成查询的唯一标识若已设置或已知可用于取消查询见下文。useCachetrue是否使用查询缓存可在 Broker / Historical 节点配置中覆盖。populateCachetrue是否将查询结果写入查询缓存主要用于调试可在节点配置中覆盖。bySegmentfalse是否按数据段segment返回结果主要用于调试开启后返回结果会附带来源段信息。finalizetrue是否终结聚合结果主要用于调试。例如置为false时hyperUnique聚合器返回完整的 HyperLogLog sketch 而非预估基数。chunkPeriodP0D关闭仅 Broker 有效长区间查询会被拆分为较短区间的子查询并行归并。使用 ISO 8601 周期例如设为P1M时覆盖一年的查询会被拆成 12 个小查询。拆分后的查询会占用更多集群资源但可能显著更快。注意 Broker 使用查询处理线程池发起分块因此需保证 Broker 的druid.processing.numThreads配置充足。GroupBy 默认不支持chunkPeriod使用旧的 v1 引擎时除外。各查询类型还有专属上下文参数TopN 有minTopNThreshold默认1000控制每个段返回参与全局归并的局部结果数Timeseries 有skipEmptyBuckets默认false置为true可关闭零填充只返回有结果的桶GroupBy 的上下文参数见 groupbyquery.md。从源码实现看timeout与queryId的处理在 QueryResource.java 中请求到达后若查询未携带queryId服务端会为其生成一个 UUID若未携带timeout则默认使用ServerConfig.getMaxIdleTime()对应的毫秒数作为超时。这也解释了为什么即使客户端不设置上下文服务端也能对查询做超时控制与后续取消。查询取消Query CancellationDruid 支持通过查询的唯一标识显式取消查询。只要在发起查询时设置了queryId或该 ID 已知就可以在Broker 或 Router上调用如下端点取消DELETE /druid/v2/{queryId}例如假设查询 ID 为abc123curl -X DELETE http://host:port/druid/v2/abc123底层的取消链路非常清晰QueryResource的getServer方法映射DELETE Path({id})QueryResource.java调用QueryManager.cancelQuery(queryId)成功后返回 HTTP 202ACCEPTEDQueryManager.java 内部以SetMultimapString, ListenableFuture维护queryId → 查询 Future的映射cancelQuery取出该 ID 关联的所有ListenableFuture并逐个执行future.cancel(true)以中断方式取消同时在查询完成监听器中自动清理映射条目查询真正被取消时执行端会抛出CancellationException最终被包装为error: Query cancelled的错误响应见下文。安全说明从 QueryResource.java 的实现可以看到若集群开启了鉴权AuthConfig.isEnabled()取消请求需要携带有效的授权信息且调用者必须对查询涉及的每个数据源拥有WRITE权限授权机制见 AuthConfig 相关实现 以及 docs/content/design/coordinator.md 中的安全配置指引否则会返回 403FORBIDDEN。查询错误与响应结构如果查询执行失败节点会返回HTTP 500响应响应体是一个 JSON 对象结构如下{ error : Query timeout, errorMessage : Timeout waiting for task., errorClass : java.util.concurrent.TimeoutException, host : druid1.example.com:8083 }各字段含义字段说明error定义良好的错误码取值见下表。errorMessage关于错误的自由格式信息可能为 null。errorClass引发错误的异常类可能为 null。host错误发生的节点主机名可能为 null。error字段可能的取值错误码说明Query timeout查询超时。Query interrupted查询被中断可能由 JVM 关闭等原因导致。Query cancelled查询通过取消 API 被取消。Resource limit exceeded查询超过了配置的资源限制例如 groupBy 的maxResults。Unknown exception其他异常。请查看errorMessage和errorClass获取详情但注意这两个字段是自由格式的内容可能随版本变化。源码级印证错误响应的 JSON 序列化由io.druid.query.QueryInterruptedException完成QueryInterruptedException.java。这个类虽然名字叫Interrupted但实际上是客户端侧所有查询失败的统一表示它通过JsonProperty注解把error、errorMessage、errorClass、host四个字段序列化为上述 JSON 结构。其错误码推导逻辑getErrorCodeFromThrowable正是按异常类型映射到上表TimeoutException→Query timeoutInterruptedException→Query interruptedCancellationException→Query cancelledResourceLimitExceededException→Resource limit exceeded其余所有异常 →Unknown exception在服务端QueryResource.java 的gotError方法通过QueryInterruptedException.wrapIfNeeded(e)把任意异常包装成统一格式并返回Response.serverError()即 HTTP 500。客户端侧Broker 的DirectDruidClient会反序列化并包装这些错误对象见 DirectDruidClient.java 对druid/v2的请求处理从而把集群内部的错误逐层传递回调用方。此外QueryResource.java 会在错误发生时向监控系统发射query/timesuccessfalse指标并写入请求日志便于事后排查。进阶指引本文覆盖了 Druid 查询的公共协议与通用机制。当你需要编写具体查询时建议按以下路径深入公共概念datasource.md数据源定义、granularities.md时间粒度、filters.md过滤、dimensionspecs.md维度规范、aggregations.md聚合器、post-aggregations.md后聚合、limitspec.md排序与截断。各查询类型分别阅读 timeseriesquery.md、topnquery.md、groupbyquery.md、searchquery.md 以及三个元数据查询文档。高级能力joins.md查询时关联、multitenancy.md多租户、caching.md缓存行为、query-context.md上下文参数全集。其他访问方式Druid 还提供了 SQL 查询层如果你需要了解各服务节点的职责与配置可阅读 Broker 设计文档 与 Historical 设计文档。赞分享数据库数据分析OLAP大数据实时分析数据仓库后端【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址https://gitcode.com/gh_mirrors/druid7/druid点击查看免费下载相关推荐Apache Druid 查询执行机制完全指南从 Datasource 类型到 scatter-gather 与子查询限制Apache Druid 查询执行机制完全指南从 Datasource 类型到 scatter gather 与子查询限制 本文以 Apache Druid数据库OLAP大数据后端Apache Pulsar SQL REST API 实战指南基于 Trino/Presto HTTP 协议提交与轮询查询Apache Pulsar SQL REST API 实战指南基于 Trino/Presto HTTP 协议提交与轮询查询 Apache Pulsar SQL消息队列后端流处理Apache Druid 指标监控完整指南查询、摄取与协调 Metrics 详解Apache Druid 指标监控完整指南查询、摄取与协调 Metrics 详解 本文以 Apache Druid 官方运维文档为核心系统讲解 Druid数据库数据分析OLAP大数据实时分析数据仓库后端上一篇告别样式混乱用Style Dictionary打造统一的设计语言系统下一篇CI/CD集成Klavis AI自动化部署最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考