资讯动态

Loki 缓存配置实战:用 Memcached、Redis 与嵌入式缓存加速查询

发布时间:2026/9/12 7:18:56 来源:尧图企业网站定制
Loki 缓存配置实战用 Memcached、Redis 与嵌入式缓存加速查询【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki本篇指南以 Loki 官方的缓存运维文档为主线系统讲解 Loki 的查询结果缓存results cache、Chunk 缓存chunks cache以及 L2 分级 Chunk 缓存的原理与配置方法覆盖 Memcached、Redis、嵌入式缓存三种可互换的后端并给出 Helm chart 与原生 Loki 配置两种落地方式。读完本文你将能够独立部署 Memcached、在 Loki 配置文件中启用各类缓存、按查询类型拆分缓存实例并利用 L2 缓存与 memcached-extstore 应对集群扩容带来的缓存容量压力。缓存能解决什么问题Loki 对查询结果、Chunk 数据和索引查询提供多级缓存能力目的是加速查询性能并减少对存储层的调用。当用户反复查询相同的时间范围、相同的日志流时命中缓存的请求可以跳过对象存储与索引查询直接返回结果。在 Loki 的 Helm chart 中Memcached 已被内置并通过chunksCache与resultsCache默认启用。本文后续内容以 Memcached 为推荐后端逐步说明其启用与调优方式。三种可互换的缓存后端Loki 中的每一个缓存chunk_cache_config、results_cache等都可以使用三种后端之一配置结构统一由 pkg/storage/chunk/cache/cache.go 中的Config承载后端配置段适用场景Memcachedmemcachedmemcached_client生产环境、多副本部署的首选。缓存共享于组件的所有实例容量可横向扩展Redisredis可用的替代外部缓存通过redis.endpoint指定服务地址嵌入式缓存embedded cacheembedded_cache存放在 Loki 进程自身内存中不跨副本共享适合单二进制或小型部署三个后端的判定逻辑在 cache.go 中实现只要配置了memcached_client.host或memcached_client.addresses即视为启用 Memcached配置了redis.endpoint即视为启用 Redisembedded_cache.enabled: true即启用嵌入式缓存。一个缓存只能配置一个后端每个缓存只能配置一个后端。源码中对此有显式校验当同一缓存同时设置了 Memcached 和 Redis 时New函数会直接返回错误use of multiple cache storage systems is not supported见 cache.goLoki 将无法启动。未配置后端时的自动回退如果某个缓存既没有配置 Memcached 也没有配置 RedisLoki 会自动为该缓存启用嵌入式缓存保证缓存开箱即用。该自动回退适用于Chunk 缓存chunk_cache_config查询结果缓存results caches但它不适用于索引查询缓存index queries cache和写入去重缓存write dedupe cache这两个缓存在未显式配置时保持关闭状态。需要注意的是嵌入式缓存是进程级的每个 Loki 副本各自维护一份多副本部署下命中率与一致性都受限因此自动回退不能替代 Memcached 或 Redis。嵌入式缓存的容量与过期参数默认最大 100 MB、TTL 默认 1 小时定义在 pkg/storage/chunk/cache/embeddedcache.go 的EmbeddedCacheConfig中可通过embedded_cache.max_size_mb、max_size_items、ttl调节。查询结果缓存Results cache结果缓存存储查询结果使后续相同查询可以直接复用并支持对日志查询进行负缓存negative caching即缓存无结果的空查询避免反复扫描。该缓存由 query-frontend 组件负责查询与写入在部分配置中也被称为 frontend cache。其工作流程为query-frontend 在收到查询时先查结果缓存如果缓存的结果不完整frontend 会计算所需的子查询并下发给 querier 执行随后再把结果写入缓存。整个协调过程以查询哈希query hash作为缓存键该哈希被计算后存入请求头中贯穿查询与命中的全过程相关实现在 pkg/querier/queryrange/roundtrip.go。六个按查询类型拆分的缓存结果缓存本质上是在query_range配置段下的一组六个独立可配置的缓存每种查询类型一个查询类型启用开关缓存配置指标查询与日志查询cache_resultsresults_cacheIndex-stats 查询cache_index_stats_resultsindex_stats_results_cacheVolume 查询cache_volume_resultsvolume_results_cache瞬时指标查询instant metriccache_instant_metric_resultsinstant_metric_results_cacheSeries 查询cache_series_resultsseries_results_cacheLabel 查询cache_label_resultslabel_results_cache这些开关与配置项在 pkg/querier/queryrange/roundtrip.go 的Config结构体中定义。其中几个开关在 CLI 参数上的默认值值得注意见RegisterFlagscache_index_stats_results、cache_volume_results、cache_series_results、cache_label_results默认均为true而cache_instant_metric_results默认是false需要显式开启。配置回退规则如果某个查询类型的缓存开关已启用但其缓存配置留空Loki 会自动回退使用results_cache的配置。这意味着只配置results_cache一处即可让所有查询类型都获得缓存只有当你想让某个查询类型使用不同的Memcached / Redis / 嵌入式缓存实例时才需要单独给它一份缓存配置。索引查询缓存与 TSDB索引查找缓存index lookup cache只支持遗留的 BoltDB 索引存储并且默认配置为内存缓存。Loki 迁移到 TSDB 索引后磁盘/持久卷本身被用作索引缓存内存中的索引查找缓存已经过时。因此使用 TSDB 索引格式时不需要为索引查询配置缓存相关说明可参考仓库内的 docs/sources/operations/storage 目录。Chunk 缓存Chunks cacheChunk 缓存使用chunkRef作为缓存键——chunkRef是 Loki ingester 切割 Chunk 时生成的唯一引用。querier 在计算出一组chunkRef用于服务查询时会先查 Chunk 缓存再去存储层拉取数据从而显著降低对象存储的读取压力。Chunk 缓存与结果缓存有一个重要的容量差异查询结果相比 Chunk 数据要小得多。随着 Loki 集群摄入量增长结果缓存可以继续高效工作而 Chunk 缓存的内存需求会随数据量按比例增长。为了支撑集群不断增长的需求Loki 在 2023 年引入了对memcached-extstore的支持。Extstore 是 Memcached 的附加功能允许为 memcached pod 挂载 SSD 磁盘以最大化缓存容量Grafana Cloud Logs 曾用该方案将 Memcached 集群扩展至 50 TB 规模。L2 Chunk 缓存分级缓存架构作为 memcached-extstore 的替代或补充方案Loki 支持第二层L2Chunk 缓存通过chunk_cache_config_l2与l2_chunk_cache_handoff两个配置项启用。工作原理l2_chunk_cache_handoff是一个年龄阈值年龄小于该阈值的 Chunk读写均走你在chunk_cache_config中配置的主缓存L1年龄大于该阈值的 Chunk读写改走 L2 缓存取值为0时 L2 缓存被禁用。两个层级之间不会复制或移动条目每个 Chunk 根据请求发生时的年龄被路由到其中一个层级。在读路径上Loki 会把阈值扩大 10%使接近边界的 Chunk 仍会在 L1 缓存中查找避免滑动窗口边界上的反复穿透。这一逻辑在 pkg/storage/chunk/fetcher/fetcher.go 中有完整实现extendedHandoff : c.l2CacheHandoff (c.l2CacheHandoff / 10)命中 L2 的 Chunk 直接从 L2 读取未命中的才进入 L1 查找与存储层回源。配置示例这样的设计让你可以保留一个小而快的近期 Chunk 缓存同时把访问频率较低的旧 Chunk 路由到更大、更便宜的第二层——例如挂载磁盘的 Memcached 实例chunk_store_config: l2_chunk_cache_handoff: 24h chunk_cache_config_l2: memcached: batch_size: 256 parallelism: 10 memcached_client: host: l2 chunk cache memcached host service: port name of memcached service在配置结构上ChunkStoreConfig同时包含chunk_cache_config、chunk_cache_config_l2与l2_chunk_cache_handoff三个字段见 pkg/storage/config/store.goCLI 对应前缀分别为store.chunks-cache.、store.chunks-cache-l2.其中store.chunks-cache-l2.handoff默认值为0。Helm chart 中的 L2 缓存如果使用 Helm chartL2 缓存在chunksCache.l2下配置默认关闭chunksCache.l2.enabled: false默认四天交接阈值chunksCache.l2.l2ChunkCacheHandoff: 345600s即 4 天chunksCache.l2.persistence设置可以为 L2 缓存 pod 挂载持久卷这是 chart 原生提供的、用于增加磁盘容量后端的方案与 memcached-extstore 思路一致。对应默认值可查阅 production/helm/loki/values.yamlL2 的 StatefulSet、Service、PDB 模板分别位于 production/helm/loki/templates/chunks-cache 目录下。开始前的准备事项在动手配置前建议确认以下几点按职责拆分 Memcached 组件推荐将查询结果缓存与 Chunk 缓存部署为独立的 Memcached 组件例如memcached_frontend与memcached_chunks避免相互影响、便于独立扩容。跟随 Helm chart 的 Memcached 镜像版本使用当前版本 Loki Helm chart 自带的 Memcached 镜像memcached.image.tag不要手动固定某个具体版本因为推荐版本会随时间更新。参考 ksonnet 部署模板如果使用 ksonnet 部署可以参考仓库内 production/ksonnet/loki 目录下的 Memcached 部署配置。TSDB 索引无需索引缓存使用 TSDB 索引格式时不需要索引查询缓存见上文索引查询缓存与 TSDB一节。容量规划关于缓存容量与集群规模的关系参考仓库内 docs/sources/setup 目录下的集群规模规划文档。启用并配置 Memcached操作步骤第一步部署 Memcached 服务每个 Memcached 服务至少部署三个副本并按用途分别配置启动参数Chunk 缓存--memory-limit4096 --max-item-size2m --conn-limit1024查询结果缓存--memory-limit1024 --max-item-size5m --conn-limit1024即 Chunk 缓存分配 4 GB 内存、单条目上限 2 MB结果缓存分配 1 GB 内存、单条目上限 5 MB查询结果通常比 Chunk 大但条目更少。第二步配置 Loki 使用缓存方式一使用 Helm chart在 values 中设置 Memcached 地址并开启对应开关chunksCache: enabled: true addresses: chunk cache memcached 地址 resultsCache: enabled: true addresses: query result cache memcached 地址需确保 Memcached 的连接数上限至少为number_of_clients * max_idle_conns客户端数量 × 每个客户端的最大空闲连接数否则连接会被拒绝。使用自有 Memcached 实例默认情况下 chart 会自行部署并管理 Memcached 服务器。如果想改用你自己的 Memcached 集群将memcached.enabled设为false以停掉 chart 内置的 Memcached同时保持chunksCache.enabled与resultsCache.enabled为true并把addresses指向你的服务。addresses使用 chart 默认采用的逗号分隔 DNS 服务发现格式memcached: enabled: false chunksCache: enabled: true addresses: dnssrvnoa_memcached-client._tcp.chunk-cache-memcached.loki.svc resultsCache: enabled: true addresses: dnssrvnoa_memcached-client._tcp.results-cache-memcached.loki.svcdnssrvnoa前缀表示通过 DNS SRV 记录做服务发现no A 记录查询。该格式与 Loki 客户端解析逻辑对应MemcachedClientConfig的addresses字段支持逗号分隔的地址列表并可通过update_interval定期刷新服务器列表见 pkg/storage/chunk/cache/memcached_client.go。配置其余五个结果缓存Helm chart 的chunksCache与resultsCachevalues 只管理 Chunk 缓存和主查询范围结果缓存。其余五个结果缓存index_stats_results_cache、volume_results_cache、instant_metric_results_cache、series_results_cache、label_results_cache没有独立的 Helm values需要通过 chart 的loki.query_rangevalue 传入chart 会原样写入生成的 Loki 配置文件中。例如loki: query_range: cache_index_stats_results: true cache_volume_results: true方式二直接修改 Loki 配置文件如果不使用 Helm chart直接编辑 Loki 配置文件的以下两个小节。配置 Chunk 缓存chunk_store_config: chunk_cache_config: memcached: batch_size: 256 parallelism: 10 memcached_client: host: chunk cache memcached host service: port name of memcached service其中batch_size是每个工作协程一次批量获取的键数量parallelism是并发请求 Memcached 的最大协程数默认分别为 4 与 5见 pkg/storage/chunk/cache/memcached.go。上述示例针对 Chunk 数据量大的场景调高了两者。配置查询结果缓存query_range: cache_results: true results_cache: cache: memcached_client: consistent_hash: true host: memcached host service: port name of memcached service max_idle_conns: 16 timeout: 200ms update_interval: 1m关键参数说明与 pkg/storage/chunk/cache/memcached_client.go 的 CLI 默认值一一对应参数默认值作用consistent_hashtrue使用一致性哈希在 Memcached 服务器间分布键减少扩缩容时的缓存失效max_idle_conns16连接池中的最大空闲连接数需与 Memcached 端conn-limit配合timeout100msCLI 默认Memcached 操作超时时间update_interval1m轮询 DNS 刷新 Memcached 服务器列表的周期results_cache整体结构对应 pkg/storage/chunk/cache/resultscache/config.go 中的ResultsCacheConfig其cache字段直接复用通用缓存配置cache.Config因此 Memcached、Redis、嵌入式缓存三种后端在此均可互换使用。底层实现速览统一缓存接口所有缓存实现Cache接口Store/Fetch/Stop/GetCacheType见 pkg/storage/chunk/cache/cache.go。缓存之上还叠加了后台批量写入background.go、指标统计instrumented.go与 Snappy 压缩snappy.go等装饰层。组合式构建New函数按配置同时启用嵌入式缓存与外部缓存时会用NewTiered组装成分级缓存读取时先查内嵌层、未命中再查外部层命中内容回填内层见 pkg/storage/chunk/cache/tiered.go。缓存键与失效结果缓存键由租户、查询语句、分片间隔与对齐后的起始时间等拼接生成见 pkg/querier/queryrange/log_result_cache.go日志查询的结果缓存目前只缓存空过滤器查询这类容易且可安全缓存的结果。租户级缓存代数cache generation number机制用于在数据变更后整体作废旧缓存实现在 pkg/storage/chunk/cache/cache_gen.go。L2 读路径Fetcher.FetchChunks按 Chunk 起始时间与扩展 10% 的handoff 阈值分流 L1/L2先查 L1 再查 L2最后回源对象存储并回写缓存详见 pkg/storage/chunk/fetcher/fetcher.go。故障排查方向若 Loki 启动报错use of multiple cache storage systems is not supported说明同一缓存同时配置了 Memcached 与 Redis删除其中一个后端的配置即可。多副本部署下缓存命中率异常偏低优先检查嵌入式缓存的自动回退是否误用每副本独立、不共享确认memcached或redis配置确实生效。Memcached 连接被拒按number_of_clients * max_idle_conns复核--conn-limit是否足够。更系统的排障方法可参考仓库内 docs/sources/operations/troubleshooting 目录下的运维排障文档。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价