【Redis】2-Redis监控与内存

发布于:2025-05-28 ⋅ 阅读:(83) ⋅ 点赞:(0)

欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
有很多很多不足的地方,欢迎评论交流,感谢您的阅读与评论😄。

引言

在"高效的数据结构"3篇中,我们已经较深入地理解了Redis作为“简单高效的内存数据库”,其在数据结构上为高效利用内存(分配、释放、使用)做的设计。
而在数据结构之外,Redis还有做其他的高效利用内存的设计。

PS:内存回收、共享对象上篇有提及。

Redis监控

不监控怎么发现问题呢?

慢查询日志

Redis设计有“慢查询日志”,执行时间超过预设阈值的命令请求会被保存在一个固定大小的列表(FIFO队列)中。
日志包含信息有:唯一ID (Unique ID)、时间戳 (Timestamp)、执行耗时 (Duration)、命令本身 (Command Array)等。
Redis可以通过参数slowlog-log-slower-than(单位:微秒)来控制阈值。默认为10000 (即 10 毫秒)。
通过参数slowlog-max-len来控制慢查询日志的最大条数。

在redis-cli中,可以通过showlog get来获取慢查询日志列表,showlog reset清空日志,showlog len获取条数。

监视器

通过MONITOR命令,客户端可以将自己变成一个Redis监视器,实时地接受并打印服务器当前处理的命令请求的相关信息。
MONITOR开启后,相当于服务器接受的每个命令都需要格式化后网络发送给开启MONITOR的客户端(主要还是因为是同步操作)。
其性能开销对Redis有显著影响,生产环境中需要避免长时间开启MONITOR。只建议在短时间、低峰期使用。

生产级监控

简单做法是定期执行info命令采集服务器各方面信息与慢查询日志。
Redis还提供有LATENCY DOCTOR、LATENCY HISTOGRAM。 LATENCY DOCTOR尝试诊断服务器可能存在的延迟问题,并给出建议。LATENCY HISTOGRAM <event> 可以查看特定事件的延迟分布。

其他监控手段如Prometheus+Grafana或Zabbix等基本都是基于此。

内存管理

过期键删除策略

Redis提供键的生效时间设置,并提融合了两种策略用于删除。
惰性删除与定期删除。

  • 惰性删除
    当客户端尝试访问一个 key 时,Redis 会首先检查这个 key 是否设置了过期时间,以及这个过期时间是否已到。

  • 定期删除
    Redis维护有设置了过期时间的key和过期时间戳的集合——“过期字典(expires)”,会周期性地、随机地从设置了过期时间的 key 集合中抽取一部分 key 进行检查,并删除其中已过期的 key。

并且,当 Redis 内存达到 maxmemory 限制时,即使没有 key 过期,Redis 也会根据配置的内存淘汰策略(如 volatile-lru, allkeys-lru, volatile-ttl 等)来删除一些 key 以释放空间。

内存淘汰策略

关于内存淘汰策略上一篇讲对象有提及。

![[Redis内存管理-1.png]]除LRU与LFU外,还有

  • noeviction:达到上限后,新的写入操作会报错(默认策略)。
  • allkeys-lru:从所有键中移除最近最少使用的键。
  • volatile-lru:仅从设置了过期时间的键中移除最近最少使用的键。
  • allkeys-random:从所有键中随机移除。
  • volatile-random:仅从设置了过期时间的键中随机移除。
  • volatile-ttl:仅从设置了过期时间的键中移除剩余生存时间最短的键。
  • allkeys-lfu (Redis 4.0+):从所有键中移除最不常用的键。
  • volatile-lfu (Redis 4.0+):仅从设置了过期时间的键中移除最不常用的键。

Redis常见内存相关问题

  • 更改默认内存淘汰策略
    Redis要配置合适的内存淘汰策略以保障内存能及时释放。默认的noeviction是不行的。

  • 大Key处理
    使用 redis-cli --bigkeys 或第三方工具扫描大 Key。
    大Key一般都是业务设计不当才出现的,将大 Key 拆分成多个小的 Key。
    使用 UNLINK(异步删除) 代替 DEL 来删除大 Key。

一般来说,单个 Key 占用几十 MB 以上内存,或者集合类型包含数十万以上的元素,对 Key 的操作会阻塞其他操作(是否算阻塞需根据各自业务权衡)。出现这样的情况,都算大 Key,需要进行处理。

  • 内存碎片
    所有使用存储空间都会有碎片。当Redis进程占用的内存(used_memory_rss)远大于Redis内部数据占用的逻辑内存(used_memory),可能我们就需要考虑解决内存碎片的问题了。
    碎片除了导致空间占用比实际大,还会导致可能分配连续内存失败。

  • 和关注Java GC一样,关注evicted_keys
    Redis 的info memory输出指标中有一项evicted_keys,是被Redis主动删除的键的数量。是一个累积计数器 (cumulative counter)。
    如果 evicted_keys 的值持续快速增长,意味着 Redis 频繁地因为内存不足而被迫删除数据。
    和GC一样,淘汰是需要占用资源,损耗性能的。


网站公告

今日签到

点亮在社区的每一天
去签到