Redis在Kubernetes中性能差主因是cgroups三层限制未对齐:节点预留(system/kube-reserved)压缩Allocatable资源,QoS类型影响cpu.weight权重,容器内maxmemory未按limits.memory的80%~90%梯度设置,导致OOMKilled或CPU争抢;须确保pod-max-pids启用、requests.memory≥maxmemory、并验证/sys/fs/cgroup/{memory.max,pids.max,cpu.weight}实际值。
Redis 在 Kubernetes 容器中性能差,八成是 cgroups 层没管住——不是配置没写,而是没对齐底层限制逻辑。
你在 Deployment 里写了 limits.cpu: "2" 和 limits.memory: "4Gi",但 Redis 实际跑起来还是卡顿、OOM 或被 kill,问题往往出在 cgroups 的实际生效路径上。Kubelet 并不直接把 limits 塞进 cgroup v2 的 cpu.max 或 memory.max,而是经过 QoS 类型(Guaranteed / Burstable / BestEffort)转换 + 节点级预留(--system-reserved、--kube-reserved)再裁剪。比如节点总内存 32Gi,若 --system-reserved=2Gi、--kube-reserved=1.5Gi,那留给 Pod 的实际内存上限就只剩约 28.5Gi —— 即使你设了 limits.memory: "32Gi",也会被 kubelet 静默截断。
实操建议:
kubectl describe node <node-name> 查看 Allocatable 字段,这才是 Redis 真正能争到的资源天花板ps aux | grep kubelet | grep -E "(system-reserved|kube-reserved)",确认预留是否挤占过多requests.memory 必须 ≥ redis.conf 中 maxmemory 值,否则容器可能在 Redis 自身触发淘汰前就被 OOMKilledRedis 本身不 fork,但如果你用了 save 持久化(RDB)、replica-serve-stale-data no + 主从同步、或集成 Lua 脚本频繁调用 redis.call(),某些场景下子进程(如 fork() 出的 bgsave 进程)会堆积。一旦容器内 PID 数超限,系统级进程表耗尽,整个节点上的所有 Pod 都会失联 —— 这不是 Redis 慢,是节点“假死”。
实操建议:
--pod-max-pids=1024(或按压测峰值 × 2 设为 2048),并开启特性门控 SupportPodPidsLimit=true
kubectl exec <redis-pod> -- cat /sys/fs/cgroup/pids.max,输出应为具体数字(如 1024),而非 max
save ""(禁用 RDB)却未配 AOF,否则故障恢复时无持久化保障;更稳妥的是关 RDB + 开 AOF + appendfsync everysec
Kubernetes 的 limits.memory 是硬隔离,而 Redis 的 maxmemory 是软控制。如果只设 limits.memory: "4Gi" 却没设 maxmemory,Redis 会不断申请内存直到被 cgroup 杀掉;反之,若 maxmemory: "3.5Gi" 但 limits.memory: "2Gi",Redis 还没到淘汰阈值就被 OOMKilled —— 两者必须形成梯度:cgroup 限制 > Redis 内存策略上限 > 实际工作集。
实操建议:
limits.memory: "4Gi" → config.redis.maxmemory: "3gb" → config.redis.maxmemory-policy: "allkeys-lru"
noeviction:它会让 Redis 在内存满时直接拒绝写入,而 Kubernetes 不会因此重启容器,导致服务静默不可用volatile-ttl,确保所有 key 都带 TTL,否则等效于 noeviction
在 cgroup v2 环境下(Kubernetes 1.26+ 默认),limits.cpu: "1" 最终转为 cpu.weight=100(相对权重)和 cpu.max=100000 100000(绝对配额)。但若节点上其他 Pod 的 cpu.weight 总和远高于 Redis,即使它没跑满 1 核,也会因调度权重低而抢不到 CPU 时间片 —— 表现为 redis-cli --latency 显示 P99 延迟毛刺突增。
实操建议:
QoS Class: Guaranteed:即 requests == limits,这样 kubelet 会为其分配 cpu.weight=1024(最高权重),避免被挤压cpu.max 配额crictl stats <container-id> 查看实时 cpu_usage_nanoseconds,比 kubectl top pod 更准,能发现短时 burst 是否被限频真正卡住 Redis 性能的,往往不是配置项漏写,而是 cgroups 的三层限制(节点预留 → Pod QoS → 容器内核控制器)没串起来。尤其当 maxmemory 和 limits.memory 差值小于 512Mi 时,OOMKilled 概率会陡增 —— 这个间隙,就是运维最容易忽略的“灰色地带”。