- 基于apache-druid-0.17
概述
- 本文是基于官网的一些建议进行的
与进程类相关的配置建议
Historical 进程
Heap 大小(堆大小)
- Historicals进程中heap的主要贡献为:
- 来自Segment的部分未合并查询结果;
- 存储
Lookup
的值;
- 调整Historicals进程的heap大小的一般经验法则是(0.5GB * CPU内核的数量),上限为~24GB。
- 这个经验法则使用CPU内核的数量作为硬件大小和并发级别的方便代理(注意:这个公式并不是确定历史堆大小的硬性规则)。
- heap太大可能会导致GC收集暂停过长,为了避免这种情况,设置了~24GB上限。
- Historicals进程如果允许缓存,缓存是存储在heap上。大小有参数
druid.cache.sizeInBytes
决定。 - 在Historicals进程上耗尽堆可能表明配置错误或使用模式导致集群超载。
lookups功能
- 如果正在使用
lookup
功能,请计算正在加载的lookup
映射的总大小。 - Druid在更新
lookup
映射时执行原子交换(在交换期间旧映射和新映射都存在于堆中),所以lookup
映射的最大潜在堆使用量将是(2 *所有加载查找的总大小)。 - 除了(0.5GB * CPU核心数量)准则外,请确保将(2 *所有加载查找的总大小)添加到堆大小中。
处理线程和缓冲区
- Historicals进程中:
-
druid.processing.numThreads
:通常应设置为(内核数量- 1):较小的值会导致CPU利用率不足,而超过内核数量则会导致不必要的CPU争用。 -
druid.processing.buffer.sizeBytes
:可以设置为500M; -
druid.processing.numMergeBuffers
:对于一般使用来说,合并缓冲区与处理线程的比例为1:4是一个合理的选择。
-
Direct Memory Sizing
- 上面描述的处理缓冲区和合并缓冲区是直接内存缓冲区。
- 当Historicals处理查询时,它必须打开一组Segment以供读取。这也需要一些直接的内存空间,如segment decompression buffers.
- 估计直接内存使用的公式如下:
(druid.processing.numThreads + druid.processing.numMergeBuffers + 1) * druid.processing.buffer.sizeBytes
-
+1
因子是一个模糊的估计,用于解释Segment解压缩缓冲区。
Connection pool sizing
- 对于
Historicals
进程,druid.server.http.numThreads
的值应该比集群中所有Broker的参数值druid.broker.http.numConnections
的和要大一些。 - 优化集群,使每个Historicals可以接受50个查询和10个非查询,这是一个合理的起点。
segment缓存大小
-
druid.server.maxSize
: Coordinator可以分配给Historicals的段数据的总大小。 -
druid.segmentCache.locations
:指定Segment数据可以存储在Historicals中的位置。这些位置上可用磁盘空间的总和应该相等druid.server.maxSize
。 - Segment由
Historicals
使用任何可用的空闲系统内存。 - 因此
druid.server.maxSize
应该被指定,这样就不会为Historicals
分配过多的Segment数据。free system memory / druid.server.maxSize
的值增加,更大比例的Segment可以保存在内存中,从而实现更好的查询性能。
Historicals的数量
- 集群中Historicals的数量取决于集群的数据量大小。为了获得良好的性能,您需要足够的Historicals,以便每个Historicals具有良好的(
free system memory / druid.server.maxSize
)比率,和上文segment缓存部分所讲一样。 - 只要您对用例有足够的容错能力,使用少量的大型服务器通常比使用大量的小型服务器要好。
SSD存储
- 我们建议使用Historicals节点使用SSD磁盘,因为它们处理存储在磁盘上的Segment数据。
总内存使用
- 要估计在这些准则下的Historicals总内存使用量:
- Heap:
(0.5GB * number of CPU cores) + (2 * total size of lookup maps) + druid.cache.sizeInBytes
- Direct Memory:
(druid.processing.numThreads + druid.processing.numMergeBuffers + 1) * druid.processing.buffer.sizeBytes
- Heap:
- Historicals将使用任何可用的空闲系统内存(即Historicals中JVM和堆/直接内存缓冲区或系统上的其他进程没有使用的内存),用于磁盘上Segment的内存映射。为了获得更好的查询性能,您需要确保一个良好的(
free system memory / druid.server.maxSize
)比率,以便在内存中保留更大比例的Segment数据。
segment大小问题
- 请务必检查segment size optimization
,以帮助优化Historicals获得最大的性能。
Broker
heap大小
- Broker中heap的最大贡献是:
- 来自Historicals和Task的部分未合并查询结果;
- Segment时间轴:这包括当前所有可用Segment的位置信息(which Historical/Task is serving a segment)。
- 缓存的Segment元数据:这包括当前所有可用Segment的元数据,例如每个Segment的schema。
- Broker 的heap 需求根据集群中的Segment数量和Segment的总数据大小进行伸缩。
- 堆大小将根据数据大小和使用模式而变化,但是4G到8G对于小型或中型集群(~15个或更少的服务器)是一个很好的起点。对于高端内存需求的粗略估计,大约有100个节点的非常大的集群可能需要30GB-60GB的Beoker heap大小。
- 如果在代理上启用了缓存,那么缓存将存储在堆上,大小由
druid.cache.sizeInBytes
决定。
Direct memory sizing
- Broker需要多少直接内存取决于配置了多少合并缓冲区(用于合并GroupBys)。Broker通常不需要处理线程或处理缓冲区,因为查询结果是在HTTP连接线程的堆上合并的。
-
druid.processing.buffer.sizeBytes
可以设置为500M; -
druid.processing.numThreads
设置为1,(允许最小值)。 -
druid.processing.numMergeBuffers
:将该值设置为与Historicals值相同或稍高。
-
- 有一个例外,Broker不需要处理线程和处理缓冲区:
- 如果在查询上下文中设置了已废弃的
chunkPeriod
属性,则GroupBy V1
查询将在Broker上使用处理线程和处理缓冲区。
- 如果在查询上下文中设置了已废弃的
连接池大小
- General Connection Pool Guidelines
- Broker中,请确保所有节点的
druid.broker.http.numConnections
的和要低于Historicals and Tasks的druid.server.http.numThreads
。 - Broker中
druid.server.http.numThreads
的值要略高于druid.broker.http.numConnections
。 - 优化集群,使每个历史记录可以接受50个查询和10个非查询,并相应地调整Broker,这是一个合理的起点。
Broker 背压
- 当检索查询结果从
Historical or Tasks
,Broker可以选择指定最大缓冲区大小排队,未读数据和施加反压力的通道达到Historical or Tasks
时限制。 - 缓冲大小由
druid.broker.http.maxQueuedBytes
参数配置。 - 这个限制是根据查询所命中的
Historical or Tasks
的数量来划分的:假设我有一个druid.broker.http.maxQueuedBytes
设置为5MB,Broker接收一个需要扩展为两个Historical
的查询。在本例中,每个Historical
将获得2.5MB的缓冲区。 - 您通常可以将这个值设置为大约2MB *Historical数量。当您的集群使用更多的Historical和Task进行扩展时,请考虑增加缓冲区大小并相应地增加Broker heap。
- 如果缓冲区太小,这可能会导致效率低下的查询,因为缓冲区很快就会填满并使通道陷入停顿
- 如果缓冲区太大,这将给代理带来更多的内存压力,因为HTTP通道中有更多的结果数据在排队。
brokers的数量
- A 1:15 ratio of Brokers to Historicals is a reasonable starting point (this is not a hard rule).
- If you need Broker HA, you can deploy 2 initially and then use the 1:15 ratio guideline for additional Brokers.
总内存使用
- 要根据这些准则估计Broker的总内存使用量:
- Heap: allocated heap size
- Direct Memory: (
druid.processing.numThreads + druid.processing.numMergeBuffers + 1) * druid.processing.buffer.sizeBytes
MiddleManager
- MiddleManager是一个轻量级的任务控制器/管理器,它启动执行数据抽取工作的任务进程。
MiddleManager堆大小
- MiddleManager本身不需要太多的资源,一般可以将堆设置为~128MB。
SSD存储
- 建议MiddleManager角色节点采用SSD磁盘,因为MiddleManager发起的任务处理存储在磁盘上的Segment数据。
任务数量
- MiddleManager可以进行的任务数量由参数
druid.worker.capacity
。 - 集群中需要的MiddleManager数量取决于您需要为用例运行多少个并发摄取任务。可以在给定机器上启动的worker的数量取决于每个worker分配的资源大小和可用的系统资源。
- 您可以为集群分配更多的MiddleManager机器来增加任务容量。
Task配置文件
task heap大小
- A 1GB heap is usually enough for Tasks.
lookups功能
- 两倍于
lookups
的大小内存。
Task processing threads and buffers
- 任务处理线程和缓冲区
- 对于任务,1个或2个处理线程通常就足够了,因为任务中可查询的数据往往比Historical进程少得多。
-
druid.indexer.fork.property.druid.processing.numThreads
: set this to 1 or 2 -
druid.indexer.fork.property.druid.processing.numMergeBuffers
: set this to 2 -
druid.indexer.fork.property.druid.processing.buffer.sizeBytes
: can be set to 100MB
-
直接内存大小
- 上面描述的处理缓冲区和合并缓冲区是直接内存缓冲区。
- 当一个任务处理一个查询时,它必须打开一组Segment以供读取。这也需要一些直接的内存空间,如 segment decompression buffers所示。
连接池大小
-
druid.server.http.numThreads
的值大于集群中所有Broker的druid.broker.http.numConnections
的和。