news 2026/9/29 16:39:19

Memcached stats命令全解析:从基础字段到内存分配排查实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Memcached stats命令全解析:从基础字段到内存分配排查实战

1. 先把话说在前面:为什么你必须学 stats 命令

聊到 Memcached 排查,大部分人第一反应是看监控面板、看缓存命中率曲线,真正落到命令行敲stats的人反而少。我在生产环境踩过几次坑之后,越来越觉得stats命令才是 Memcached 运维里最被低估的利器。它不需要任何额外组件,一条命令就能把整个实例的运行状态、内存分配、对象数量、淘汰情况全部拉出来,比很多可视化监控都来得真实、来得及时。

严格来说,stats不是单条命令,而是一族命令,包括基础的stats、stats settings、stats slabs、stats items、stats cachedump、stats sizes等等。每条命令回答的问题都不一样:实例整体状态怎么样、配置参数实际生效没生效、内存分得合不合理、哪些 key 是僵尸数据、当前热点数据规模有多大。学完这一族命令,排查 Memcached 问题时你基本能做到不慌不忙——先stats看整体,再stats settings核对配置,接着stats slabs和stats items定位内存和淘汰问题,最后用stats cachedump去抽查具体数据。这一套流程走下来,绝大多数线上异常都能定位到根因。

这篇博文面向三类人:刚接触 Memcached、对着命令手册一头雾水的入门运维;已经部署了 Memcached 但只靠监控面板看数据的开发;以及正在排查线上缓存异常、需要快速定位问题的工程人员。我尽量把每个字段讲透,不只是告诉你它“是什么”,更重要的是告诉你“异常时它可能说明什么”。命令本身很简单,难的是看懂数字背后的含义。

2. 动手之前:先搞定进入 Memcached 命令行的三种方式

stats命令要发挥作用,你得先能跟 Memcached 对话。Memcached 默认监听 TCP 11211 端口,走的是自己的文本协议,说白了就是你能用任意一个 TCP 客户端连上去发命令、收响应。常见的连接方式有三种。

2.1 用 telnet 直连

最经典的方式,内存里敲几行命令就能看结果:

telnet 127.0.0.1 11211

连上之后直接敲stats回车,响应是一堆STAT开头的键值对,最后一行是END。如果你在 Windows 上遇到telnet命令找不到,那是系统默认没装 Telnet 客户端,去“控制面板 - 程序 - 启用或关闭 Windows 功能”里勾选“Telnet 客户端”即可。

2.2 用 nc(netcat)更顺手

telnet 交互式体验其实有点别扭,尤其你想在脚本里跑stats抓结果时。更推荐用 nc:

printf 'stats\nquit\n' | nc 127.0.0.1 11211

或者用 bash 的/dev/tcp虚拟设备,不需要装任何额外工具:

exec 3<>/dev/tcp/127.0.0.1/11211 && printf 'stats\nquit\n' >&3 && cat <&3

2.3 程序里怎么调用

如果你是开发者,想在自己的服务里探一下某个 Memcached 实例的状态,不用绕弯子,直接用客户端的 API。PHP 的Memcached::getStats()、Python 的pymemcache.Client.stats()、Go 的github.com/bradfitz/gomemcache里遍历服务器逐个Stats(),都能拿到和命令行一样的字段。这个在排查多实例部署时特别有用,不用挨个 telnet 上去。

需要注意的是,Memcached 默认配置允许来自任意地址的访问,这属于历史遗留设计。生产环境务必加-l 127.0.0.1只监听本机,或者用防火墙限制 11211 的访问来源。如果外网能直接连到你的 11211,别人不用入侵你的业务系统,先把你缓存里的数据拖走再说,这个不是危言耸听。

3. 基础 stats:一整块实例状态的“体检报告”

连上之后第一条命令就是stats,不带任何子参数。它会返回当前实例所有可访问的统计指标。这里我不打算逐个字段复读手册,而是挑出在实战中真正需要盯的字段,讲讲它们能说明什么问题。

3.1 先看几个“时长”类字段:instance 活了多久

响应里的uptime字段是实例自启动以来经过的秒数,time是当前服务器时间戳,version是版本号。这三个字段要合在一起看。有一次我排查一个诡异的“缓存变慢”问题,一查uptime发现实例才跑了不到 200 秒,说明 Memcached 刚被 OOM 干掉又被守护进程拉起来了——监控指标曲线看半天没看出名堂,其实实例根本就是刚重启的“新家伙”。所以看到任何异常指标,先确认uptime是否足够长,排查思路会清晰很多。

3.2 命中率相关字段:命中率低不要慌,先分场景

get_hits和get_misses是 Memcached 收到 get 请求后命中和未命中的累计次数。命中率就是get_hits / (get_hits + get_misses)。很多文章直接说“命中率低于 90% 就不正常”,但我想给个补充视角:命中率低不一定代表缓存配置有问题,要结合业务场景判断。比如业务刚上线,缓存里没有数据,冷启动时期命中率低是正常的;再比如缓存的数据天然就不是高频访问型,比如后端回源也很快,那命中率低也未必是问题。关键要看命中率的趋势是否稳定、是否随流量正常波动。

更值得关注的字段其实是cmd_get和cmd_set的比例。如果你发现cmd_set远远大于cmd_get,说明业务在疯狂写缓存,但读得非常少——这种场景下缓存大概率没起到应有的作用,很可能是代码逻辑把缓存当临时存储用了。

3.3 连接相关字段:不是连接数越多越好

curr_connections是当前打开的连接数,total_connections是实例启动以来累计接纳的连接数。有个新手容易踩的坑:一看curr_connections很高就觉得有问题。实际上,Memcached 对每个 TCP 连接内部会维护一个结构体,连接数太多确实会占用内存,但判断标准要看curr_connections相对maxconns的比例。默认maxconns是 1024,如果连接数持续贴着上限,客户端拿不到连接就会超时,这时候才需要认真处理。

rejected_connections(部分新版才有)表示因超过最大连接数而被拒绝的连接数,这个值只要在增长,说明客户端连接池配置不合理的可能性非常大。

3.4 线程相关字段:确认是不是多线程在干活

threads字段显示当前 worker 线程数,默认是 4,可以通过-t参数调整。大多数场景下 4 个线程足够用了,因为它处理的是内存操作,不像磁盘 IO 容易卡。但如果你的日志里频繁出现Memcached: connection reset by peer,同时 CPU 使用率又很高,可以尝试把线程数调高到 8 或 16,实测下来对高并发读场景有一定改善。

3.5 字节类字段:估算内存占用时别忽略连接结构

bytes是当前存储数据占用的字节数,bytes_read和bytes_written是网络 IO 累计读写的字节数。这里要特别说明:bytes只是数据本身占用的内存,不算 Memcached 自身管理元数据和连接结构的开销。实际每个 item 还会带着 key、标志位、过期时间等元数据,所以当你看到bytes离limit_maxbytes(也就是最大内存上限,通过-m参数设置)还很远时,不代表内存一定安全。真实内存占用会明显高于bytes。我在排查一次内存溢出问题时,bytes显示只用了 3GB,但实际进程已经吃掉 5GB 了。

3.6 淘汰类字段:这三兄弟要连起来读

evictions、reclaimed、expired_unfetched这三个字段是判断缓存健康度的关键,放在 3.7 细讲。evictions是内存不足时被强制淘汰的 item 数量。正常情况下,这个值会缓慢增长。但如果它在短时间内暴涨,意味着内存容量触及上限,并且有大量新数据写入把旧数据挤了出去。你可能会问:缓存本来就有淘汰机制,淘汰不是正常的吗?问题在于淘汰意味着该数据后续访问时必然 miss,如果淘汰的数据恰好是热点数据,就会引发缓存雪崩级别的一连串回源压力。

3.7 三个容易看走眼的字段:curr_items、total_items、expired_unfetched

curr_items是当前存储的 item 总数,total_items是启动以来累计写入的 item 总数。注意,total_items包括了被写入又淘汰掉的,所以这个值只涨不跌。如果你发现total_items增长非常快但curr_items保持稳定,说明数据处于高频写入高频淘汰的状态,需要思考是不是 key 设计得太碎、TTL 设置得太短。

expired_unfetched是“已过期但从未被读取过”的 item 数量。这个字段特别有意思:它反映的是那些写入之后压根没人读的数据,属于纯浪费。如果这个值占curr_items的比例很高,说明业务代码里有一批没有被消费的“死数据”,排查思路是去检查写入缓存的 key 是否真的被读取过。

3.8 哈希表相关字段:hash_power_level和hash_bytes

hash_power_level是哈希表的幂次,hash_bytes是哈希表占用的内存。Memcached 会自动扩容哈希表。当你curr_items很多但hash_power_level很低时,理论上查找速度会变慢,不过 Memcached 对这种场景做过多轮优化,实际影响有限。我提它的目的在于,有些“性能问题”其实是哈希表在扩容时短暂锁表导致的延迟尖刺,基本面查这个字段能帮你快速排除。

提示:基础stats命令返回的字段在不同版本之间略有差异——比如老版本没有rejected_connections和expired_unfetched。如果你在对比不同版本实例的字段,先确认版本,别拿着新版字段去比旧版数据,容易得出错误结论。

实战中我通常会写一个简化版脚本,把stats输出解析成可读格式。这就涉及到几乎所有 Memcached 命令的统一格式:响应是STAT <字段名> <值>,以END结束。解析时逐行处理即可。为了验证命中率,脚本里算了get_hits/(get_hits+get_misses);为了看内存余量,算了limit_maxbytes - bytes。这个小脚本比很多监控面板直观得多,监控面板的采样周期内如果实例重启过,很多指标就失真了。

4. stats settings:核对“你以为的配置”和“实际生效的配置”

配置参数这件事,我吃过不止一次亏。启动 Memcached 时敲的参数你以为生效了,实际上可能因为多个启动脚本互相覆盖、环境变量优先级等问题,最终跑起来的配置跟你预期完全不一样。stats settings就是用来核对运行时真实配置的,它把当前实例有效配置项全部拉出来。

4.1 核心内存参数:maxbytes和factor

maxbytes对应-m参数,单位是字节。比如你想设置 512MB,启动参数写-m 512,这里就显示 536870912。factor对应-f参数,默认是 1.25,它决定 slab 内存分配时各个 class 之间的内存块大小增长倍数,后面讲stats slabs时你会看到它的实际作用。

4.2 过期与淘汰策略参数

maxbytes决定了总容量,但具体怎么淘汰,要看eviction策略。stats settings里的evictions字段(注意跟基础 stats 里的 evictions 字段重名,但含义不同,settings 里的是配置策略值)显示当前淘汰策略,默认是lru,也就是当内存满时按 LRU 顺序淘汰。如果你改成unfetched或notransfer,优先级逻辑会变,生产环境默认lru基本是正确的选择,不太需要动。

expirezero_holds_empty是一个很容易被忽略的字段:当设置为 true 时,TTL 为 0(永不过期)的 item 在内存压力下即使变成空也不会被立即回收。这个配置直接影响stats里curr_items和expired_unfetched的数值关系,排查“内存没降下来”的问题时需要关注。

4.3 连接与协议参数

maxconns、tcpport、udpport这些很好理解。binding_protocol显示当前协议是auto-negotiation、binary还是ascii。老的客户端只支持 ascii 协议,新的二进制协议性能更优。这里的坑在于,如果你在配置文件里指定了二进制协议,但客户端库用的是老版本只支持 ascii,连接会失败或者表现怪异。这时候stats settings一查,一目了然。

4.4 从排查场景反推 settings 使用技巧

举个例子:线上缓存 miss 率突然飙升,你想确认是不是缓存服务被重启了,最简单的办法是看stats的uptime和time;但如果你想确认是不是启动参数里的-m被人改小过,就必须stats settings看maxbytes。有一次我的经历是:明明部署文档里写了-m 2048,结果maxbytes显示只有 268435456(256MB),一追查发现运维脚本里有一行旧配置覆盖了启动参数。这种问题如果不查运行时配置,单靠看部署文档根本发现不了。

stats settings还有一个常用场景是排查客户端超时问题。客户端连不上、读超时,除了查网络,还要确认服务端maxconns是不是太小、连接是否被拒绝。stats settings查完maxconns、stats查完curr_connections,基本能定性。

4.5 关于统计子命令的一个关键错误观念

很多人以为stats settings里能看到统计功能开关。实际上,Memcached 的统计收集机制不是“可开关”的,而是常开的。统计本身对性能的影响很小(主要是原子计数器增加),所以不存在“为了性能关闭统计”这种操作。真正跟“开关”有关的是stats detail on/off,它控制的是更细粒度的 per-slab 统计是否收集,默认关闭。如果你需要看stats items的详细分布,偶尔需要先开启 detail 模式,但生产环境不建议长期开着,因为会额外增加少量开销。

5. stats slabs 和 stats items:内存分配的“透视镜”

这两条命令是排查内存问题时的核心工具,但很多人把它们混为一谈。简单区分:stats slabs以 slab class(内存分块等级)为维度,告诉你每个等级的内存块分配了多少、用了多少;stats items以 item 为维度,告诉你每个 slab class 里有多少 item、过期情况、淘汰情况。两者要配合着看,才能完整还原内存分配全貌。

5.1 slab 机制:Memcached 内存分配器是怎么工作的

不理解 slab 机制,看stats slabs会一头雾水。Memcached 为了避免频繁调用 malloc/free 造成内存碎片,把内存按“块大小等级”预先切分。启动时-f指定增长因子,默认 1.25,也就是 96 字节、120 字节、150 字节……逐级增长。每个等级称为一个 slab class,编号从 1 开始;每个 class 内有多个 page(默认 1MB 一个),每个 page 又切分成若干固定大小的 chunk。

用停车场来类比:停车场划分了若干区域,每个区域只停一种尺寸的车。来了一辆尺寸接近某一区域的车,就停到该区域对应的车位上;如果某个区域的车位满了,后来的车只能去更大的区域找位置,或者直接走人(淘汰)。这解释了为什么一个 key 只有 50 字节,可能占用 96 字节的 chunk——存不下更小的 chunk 了,这就是“内存浪费”的根源。

stats slabs的每个 class 会返回若干字段,其中几个关键字段:

  • chunk_size:这个 class 内每个 chunk 的字节数。
  • chunks_per_page:一个 page 能切出多少个 chunk。
  • total_pages:分配给这个 class 的 page 数量。
  • used_chunks:已经被使用的 chunk 数量。
  • free_chunks:尚未分配出去的 chunk 数量。
  • get_hits/get_misses:针对这个 class 的命中情况。

5.2 看懂 slab class 分配是否健康

正常情况下,不同大小的 key 会落在不同 slab class 里。如果某个 class 的free_chunks长期为 0,而total_pages快速增长,说明该尺寸的数据在大量写入。如果新增数据用光了所有 page,就会触发 eviction,stats items里对应 class 的evicted字段会增长。

真正的判断技巧在于:观察total_pages的分布是否与业务数据大小分布匹配。我有一个实际案例:业务里大量存储 200 字节左右的小对象,理论上应该集中在某个低编号 class,但stats slabs显示高编号 class 占了大量 page,低编号 class 的free_chunks却有很多空余。一查代码发现,存储时顺手把数据序列化成了 JSON 字符串,再加上一个很长的 key,实际 item 膨胀到了好几 KB,导致落在高编号 class 里。这解释了为什么内存老是不够用——数据本身的膨胀远比数量增长更致命。

5.3 stats items:过期和淘汰的细节都在这里

stats items的输出按 slab class 分组,格式类似STAT items:1:number 123。新版本还支持按 TTL 维度拆分统计。几个重点字段:

  • number:该 class 内当前 item 数量。
  • age:该 class 内最老 item 存活时长(秒)。
  • evicted:该 class 内被淘汰的 item 累计数量。
  • evicted_time:最近一次淘汰距离现在多少秒。
  • outofmemory:因内存不足无法写入而被拒绝的操作次数。
  • tailrepairs:LRU 尾部修复操作次数(这个属于比较深的领域,正常情况忽略)。

这里有个关键认知:stats items里的age能帮你判断冷热数据分布。如果有个 class 的age特别大(比如几百秒甚至几千秒),说明有一条长期不更新的数据躺在缓存里。如果业务预期是短缓存(比如 TTL 30 秒),但age却上千秒,说明 TTL 没传对,代码里可能把过期时间写成了 0(永不过期)。

最常见的一个误判场景:stats items显示某 class 的evicted在涨,你以为是内存不足。但结合stats slabs看,该 class 的total_pages未达到上限,其他 class 还有充足空余。这种“局部淘汰”往往不是全局内存不足,而是该尺寸类的 chunk 不够用,其他 class 帮不上忙。加上-f的分配粒度限制,这种不均衡其实很难完全避免。优化思路包括调整-f因子让分配更细,或者在业务侧统一 key 和 value 的大小范围。

5.4 从内存视角看,什么时候该报警

我自己的经验阈值是这样的:

  • evictions持续增长且每秒超过几十次——需要立即关注。
  • outofmemory大于 0——说明有新数据因为内存不足写不进去,对业务来说这是比淘汰更严重的问题。
  • stats slabs显示某个 classfree_chunks几乎为 0 但其他 class 大量空闲——先考虑业务侧数据大小分布,再决定是否调-f。
  • stats items的age远大于业务 TTL——优先查代码里过期时间参数是否被忽略。

可以做一个简化版的内存分配报告脚本,把stats slabs和stats items合并起来,按 class 输出“使用率、chunk 浪费率、淘汰数”,再配合stats settings里的maxbytes算总占用率。这套东西跑出来,比商业监控面板的“内存使用率”曲线更有诊断价值,因为后者只告诉你“满了没满”,前者能定位“哪里满的、为什么满的”。

6. stats cachedump 和 stats sizes:探查具体缓存的“显微镜”

如果说前面几组命令是宏观体检,stats cachedump和stats sizes就是微观切片。它们的场景是:你想知道某个 slab class 里到底存了哪些 key、一个 key 大概占多大。

6.1 stats cachedump 的基本用法与限制

stats cachedump <slab_class> <limit>可以列出一个 slab class 里最多limit个 item 的 key、expiration time 和 value 大小。示例:

stats cachedump 5 100

注意它的使用限制:只支持 ASCII 协议,二进制协议客户端不一定能直接调用;只返回指定 slab class 的 item,而且受限于 LRU 尾部扫描机制,不是全量精确列表,更接近“抽样”。所以它适合用来确认某个 class 里大概存了什么数据,不适合用来做全量 key 枚举。

实际场景里最有用的用法是“定位异常 key”:当你发现某个 slab class 的evicted和outofmemory同时增长,你很好奇是谁占的空间,就可以stats cachedump看看。我排查过的一个案例:某个 class 里全是带时间戳的日志 key,value 动辄几 KB,导致该 class 频繁淘汰。stats cachedump把这个 class 的 key 列出来之后,问题立刻清楚了——业务代码把缓存当日志存储使用了。

6.2 从 cachedump 反推 key 设计是否合理

stats cachedump还有一个更高级的用法:验证 key 是否可预测。如果你发现某个 class 里大量的 key 带有极长前缀、带随机字符串或时间戳,说明 key 设计不合理。这会导致两个问题:一是 key 本身占用 chunk 空间,二是前缀过于随机可能影响哈希分布的局部性,从而影响查找效率。业务侧应尽量使用短且有意义的 key,同时统一长度范围。

6.3 stats sizes:快速掌握 value 大小分布

stats sizes输出当前各 item 大小分布。它会按 value 大小的幂次区间统计,例如小于 64 字节、64-128 字节、128-256 字节等各个区间的 item 数量。这个命令在以下场景特别好用:你想评估-f因子是否需要调整。如果大量数据集中在 128-256 字节区间,你却用默认 1.25 的因子把 chunk 等级在 96、120、150、188 这种步长上切分,就会有明显的空间浪费。调整方案可以是改用-f 1.10或者-f 1.05让 chunk 粒度更细,减少小对象占用大 chunk 的浪费。

不过要注意:stats sizes在 Memcached 1.5.x 及更早版本里性能较差,因为它需要遍历整个缓存项列表来计算分布,对高并发实例影响明显。如果实例正在承担大量业务流量,我不建议随手执行这条命令,建议在低峰期使用,或者只在测试环境验证。

6.4 flush_all:一个和统计强相关的“危险命令”

排查过程中很多人会顺手执行flush_all清空缓存。这里面有个容易被忽略的事实:flush_all并不是“立刻清空所有 item”,而是通过“逻辑失效”机制——所有新写入的数据会替换旧数据,但旧数据占用的内存不会瞬间释放,而是等自然过期或被淘汰。所以你在执行flush_all之后立即看stats,curr_items可能没有变成 0,bytes也可能还有残值。这种现象让不少人误以为flush_all没生效,其实是理解错了机制。

更关键的是:生产环境执行flush_all前必须确认自己对业务影响是否有完整预期。清空之后,所有客户端请求都会 miss 并回源,如果回源数据库扛不住,那就不是缓存命中率问题,而是整个服务雪崩的问题。我在一个高并发项目里见过一次误操作,flush_all之后数据库连接数被打满,直接引起线上故障。所以我的建议是:排查阶段先用stats系列定位问题,别动不动就 flush。

7. 通用参数reset和detail on/off:统计数据的“清零”与“加细”

stats系列的累计计数器有个特点:从实例启动开始累计。这带来一个问题:你无法知道某个时段内的增量变化,只能看整体累计。这时候stats reset就派上用场了。stats reset会把所有累计计数器(如get_hits、get_misses、cmd_get、cmd_set、evictions等)清零。注意:curr_items、uptime、bytes这类“状态值”不会被清零,因为它们不是累计值。

实际操作建议:清空之前先记录一份基线数据,清空后过一段时间再拉数据,这样能快速算出该时段内的真实增量。比如怀疑线上在某个时间点开始出现大量淘汰,你可以在修复后执行stats reset,过 15 分钟再拉一次,看evictions涨了多少。这个方法比对比两个大时间点的差值来得更直观。

stats detail on开启 per-key 级别的计数统计,stats detail off关闭,stats detail dump输出统计结果。这个功能主要用来定位“哪个 key 被访问最多”,但开启后每台服务器上额外维护的信息会增加内存和 CPU 开销,所以线上默认不开启。如果你需要做短期的热点 key 分析,可以在低峰期开启跑一段时间,分析完立刻关掉。

8. 实操实录:一套 stats 排查流程的完整推演

空谈理论没意思,我拿一个真实的排查场景完整走一遍流程,你看完就能照搬。

8.1 场景描述

某在线服务高峰期缓存命中率从 96% 跌到 80%,监控面板显示内存使用率接近 90%,CPU 没明显异常。业务侧反馈有大量请求回源数据库,数据库负载明显上升。

8.2 排查步骤

第一步,连上实例执行基础stats,先看uptime和version,确认实例没被重启,版本正常。

第二步,仔细读几个关键字段:get_hits和get_misses计算命中率,确认 80% 属实;再看curr_items、bytes、limit_maxbytes,确认内存确实接近满。

第三步,执行stats settings查maxbytes和maxconns,确认配置未被改动。

第四步,执行stats slabs看各 class 的total_pages、used_chunks、free_chunks。发现编号较高(对应 2KB-4KB 尺寸)的 class 占用了大量 page,且其free_chunks极低,evicted在增长。而编号较低的 class(几十到几百字节)反而有大量空闲 chunk。

第五步,执行stats items定位具体 class 的evicted、evicted_time、age等字段,确认淘汰集中发生在高编号 class,且淘汰频繁程度在秒级。

第六步,执行stats cachedump抽查该 class 的 key 列表。发现里面有大量以“temp_report”为前缀、value 约 2KB 的数据。结合业务知识一核对,这是业务侧某个后台任务把用户行为report缓存到了 Memcached,且未设置 TTL,导致数据长期占用内存无法释放,最终把其他 class 的内存挤占,影响正常缓存命中。

8.3 问题根因与解决

根因清楚了:后台任务写入的“僵尸数据”占了内存大头,触发了淘汰风暴。解决方式是给这类任务数据设置较短 TTL(比如 10 分钟),同时在代码层面做数据大小限制;对已经存在的脏数据,使用flush_all或通过程序逐步删除。

实际操作中我们用stats reset清零计数,观察 10 分钟后的evictions增量来验证修复效果,明显看到淘汰量下降。这套流程从接到反馈到定位根因,大概用了不到半小时,效率远高于翻日志。

9. 避坑速查表:排查 Memcached 时最容易犯的错

为了让这篇内容能直接当工具用,我把这多年踩过的坑整理成一张速查表,每条都对应一个具体命令和判断方法。

现象可能原因用哪条命令验证规避要点
命中率突然下跌实例重启、key 前缀变更、数据冷启动stats看uptime先确认 uptime,别急着动缓存代码
内存“没满”却大量淘汰单 class 内 chunk 耗尽,全局内存却有富余stats slabs+stats items关注各 class 分配不均,而非只看总内存
flush_all后curr_items没归零逻辑失效机制导致内存未立即释放stats看curr_items不要重复执行 flush_all
连接数持续走高且拒绝增长客户端连接池未复用或配置过大stats看连接字段 +stats settings看maxconns检查客户端连接池配置,而不是盲目调高 maxconns
stats sizes执行后性能下降该命令遍历全部 item,开销较大用stats slabs替代或低峰期执行高并发实例慎用
配置了-m 1024但maxbytes不对有启动参数覆盖或环境变量干扰stats settings以运行时配置为准,别信启动脚本
stats cachedump看不到某些 key二进制协议或 LRU 尾部扫描限制确认调用端协议类型用 ASCII 协议工具执行

这张表并不能覆盖所有情况,但覆盖了大部分真实世界中会遇到的问题。收藏下来,排查时对照着看,能省下不少冤枉时间。

10. 我个人最后想分享的一点经验

Memcached 这套stats族命令的真正价值,不在于让你能背出每个字段,而在于它能让你用一种“立体”的视角去看缓存系统。初学者往往只看stats的基础字段,仿佛那就能说明一切;真正排过几次大故障之后你会发现,组合使用stats settings、stats slabs、stats items、stats cachedump这四位一体,才能构建出完整的问题叙事。而且这种能力跟用不用商业监控无关——就算监控平台能力再强,你亲手在命令行里敲出来的数据永远是最真实的,因为它没有采样丢失、没有时序偏差。

还有一个很小的技巧想分享给看这篇内容的读者:在做任何 Memcached 变更前后,都设计一个“前后对照”习惯。变更前拉一次完整stats,记录关键字段的值;变更后再拉一次,对比增量。这看起来很简单,但能省掉大量“做了操作但不确定有没有生效”的纠结。我就靠这个习惯,解决过不少配置没刷上去、修改没生效的疑难杂症。工具本身是死的,怎么用、用得好不好,全看平时的积累和习惯。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 16:39:19

starnet 桌面 AI Agent 框架:MCP 协议与本地优先架构实战

1. 从“starnet”这个名字说起&#xff1a;它到底想解决什么问题第一次看到“starnet”这个项目标题&#xff0c;加上旁边跟着的AI agents、desktop harness、local-first、MCP这几个关键词&#xff0c;我脑子里第一反应是&#xff1a;这又是一个想把 AI 能力从浏览器标签页里拽…

作者头像 李华
网站建设 2026/9/29 16:38:33

SecureCRT for mac 安装配置与避坑指南

简介&#xff1a;SecureCRT 是老牌远程终端连接客户端&#xff0c;这个 macOS 版本面向经常通过 SSH、Telnet 等协议登录服务器、交换机等设备的开发与运维人员&#xff0c;解决了在 Mac 上找不到稳定好用的终端工具、又不想费心处理破解授权的问题。压缩包内含可直接运行的免破…

作者头像 李华
网站建设 2026/9/29 16:38:00

Windows MySQL自动备份bat脚本:定时备份与30天清理实践

Windows服务器上跑MySQL&#xff0c;最让我头疼的从来不是SQL写不好&#xff0c;而是备份这件事。装个图形工具固然省心&#xff0c;可一旦机器没装桌面环境、或者半夜两点数据库被搞挂了&#xff0c;能救命的往往还是那条不声不响的bat批处理脚本。这篇我把自己一直在用的自动…

作者头像 李华
网站建设 2026/9/29 16:37:55

从零搭建AI工程体系:数据管道、模型训练与推理服务实战指南

从零搭建AI工程体系这件事&#xff0c;我前前后后折腾过三轮。第一轮是2019年前后&#xff0c;那时候大家还在争论"算法工程师要不要会写后端"&#xff1b;第二轮是2022年大模型爆发&#xff0c;一堆人冲进来发现光会调API根本撑不住线上流量&#xff1b;第三轮就是现…

作者头像 李华
网站建设 2026/9/29 16:37:52

IE9离线安装包部署指南:前置补丁、静默安装与报错排查

简介&#xff1a;面向Windows 7 64位用户的IE9离线安装包&#xff0c;让你在没有网络或网络不稳定的情况下&#xff0c;也能完整安装Internet Explorer 9浏览器&#xff0c;特别适合多台电脑批量部署或对下载速度不敏感的场景。压缩包共4个文件&#xff0c;体积90.65MB&#xf…

作者头像 李华
网站建设 2026/9/29 16:36:57

车辆安全系统深度解析:从AEB到ESP,判断一辆车真正安全的关键

1. 车辆安全系统到底怎么理解&#xff1a;一次从“保命”到“怕事故”的进化先说说这个标题本身。大家一看到“超棒的车辆安全系统”&#xff0c;第一反应多半是“又有人在吹配置”。但我在汽车行业摸爬滚打这些年&#xff0c;见过太多把安全配置当营销卖点、却说不清原理的车主…

作者头像 李华