进阶 docs.memcached.org 2026-10-13 18:51:48 · 22 阅读

第4章 Memcached 服务器维护与监控指南

Server Guide维护维护监控服务器健康状况

Memcached 提供大量统计计数器。大多数只是累计值,但有些可以用作提醒管理员的警告信号。网上有很多工具和类 top 程序可以帮你消化这些信息。

发起命令

监控脚本最好偶尔向服务器发起 test set/get/delete 操作,并记录每次响应耗时。如果连接慢,可能是连接数或网络出了问题;如果响应慢,服务器可能在 swap 或者状态不佳。你本该严格监控服务器健康,但多加一层监控也是值得的。

重要统计项

以下统计项可以通过向 memcached 服务器发送简单的 stats 命令获取。

curr_connections

列出当前连接的客户端数量。注意别让这个数字太接近最大连接数设置(-c)。

listen_disabled_num

名字有点晦涩,统计的是 memcached 达到连接上限的次数。达到最大连接数后,memcached 会禁用监听器,新连接进入队列等待;一旦有连接断开,监听器被唤醒,重新开始接受连接。

这个计数器每增加一次,就说明新连接开始出现延迟。务必让它保持在零或接近零。

accepting_conns

与上面的 listen_disabled_num 相关。如果你已经连上了 memcached,可以通过检查这个值是 1 还是 0,判断它是否达到了最大连接数。

limit_maxbytes

有时最好确认一下你以为的启动配置和实际启动配置是否一致。检查 limit_maxbytes 可以验证 -m 参数是否生效。使用 init 脚本的人偶尔会配置错误,导致 memcached 以默认值启动。

cmd_flush

虽然不完全算服务器健康指标,但值得常规监控。每次有人执行 flush_all 命令,缓存中的所有条目都会失效,这个计数器也会加一。有时调试代码或一知半解的人会把脚本或回调留在后台运行,不断“清空”整个缓存。在生产环境盯着这个值,一旦开始变动就报警——除非你确实是有意为之。

stats sizes

如果 memcached 以 -o track_sizes 启动,内部会做一些额外统计,更细致地展示存储数据的大小分布。

运行 stats sizes 可以看出你的条目与 slab class 的匹配程度。

警告:如果你的 memcached 版本较老(1.4.27 之前),这个命令在扫描所有条目时可能导致缓存卡死。可能非常危险!

Slab 不均衡

一个更复杂的问题是:各 slab 分配到的内存量与实际数据想去的 slab 之间不匹配。算法其实很简单,只是描述起来绕:

监控全局的 'evictions' 统计项。如果开始上涨(也可以直接跳到第 2 步)。

监控 stats items 中的 evicted 和 evicted_nonzero 统计项。evicted_nonzero 表示对象被提前逐出,且没有设置无限过期时间。这些信息是按 slab 统计的。

从 stats slabs 读取 total_pages 统计项,与上面的 evicted 数据对照。

如果逐出最多的 slab 恰好也是页数最多的 slab,那你可能真的内存不足了。

或者(也许更重要),把每个 slab 的命中率与页数做关联分析。

如果逐出最多的 slab 和页数分布对不上,你需要重启 memcached,让它重新分配内存。

较新版本的 memcached(1.4.25 及以后)内置了调优良好的自动化机制来修复这个问题,无需重启。详情参见发布说明和 https://github.com/memcached/memcached/blob/master/doc/protocol.txt。

应用健康统计

监控这些统计项可以让你了解 memcached 的可用内存如何变化、应用行为如何影响效率。

全局命中率

命中率定义为:get_hits / (get_hits + get_misses)。这个值越高,说明应用越常命中缓存结果,而不是扑空。注意这个值是否高于你的预期,并观察它随时间或应用发版的变化。

按 slab 的命中率

虽然无法精确计算每个 slab 的命中率——“get miss”并不知道丢失的条目可能有多大——但可以通过 stats slabs 按 slab 监控 get_hits 和 cmd_set 的数量。注意 get_hits 通常应高于 cmd_set(读多于写往往才是你想要的状态),并留意随时间的变化。

逐出(Evictions)

如果一个条目还有存活时间,但在分配新条目时恰好位于 LRU 链表尾部,它就会被从缓存中“逐出”。memcached 会尝试从尾部找找有没有已过期的条目,但并不保证找到。

stats items 显示每个 slab 的逐出情况。'evicted' 是该 slab 被提前逐出的条目总数,'evicted_nonzero' 是其中没有无限过期时间的条目数,'evicted - evicted_nonzero' 则是被永久存储却被逐出的条目数。

'evicted_time' 记录了最后一个被逐出的条目距离上次被访问过了多少秒。如果这个数字很小,说明你正在逐出最近刚用过的条目。

表象可能骗人

你看到命中率低、逐出率高,就以为该给 memcached 加内存了。可惜这不一定对。考虑以下几种可能:

你的应用写入了大量 key,其中大部分之后再也不会被用到。

你的应用在多数请求中查询一个或多个不存在的 key,也不会重新缓存——比如某个标志位,或者来自某个有 bug 的用户的值。

前者会导致很高的逐出次数,即使这些数据本来就不重要。审计一下应用存储了什么,看看是否存在这个问题。

后者会拉低命中率,因为大量的 get_misses 都来自这个标志。解决办法是让应用“重新缓存”一个值为“not set”的标志。这样即使标志被禁用,它仍留在缓存中,也不会干扰命中率统计。

操作系统健康(避免 swap!)

Memcached 与网络和内存交互非常密切。swap 的使用会严重拖慢 memcached,因此监控 swap 用量很常见。

同样重要的是网络栈。以 Linux 为例,网络接口有大量与丢包、下溢、CRC 错误等相关的计数器。大多数交换机也有针对每个端口的丢包或链路问题计数器。性能下降的根源可能是线路老化、交换机端口故障、网卡濒临损坏,或网络驱动需要调优。

升级

Memcached 的大多数次要版本更新专注于修 bug 和增加监控指标。新功能很少见,现在一般只在中等版本号变更时才有——比如 1.2 到 1.4 加入了二进制协议和大量计数器;1.4.0 到 1.4.1 则主要是修 bug 和补齐计数器。

小的功能也会出现。SASL 认证支持就是在 1.4 系列中期加入的,但改动是隔离的,不会破坏现有客户端。

你应该跟进新版本和发布说明。通常尽早升级更好,这样在需要时就有额外的监控指标可用,而不是出了问题才后悔没升级。

配置性能与效率

评论 (0)