温馨提示×

Redis如何解决Ubuntu内存不足

小樊
40
2025-12-30 11:04:11
栏目: 云计算

Redis在Ubuntu内存不足的排查与解决

一 快速止损与定位

  • 设置硬上限并启用淘汰策略,避免写入被拒与系统 OOM。编辑配置文件 /etc/redis/redis.conf:设置 maxmemory 1gb(按机器内存调整),并设置 maxmemory-policy allkeys-lru(缓存场景通用;若业务不能丢数据,可改为 noeviction 并配合扩容或清理)。修改后重启:sudo systemctl restart redis-server
  • 观察实例内存与策略是否生效:redis-cli info memory(关注 used_memorymaxmemorymem_fragmentation_ratio)。
  • 若遇到错误提示 OOM command not allowed,说明已达 maxmemory 且策略为 noeviction 或淘汰来不及,需立即扩容、清理或调整策略。
  • 检查系统层面是否因内存紧张触发了 OOM Killer:dmesg | grep -i ‘oom|kill’。若 Redis 被系统杀死,需降低 Redis 占用或增加系统可用内存。

二 系统层面扩容与稳定性

  • 增加交换分区(Swap),为突发峰值提供缓冲:
    • 创建 4GB 交换文件:sudo fallocate -l 4G /swapfile(如失败用 dd if=/dev/zero of=/swapfile bs=1M count=4096
    • 设置权限并启用:sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile
    • 永久生效:在 /etc/fstab 添加 /swapfile none swap sw 0 0
  • 调整内存过量使用策略,降低 fork(bgsave/bgrewriteaof)失败概率:
    • 查看:cat /proc/sys/vm/overcommit_memory
    • 临时设置:sudo sysctl vm.overcommit_memory=1
    • 永久设置:在 /etc/sysctl.conf 追加 vm.overcommit_memory=1
  • 合理设置 swappiness(倾向使用 swap 的程度):
    • 建议值:10–30(减少 Redis 工作集被换出,同时保留应急缓冲)
    • 临时设置:echo 10 | sudo tee /proc/sys/vm/swappiness;永久设置:写入 /etc/sysctl.conf
  • 可选优化:禁用透明大页(THP)以降低延迟波动与内存碎片:echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
  • 风险提示:开启或增大 Swap 会带来一定 IO 延迟,在高并发/低延迟场景需结合压测评估。

三 Redis内部优化降低占用

  • 选择合适淘汰策略:
    • 缓存为主:allkeys-lru / volatile-lru
    • 时间敏感:volatile-ttl
    • 严禁丢写:noeviction(需确保内存充足或配合扩容/清理)
  • 启用小对象编码与结构调优(示例值可按业务微调):
    • hash-max-ziplist-entries 512、hash-max-ziplist-value 64
    • list-max-ziplist-size -2、list-compress-depth 1
    • set-max-intset-entries 512、zset-max-ziplist-entries 128、zset-max-ziplist-value 64
  • 处理大 Key 与阻塞风险:
    • 找出大 Key:redis-cli --bigkeys
    • 异步删除大 Key:UNLINK 替代 DEL
    • 大 Hash/List 按业务键拆分,降低单键内存与阻塞时长
  • 降低碎片率与提升利用率:
    • 使用 jemalloc(默认),查看分配器:redis-cli info server | grep allocator
    • 开启主动碎片整理(Redis 4.0+):activedefrag yes,并结合阈值如 active-defrag-ignore-bytes 100mb、active-defrag-threshold-lower 10
  • 持久化策略折中:
    • RDB:合理设置 save 策略,避免频繁快照带来内存与 CPU 峰值
    • AOF:appendfsync everysec,开启 aof-rewrite-incremental-fsync;Redis 4.0+ 可用 aof-use-rdb-preamble yes 提升恢复速度与降低重写开销

四 架构与容量治理

  • 水平扩展:数据量持续增长时,使用 Redis Cluster 将数据分片到多实例,降低单实例内存压力。
  • 读写分离与本地缓存:对热点数据引入 应用层本地缓存(如 Caffeine),减少穿透到 Redis 的请求量。
  • 容量规划:为持久化与峰值预留 20%–30% 空闲内存;监控 used_memory_rssmem_fragmentation_ratio,当碎片率长期高于 1.5 时优先做结构优化与主动碎片整理。
  • 监控与告警:定期执行 redis-cli info memory,配合 Prometheus + Grafana 或类似工具设置内存阈值告警,提前处置。

五 常见症状与对应措施

症状 可能原因 处理建议
写入报错:OOM command not allowed maxmemory 达到且策略为 noeviction 或淘汰来不及 设置 maxmemory 与合适的 maxmemory-policy(如 allkeys-lru),并清理/扩容
Redis 进程被系统杀死 系统内存不足触发 OOM Killer 增加 Swap、降低 Redis 占用、优化数据结构,必要时扩容物理内存
bgsave/bgrewriteaof 失败或很慢 fork 阶段内存不足、overcommit 策略不当 设置 vm.overcommit_memory=1,并预留足够空闲内存
延迟抖动、吞吐下降 频繁 Swap、THP、碎片率高 调整 swappiness、禁用 THP、开启主动碎片整理、优化数据结构
监控显示 mem_fragmentation_ratio > 1.5 内存碎片偏高 启用 activedefrag,优化 Key/结构,必要时重启实例重建内存布局

0