Apache Druid 缓存配置实战指南:Local / Memcached / Hybrid 三种缓存类型深度解析
2026/9/23 13:06:57 网站建设 项目流程

Apache Druid 缓存配置实战指南:Local / Memcached / Hybrid 三种缓存类型深度解析

【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址: https://gitcode.com/gh_mirrors/druid7/druid

缓存是 Druid 查询链路中最重要的性能优化手段之一。在 Apache Druid 中,缓存可以按需在Broker、Historical 和 Realtime三类进程上开启,用于加速重复查询、降低底层 Segment 扫描压力。本文以仓库中的官方配置文档docs/content/configuration/caching.md为主体,结合server/src/main/java/io/druid/client/cache/下的源码实现与examples/conf/中的真实示例配置,完整讲解localmemcachedhybrid三种缓存类型的全部配置参数、底层工作原理、适用场景与常见实践,帮助你为自己的集群选择并落地正确的缓存方案。

一、缓存在哪里生效:Broker、Historical 与 Realtime

Druid 的查询缓存是一个可选项,需要在BrokerHistorical以及 Realtime 处理节点上分别决定是否启用。官方文档给出了三份对应的配置说明:

  • broker 缓存配置:Broker 负责接收查询请求、将其分发到各数据节点并合并结果,是缓存收益最明显的进程;
  • historical 缓存配置:Historical 节点直接提供历史数据查询,开启缓存可大幅降低重复扫描;
  • realtime 缓存配置:实时节点提供近实时数据,同样可参与缓存。

以 Broker 为例,其缓存开关在examples/conf/druid/broker/runtime.properties中有真实示例:

# Query cache druid.broker.cache.useCache=true druid.broker.cache.populateCache=true druid.cache.type=local druid.cache.sizeInBytes=2000000000

druid.broker.cache.useCachedruid.broker.cache.populateCache分别控制“查询时是否读取缓存”和“查询结果是否写入缓存”,二者独立配置,默认均为false(见 CacheConfig.java 源码中private boolean useCache = false;private boolean populateCache = false;)。因此“开启缓存”至少需要同时把这两个开关置为true,否则只会单向生效。

哪些查询类型默认不参与缓存

CacheConfig中还内置了一个默认不可缓存的查询类型列表:

private List<String> unCacheable = Arrays.asList(Query.GROUP_BY, Query.SELECT);

也就是说,默认情况下 GroupBy 与 Select 查询不会被缓存,Timeseries、TopN 等查询类型则正常参与缓存。该列表可通过druid.cache.unCacheable配置覆盖。CacheConfigisQueryCacheable(String queryType)方法正是通过判断查询类型是否落在该列表中来决定缓存的可用性。

二、缓存类型总览:druid.cache.type

Druid 默认使用本地 JVM 内存缓存local),除非你显式指定了其他类型。全局缓存类型由公共配置文件(即examples/conf/druid/_common/common.runtime.properties)中的druid.cache.type决定,因此Broker 与 Historical 可以复用同一份缓存配置

PropertyPossible ValuesDescriptionDefault
druid.cache.typelocal,memcached,hybrid查询使用的缓存类型。各类型的详细配置选项见下文local

缓存类型通过CacheProvider接口工厂化注入:LocalCacheProviderMemcachedCacheProviderHybridCacheProvider分别对应上述三种类型,统一实现 CacheProvider.java 与 Cache.java 抽象出的get / put / getBulk / close / getStats等操作。

三、Local Cache:简单高效的进程内 LRU 缓存

3.1 原理

Local Cache 是一个简单的 JVM 堆内内存 LRU 缓存,其实现为MapCache包装的ByteCountingLRUMap(见 LocalCacheProvider.java):

@Override public Cache get() { return new MapCache(new ByteCountingLRUMap(initialSize, logEvictionCount, sizeInBytes)); }

ByteCountingLRUMap继承自LinkedHashMap并以accessOrder = true构造(即按访问顺序排序),因此天然具备 LRU 淘汰语义;它额外用AtomicLong numBytes按字节精确统计缓存占用,并在超过sizeInBytes上限时按插入/访问顺序淘汰最久未使用的条目(详见 ByteCountingLRUMap.java)。

由于缓存驻留在 JVM 堆内存中,启用 Local Cache 后务必同步调大进程的堆内存(如jvm.config中的-Xmx,否则缓存会与数据对象争抢堆空间。

3.2 配置参数

PropertyDescriptionDefault
druid.cache.sizeInBytes缓存最大字节数。设为0表示禁用缓存0
druid.cache.initialSize缓存底层哈希表(hashtable)的初始大小500000
druid.cache.logEvictionCount非零时,每淘汰logEvictionCount个条目记录一条日志0

其中sizeInBytesinitialSize都带有@Min(0)校验约束;当logEvictionCount非零时,ByteCountingLRUMap会在淘汰计数达到该值的整数倍时输出日志,日志中同时打印当前大小与平均对象大小,便于排查缓存抖动。

3.3 实践示例

官方 Quickstart 配置(examples/conf/druid/broker/runtime.properties)给出的正是 Local Cache 的典型用法:

druid.broker.cache.useCache=true druid.broker.cache.populateCache=true druid.cache.type=local druid.cache.sizeInBytes=2000000000 # 2GB 堆内缓存

四、Memcached:进程间共享的分布式缓存

4.1 原理

Memcached 模式使用memcached 作为缓存后端,所有节点共享同一个缓存实例,因此多 Broker / 多 Historical 之间可以共用缓存命中结果,避免各自为政的重复计算。底层通过 spymemcached 客户端(MemcachedCache+MemcacheClientPool)与 memcached 服务通信,LZ4Transcoder负责对象的 LZ4 压缩编解码。

与 Local Cache 不同,Memcached 缓存不占用 Druid 进程的堆内存,这是它适合大规模共享缓存的关键原因。

4.2 配置参数

PropertyDescriptionDefault
druid.cache.expirationMemcached 缓存条目的过期时间(秒)2592000(30 天)
druid.cache.timeout等待 memcached 响应的最大毫秒数500
druid.cache.hosts逗号分隔的 memcached 主机列表<host:port>无(必填)
druid.cache.maxObjectSize单个 memcached 对象的最大字节数52428800(50 MB)
druid.cache.memcachedPrefix所有 key 在 memcached 中的统一前缀druid
druid.cache.numConnections使用的 memcached 连接数1

对照源码 MemcachedCacheConfig.java,以下细节值得注意:

  • hosts@NotNull必填项,格式为逗号分隔的host:port列表;
  • expiration默认 30 天:超过 30 天的值会被 memcached 解释为绝对 POSIX 时间戳而非相对时长,因此如需更长保留期需小心换算;
  • 源码中还包含文档未列出的两个进阶参数:druid.cache.readBufferSize(客户端读缓冲字节数,-1表示使用 spymemcached 默认值)与druid.cache.maxOperationQueueSize(客户端操作队列最大字节数,0表示无界),可按需微调。

4.3 实践示例

druid.cache.type=memcached druid.cache.hosts=memcache-1:11211,memcache-2:11211 druid.cache.expiration=86400 # 1 天 druid.cache.timeout=500 druid.cache.memcachedPrefix=druid_prod druid.cache.numConnections=4

五、Hybrid Cache:Local + Memcached 两级 L1/L2 缓存

5.1 原理与读取流程

Hybrid 模式组合任意两种缓存构成 L1 / L2 两级缓存,最常见的是“本地内存(L1)+ 远端 memcached(L2)”的组合,兼顾本地命中的低延迟与远端共享的命中率。

读取流程由 HybridCache.java 的get/getBulk实现:

  1. 先查L1缓存;
  2. L1 未命中(miss),再查L2缓存;
  3. L2 命中,则同时回填写入 L1,下次相同查询即可在本地直接命中;
  4. 只有两级都未命中时才算整体 miss。

写入时则是两级同时putlevel1.put(key, value); level2.put(key, value);),保证一致性。统计信息(命中、未命中、条目数、字节数、淘汰数、超时数、错误数)由两级分别统计后汇总。

从 HybridCacheProvider.java 可以看到,两级缓存通过依赖注入@Named("l1")@Named("l2")绑定,任一缺失都会直接抛出 "l1/l2 cache not specified for hybrid cache" 异常。

5.2 配置参数

PropertyDescriptionDefault
druid.cache.l1.typeL1 缓存的类型,取值同druid.cache.typelocal/memcached/hybridlocal
druid.cache.l2.typeL2 缓存的类型,取值同druid.cache.typelocal
druid.cache.l1.*L1 缓存类型的任意合法属性,均可用此前缀覆盖。例如 L1 为local时,用druid.cache.l1.sizeInBytes设置其大小与对应缓存类型的默认值一致
druid.cache.l2.*L2 缓存设置前缀,语义同 L1与对应缓存类型的默认值一致

即:druid.cache.l1.*druid.cache.l2.*各自层级的属性命名空间,其下的属性名与对应缓存类型在全局配置中的属性名一一对应。

5.3 实践示例

druid.cache.type=hybrid # L1:本地内存缓存,容量 1GB druid.cache.l1.type=local druid.cache.l1.sizeInBytes=1000000000 druid.cache.l1.initialSize=500000 # L2:共享 memcached druid.cache.l2.type=memcached druid.cache.l2.hosts=memcache-1:11211 druid.cache.l2.expiration=2592000 druid.cache.l2.memcachedPrefix=druid

六、缓存类型的选型建议

结合上述原理与源码,三种缓存类型的适用场景可以归纳如下:

场景推荐类型理由
单机 / 小集群、查询重复度高、延迟敏感local零网络开销,命中延迟最低;注意同步增大 JVM 堆内存
多节点共享缓存、堆内存紧张、节点间结果可复用memcached缓存不占 Druid 堆内存,所有节点共享同一份结果
兼顾本地低延迟与远端高命中率hybridL1 承担热点、L2 兜底并回填,是生产环境最均衡的方案

无论选择哪种类型,都需要在公共配置文件中统一定义(如examples/conf/druid/_common/common.runtime.properties),从而让 Broker、Historical 等进程复用同一份缓存配置;同时配合各进程的druid.<process>.cache.useCachedruid.<process>.cache.populateCache开关控制具体行为。缓存命中率、淘汰数与内存占用等指标,可通过CacheStatsCacheMonitor上报到 Druid 的监控体系中进行观测与调优。

【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址: https://gitcode.com/gh_mirrors/druid7/druid

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询