Memcached 1.6.44 已发布,这不是一个堆功能的版本,而是一个安全修复版本。对线上缓存系统来说,这类版本往往比新特性更值得关注:它修掉的是异常输入、边界条件和后台组件在高压下可能暴露的问题。
这次修了哪些风险点
这次更新集中在几个容易被忽视但影响面不小的区域。
proxy 侧修复了后端数据过大导致溢出的问题。对于启用了 Memcached proxy 的部署,这类问题需要优先看,因为 proxy 位于客户端和后端缓存节点之间,一旦边界处理出错,影响的不是单个 key,而可能是整条访问路径。
ascii 协议修复了一个崩溃场景:启用身份验证后,如果遇到空换行符,进程可能崩溃。很多老系统、脚本、sidecar 仍然在用 ascii 协议访问 Memcached,因此不能只按“我们主要用二进制协议”来判断风险。
crawler 相关修复有两个:一个是 unlocked mutex 被再次解锁,另一个是空闲客户端缓冲区溢出。crawler 通常不是业务代码直接接触的组件,但它参与内部清理和扫描,越是这种后台路径,越容易在压测、长连接、异常客户端行为下暴露问题。
binprot 方面允许禁用统计详情。统计接口经常被监控系统、排障脚本调用,细粒度统计如果不加边界,可能带来额外的信息暴露或性能成本。这个变化提示我们:生产环境不要默认把所有调试级信息都打开。
升级判断:哪些集群应该先动
如果你的部署满足下面任一条件,建议优先升级到 1.6.44:
- 使用 Memcached proxy。
- 启用了认证,尤其还有旧客户端或自研客户端访问 ascii 协议。
- 使用 crawler 相关能力,或者线上存在大量长连接、空闲连接。
- 监控系统会频繁抓取 stats、stats detail 一类信息。
- Memcached 暴露在跨服务共享网络中,而不是只在单个应用私有网络内使用。
反过来,如果 Memcached 只绑定在本机回环地址、没有认证、没有 proxy、客户端行为完全受控,风险会低一些,但安全修复版本仍然应该进入常规补丁窗口。缓存服务通常被当成“无状态基础设施”,这正是它适合快速滚动升级的原因。
可以这样做一次最小验证
下面示例用 Docker 启动 Memcached 1.6.44,并通过 ascii 协议做一次 set/get 冒烟测试。运行前需要本机已安装 Docker 和 nc。端口、内存大小、连接数按你的环境调整。
docker run --rm -d \
--name mc-1644 \
-p 11211:11211 \
memcached:1.6.44 \
memcached -m 64 -c 1024 -vv
printf 'set demo 0 60 5\r\nhello\r\nget demo\r\nquit\r\n' | nc 127.0.0.1 11211
docker logs --tail 40 mc-1644
docker stop mc-1644
预期输出里应该能看到类似下面的响应:
STORED
VALUE demo 0 5
hello
END
如果你在线上使用的是 Kubernetes,可以先把镜像版本固定到 1.6.44,再通过滚动发布替换旧 Pod。下面是一个可改造的最小 Deployment 片段:
apiVersion: apps/v1
kind: Deployment
metadata:
name: memcached
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: memcached
template:
metadata:
labels:
app: memcached
spec:
containers:
- name: memcached
image: memcached:1.6.44
args:
- memcached
- -m
- '512'
- -c
- '4096'
ports:
- containerPort: 11211
应用后可以用这些命令观察发布过程和基础连通性:
kubectl apply -f memcached-deployment.yaml
kubectl rollout status deployment/memcached
kubectl get pods -l app=memcached -o wide
POD=$(kubectl get pods -l app=memcached -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it $POD -- sh -c 'printf "version\r\nquit\r\n" | nc 127.0.0.1 11211'
如果容器镜像里没有 nc,可以临时起一个调试 Pod,或者用你们现有的连通性探测工具替代。
发布前要看三件事
升级 Memcached 本身通常不复杂,难点在于客户端和运维脚本的边界行为。
检查客户端协议。确认业务使用 ascii、binary 还是 proxy 路径;如果混用协议,灰度时要覆盖每一种客户端。
检查监控和排障命令。对于 stats detail 这类细粒度统计,生产环境应明确谁能调用、多久调用一次、是否真的需要长期打开。1.6.44 对 binprot 的变化也适合顺手清理这些脚本。
检查网络暴露面。Memcached 不应该裸露在不可信网络里。即使这次修复了认证和异常输入相关问题,也不要把补丁当成网络边界。绑定地址、防火墙、NetworkPolicy、服务网格策略仍然要到位。
采用建议
把 1.6.44 当作安全补丁发布,而不是普通小版本更新。推荐顺序是:先在测试环境跑协议冒烟测试,再选一个低风险分片或副本集灰度,观察连接数、命中率、错误率、重启次数和监控抓取行为,最后滚动全量发布。
缓存层的问题通常不会优雅地失败:它可能表现为延迟抖动、连接重试、热点 key 穿透到数据库。升级窗口里把数据库侧指标也放进看板,比只盯 Memcached 进程状态更稳妥。