Router 服务
Router 服务负责在不同的 Broker 服务之间分发查询。默认情况下,Broker 根据预先配置的 数据保留规则 来路由查询。例如,如果一个月内的近期数据被加载到 hot(热)集群中,那么落在该近期范围内的数据查询可以被路由到一组专用的 Broker。该范围之外的查询则被路由到另一组 Broker。这种设置提供了查询隔离,从而确保对重要数据的查询不会受到对不那么重要数据查询的影响。
对于查询路由,通常只有在 Druid 集群达到 TB 级别时,才真正需要使用 Router 服务。
除了查询路由,Router 还运行 Web 控制台,这是一个用于加载数据、管理数据源和任务,以及查看服务器状态和段(segment)信息的 UI 界面。
配置
有关 Apache Druid Router 服务的配置,请参阅 Router 配置。
有关 Router 服务的基础调优指南,请参阅 集群基础调优。
HTTP 端点
有关 Router 支持的 API 端点列表,请参阅 旧版元数据 API 参考。
运行
org.apache.druid.cli.Main server router
作为管理代理的 Router
您可以配置 Router 将请求转发到处于活跃状态的 Coordinator 或 Overlord 服务。这在构建高可用集群时非常有用,特别是在 Coordinator 或 Overlord 服务的 HTTP 重定向机制无法正常工作的情况下,例如当服务器位于负载均衡器之后,或者重定向中使用的主机名只能在内部解析时。
启用管理代理
要启用管理代理,请在 Router 的 runtime.properties 中设置以下内容
druid.router.managementProxy.enabled=true
管理代理路由
管理代理支持隐式路由和显式路由。隐式路由是指根据 Druid API 路径约定,可以从原始请求路径确定目标地址的路由。对于 Coordinator,约定为 /druid/coordinator/*;对于 Overlord,约定为 /druid/indexer/*。这种方式很方便,因为使用管理代理时无需修改 API 请求,只需将请求发送到 Router 而非 Coordinator 或 Overlord 即可。大多数 Druid API 请求都可以进行隐式路由。
显式路由是指请求中包含一个路径前缀,用于指明应将请求路由到哪个服务。对于 Coordinator,此前缀为 /proxy/coordinator;对于 Overlord,此前缀为 /proxy/overlord。这在 API 调用目标不明确时是必需的。例如,/status API 存在于所有 Druid 服务上,因此必须使用显式路由来指明代理目标。
下表总结了相关路由:
| 请求路由 | 目标 | 重写后的路由 | 示例 |
|---|---|---|---|
/druid/coordinator/* | Coordinator | /druid/coordinator/* | router:8888/druid/coordinator/v1/datasources -> coordinator:8081/druid/coordinator/v1/datasources |
/druid/indexer/* | Overlord | /druid/indexer/* | router:8888/druid/indexer/v1/task -> overlord:8090/druid/indexer/v1/task |
/proxy/coordinator/* | Coordinator | /* | router:8888/proxy/coordinator/status -> coordinator:8081/status |
/proxy/overlord/* | Overlord | /* | router:8888/proxy/overlord/druid/indexer/v1/isLeader -> overlord:8090/druid/indexer/v1/isLeader |
Router 策略
Router 拥有一系列可配置的策略,用于决定将查询路由到哪些 Broker。策略的顺序非常重要,因为一旦满足策略条件,就会立即选择相应的 Broker。
timeBoundary
{
"type":"timeBoundary"
}
包含此策略意味着所有 timeBoundary 查询总是被路由到优先级最高的 Broker。
priority
{
"type":"priority",
"minPriority":0,
"maxPriority":1
}
优先级低于 minPriority 的查询被路由到优先级最低的 Broker。优先级高于 maxPriority 的查询被路由到优先级最高的 Broker。默认情况下,minPriority 为 0,maxPriority 为 1。使用这些默认值时,如果发送优先级为 0(默认查询优先级)的查询,该查询将跳过优先级选择逻辑。
manual
此策略从查询上下文中读取 brokerService 参数,并将查询路由到该 Broker 服务。如果查询上下文中未指定有效的 brokerService,则使用 defaultManualBrokerService 字段来确定目标 Broker 服务(前提是该值有效且非空)。如果一个值存在于 druid.router.tierToBrokerMap 中,则认为该值有效。此策略可用于路由原生查询和 SQL 查询。
以下策略示例在查询上下文中未找到有效的 brokerService 时,会将查询路由到 druid:broker-hot Broker。
{
"type": "manual",
"defaultManualBrokerService": "druid:broker-hot"
}
JavaScript
允许使用 JavaScript 函数定义任意路由规则。该函数接收配置和待执行的查询,并返回应路由到的层级,或者返回 null 表示使用默认层级。
以下示例函数将包含超过三个聚合器的查询发送到优先级最低的 Broker。
{
"type" : "javascript",
"function" : "function (config, query) { if (query.getAggregatorSpecs && query.getAggregatorSpecs().size() >= 3) { var size = config.getTierToBrokerMap().values().size(); if (size > 0) { return config.getTierToBrokerMap().values().toArray()[size-1] } else { return config.getDefaultBrokerServiceName() } } else { return null } }"
}
基于 JavaScript 的功能默认是禁用的。请参阅 Druid JavaScript 编程指南,了解关于使用 Druid JavaScript 功能的指南,包括如何启用它的说明。
使用策略路由 SQL 查询
要启用使用策略的 SQL 查询路由,请将 druid.router.sql.enable 设置为 true。给定 SQL 查询的 Broker 服务仅使用提供的 Router 策略解析。如果无法通过任何策略解析,Router 将使用 defaultBrokerServiceName。此行为与原生查询略有不同:原生查询时,Router 会先尝试通过策略解析 Broker 服务,然后是加载规则,最后是 defaultBrokerServiceName(如果仍未解析)。当 druid.router.sql.enable 设置为 false(默认值)时,Router 直接使用 defaultBrokerServiceName。
设置 druid.router.sql.enable 不会影响 Avatica JDBC 请求或原生查询。Druid 始终按照文档说明使用策略和加载规则来路由原生查询。Druid 始终根据连接 ID 路由 Avatica JDBC 请求。
Avatica 查询负载均衡
所有具有相同连接 ID 的 Avatica JDBC 请求都必须路由到同一个 Broker,因为 Druid Broker 之间不共享连接状态。
为此,Druid 提供了两个内置负载均衡器,分别使用“汇聚哈希”(Rendezvous Hashing)和“一致性哈希”(Consistent Hashing)来根据请求的连接 ID 将请求分配给 Broker。
注意,当使用多个 Router 时,所有 Router 应具有相同的负载均衡器配置,以确保它们做出相同的路由决策。
Rendezvous 哈希负载均衡器
该负载均衡器在 Avatica 请求的连接 ID 上使用 汇聚哈希 (Rendezvous Hashing) 将请求分配给 Broker。
要使用此负载均衡器,请指定以下属性
druid.router.avatica.balancer.type=rendezvousHash
如果未设置 druid.router.avatica.balancer 属性,Router 默认使用汇聚哈希负载均衡器。
一致性哈希负载均衡器
该负载均衡器在 Avatica 请求的连接 ID 上使用 一致性哈希 (Consistent Hashing) 将请求分配给 Broker。
要使用此负载均衡器,请指定以下属性
druid.router.avatica.balancer.type=consistentHash
这是一个非默认实现,旨在用于实验目的。一致性哈希在初始化和 Broker 集合发生变化时设置时间较长,但在测试 5 个 Broker 时,其 Broker 分配速度比汇聚哈希更快。两种实现的基准测试已提供在 ConsistentHasherBenchmark 和 RendezvousHasherBenchmark 中。此外,一致性哈希需要锁定,而汇聚哈希不需要。
生产配置示例
在此示例中,我们的生产集群有两个层级:hot 和 _default_tier。hot 层级的查询通过 broker-hot Broker 组路由,_default_tier 层级的查询通过 broker-cold Broker 组路由。如果发生任何异常或网络问题,查询将被路由到 broker-cold Broker 组。在本例中,我们运行在 c3.2xlarge EC2 实例上。我们假设 common.runtime.properties 已经存在。
JVM 设置
-server
-Xmx13g
-Xms13g
-XX:NewSize=256m
-XX:MaxNewSize=256m
-XX:+UseConcMarkSweepGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+UseLargePages
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/mnt/galaxy/deploy/current/
-Duser.timezone=UTC
-Dfile.encoding=UTF-8
-Djava.io.tmpdir=/mnt/tmp
-Dcom.sun.management.jmxremote.port=17071
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Runtime.properties
druid.host=#{IP_ADDR}:8080
druid.plaintextPort=8080
druid.service=druid/router
druid.router.defaultBrokerServiceName=druid:broker-cold
druid.router.coordinatorServiceName=druid:coordinator
druid.router.tierToBrokerMap={"hot":"druid:broker-hot","_default_tier":"druid:broker-cold"}
druid.router.http.numConnections=50
druid.router.http.readTimeout=PT5M
# Number of threads used by the Router proxy http client
druid.router.http.numMaxThreads=100
druid.server.http.numThreads=100