Druid--Druid的基础集群配置优化

  • 基于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
  • 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的和。

你可能感兴趣的:(Druid--Druid的基础集群配置优化)