redis内存淘汰

https://redis.io/docs/latest/develop/reference/eviction/

 

在 Redis 中,使用 allkeys-lru 策略时,并不是一次删除一个特定的键,而是通过内存使用情况以及 LRU 算法来选择一批最久未使用的键进行删除。当 Redis 内存达到最大限制(maxmemory)时,它会触发淘汰过程。此时,Redis 会根据设置的 maxmemory-policy(比如 allkeys-lru)删除一些键,以便腾出内存。

删除的比例和删除过程

  1. 淘汰过程 Redis 的 LRU(Least Recently Used)算法会在内存达到 maxmemory 限制时,开始删除最久未使用的键。此过程不是一次性删除特定比例的键,而是通过计算最久未访问的键来逐渐删除,直到内存使用量降到合理范围。

  2. 删除比例 由于 Redis 是基于 LRU 算法进行内存淘汰的,并不会设置一个固定的删除比例,而是根据实际情况删除键。具体删除多少个键是由 Redis 内存使用量、剩余空间以及键的访问频率决定的。通常 Redis 会删除那些长时间没有被访问的键,但删除的数量并不是固定的比例。

  3. LRU 删除的键数 Redis 通过对所有键的 LRU 时间戳进行排序(根据最近的访问时间),从而决定哪些键最久未被使用。然后它会将这些键删除。这个删除过程会持续进行,直到释放足够的内存。

代码层面

在 Redis 中,关于 allkeys-lru 策略的内存淘汰代码主要体现在 src/server.c 中,特别是在 evictKey 和相关的淘汰函数里。以下是与 LRU 淘汰相关的代码流程:

  1. 判断是否达到最大内存

    当 Redis 的内存使用量超过 maxmemory 限制时,Redis 会开始执行内存淘汰过程。

    if (used_memory > server.maxmemory) {
        // 执行淘汰操作
        eviction = evict_lru();
    }
    
  2. LRU 淘汰逻辑

    Redis 会遍历键,选择最久未访问的键进行淘汰。具体的淘汰操作通过 lru_eviction() 函数进行,这个函数会根据 LRU 策略选择键进行删除。

    // LRU 淘汰算法
    eviction = lru_eviction();
    
  3. LRU 删除的数量

    Redis 内部并没有明确限制一次删除多少个键,而是通过内存使用情况决定删除的键数。一次可能删除一个键,也可能删除多个键,具体取决于剩余内存的大小和需要释放的空间。

    // 内存释放
    while (used_memory > server.maxmemory) {
        // 选择最久未使用的键进行删除
        evict_lru_key();
    }
    

如何控制删除的频率

虽然 Redis 本身没有提供直接控制删除比例的配置项,但你可以通过以下方式间接影响内存的删除频率:

  1. 增加 maxmemory 设置

    如果 maxmemory 设置得更高,Redis 会在内存达到限制之前有更大的空间,这样可以减少删除的频率。

  2. 调整 maxmemory-policy

    根据你的应用需求,选择合适的内存淘汰策略,例如:

    • allkeys-lru:会根据 LRU 策略淘汰最久未使用的键。

    • allkeys-lfu:会根据 LFU 策略淘汰访问频率最低的键。

  3. 使用 maxmemory-samples

    Redis 使用 maxmemory-samples 参数来决定每次内存淘汰时扫描的样本数。增加 maxmemory-samples 的值会使 Redis 更精确地选择需要淘汰的键,但也会导致更多的计算开销。

    maxmemory-samples 10
    

    这个值决定了 Redis 每次扫描多少个样本进行内存淘汰,增大它会增加删除精度,但也会增加 Redis 的计算负担。

总结

  • 删除的比例:Redis 的 LRU 和 LFU 淘汰策略并没有固定的删除比例。它会根据内存使用情况和键的访问历史来选择最适合删除的键。删除的数量会动态变化,直到释放足够的内存。

  • 如何影响删除过程:可以通过调整 maxmemorymaxmemory-policymaxmemory-samples 参数来间接影响删除频率和精度,但不能直接设置固定的删除比例。

在 Redis 中,maxmemory-samples 是一个用来控制在内存淘汰过程中每次随机选择样本的数量的配置项。它的目的是在执行内存淘汰时,让 Redis 更加准确地选择最合适的键进行删除,尤其是在使用 allkeys-lruallkeys-lfu 这类策略时。

maxmemory-samples 的作用

  • 该参数指定了 Redis 在进行内存淘汰时,从所有键中随机抽取的样本数目。Redis 通过这些样本来估算哪些键最适合被淘汰。

  • 默认情况下,maxmemory-samples 的值为 5,表示每次从 Redis 的键中随机选择 5 个样本来进行评估。

  • 如果你将该值设置为较大的数值(如 10000),Redis 每次会随机抽取更多的样本来进行评估。这将使得内存淘汰的选择更准确,但也会带来更多的计算开销。

设置 maxmemory-samples 为 10000 的影响

  1. 提高淘汰准确性

    • 设置 maxmemory-samples 为较大的值(如 10000),可以提高 Redis 在淘汰过程中对于哪些键需要被删除的判断精度。这意味着 Redis 会更准确地评估哪些键是最久未使用或最少被访问的,从而减少错误淘汰的风险。

  2. 增加计算开销

    • 每次进行内存淘汰时,Redis 需要检查更多的样本(例如 10000 个样本),这将增加内存消耗和 CPU 开销。如果你设置的样本数过大,可能会导致 Redis 在高负载时性能下降。

  3. 适用场景

    • 如果你的 Redis 数据集很大,且内存淘汰策略对性能要求较高,增加样本数可以改善内存管理的效果。但需要注意的是,设置过大的值可能会导致 CPU 使用率过高,尤其是在高并发的情况下。

设置为 10000 是否合适?

  • 小型和中型 Redis 实例:如果你的 Redis 实例的内存和 CPU 资源比较充足,且数据量不是非常庞大,设置 maxmemory-samples 为 10000 是可以的。但你需要监控性能开销。

  • 大型 Redis 实例:如果你的 Redis 实例数据非常大且 CPU 和内存资源有限,设置为 10000 可能会导致性能瓶颈。可以考虑根据实际负载和性能需求逐步增加该值,而不是一次性设为 10000。

如何修改 maxmemory-samples

可以通过修改 Redis 配置文件(redis.conf)或动态修改该配置项:

配置文件中修改:

maxmemory-samples 10000

动态修改:

使用 Redis 命令 CONFIG SET 来动态修改 maxmemory-samples 的值:

CONFIG SET maxmemory-samples 10000

验证效果

要验证设置 maxmemory-samples 为 10000 是否有效,可以通过以下几步来监控和分析 Redis 的性能:

  1. 监控 CPU 使用情况:可以使用 tophtop 等工具监控 Redis 进程的 CPU 使用情况。如果你设置了较高的 maxmemory-samples,并且 Redis 在淘汰时的 CPU 使用率过高,可能说明设置过高。

  2. 查看淘汰日志:使用 redis-cliMONITOR 命令来观察 Redis 是否频繁地进行内存淘汰操作。你可以通过设置 maxmemory-policy 来测试不同淘汰策略对内存使用的影响。

  3. 分析响应时间:通过 redis-benchmark 或自定义负载测试,验证 Redis 的响应时间是否因为高样本数的设置而变得较慢。

总结

  • 设置 maxmemory-samples 为 10000 可以提高内存淘汰策略的精度,但也会增加 Redis 的计算开销,特别是在高负载环境下。

  • 在决定是否设置该值时,需要平衡精度和性能,避免设置过高导致 Redis 性能问题。

  • 通过逐步调整和监控性能,找到最适合自己场景的配置。

Redis 淘汰策略源码分析

  1. allkeys-lruallkeys-lfu 淘汰策略源码 Redis 的内存淘汰策略在 src/server.c 中有相关代码实现。在选择淘汰策略时,Redis 通过检查配置中的 maxmemory-policy 值来决定使用哪种策略。

    • allkeys-lru:使用 LRU(Least Recently Used)算法,删除最久未访问的键。

    • allkeys-lfu:使用 LFU(Least Frequently Used)算法,删除访问频率最低的键。

    以下是 src/server.c 中与内存淘汰相关的部分代码(伪代码表示):

    // 选择删除策略的函数
    if (server.maxmemory_policy == MAXMEMORY_VOLATILE_LRU) {
        // 使用 LRU 策略删除最久未使用的键
        eviction = lru_eviction();
    } else if (server.maxmemory_policy == MAXMEMORY_ALLKEYS_LRU) {
        // 使用 LRU 策略删除最久未使用的键
        eviction = allkeys_lru_eviction();
    } else if (server.maxmemory_policy == MAXMEMORY_ALLKEYS_LFU) {
        // 使用 LFU 策略删除访问频率最低的键
        eviction = allkeys_lfu_eviction();
    }
    

    eviction 函数会在 Redis 内存达到最大限制时被调用,选择最合适的键进行淘汰。

  2. notify-keyspace-events 配置说明

    notify-keyspace-events 是 Redis 的一个配置选项,用于指定 Redis 在键空间中发生某些事件时触发的通知。该配置允许你订阅不同类型的事件,并在事件发生时获得通知。这个选项对内存淘汰策略没有直接影响,但它会影响 Redis 的行为,特别是对于某些需要监控键操作(如过期、删除等)的场景。

    Redis 事件通知的类型分为两类:

    • 事件类型(Event Types):包括键过期(E)、键删除(d)、键修改(m)等。

    • 事件内容(Keyspace Events):针对具体键空间中的变化(例如过期、删除等)。

    配置方法: 你可以在 Redis 配置文件中启用键空间通知,例如:

    notify-keyspace-events Ex
    
    • E:代表过期事件(expire)。

    • x:代表删除事件(del)。

    通过这种配置,你可以让 Redis 在键过期或被删除时,向订阅者发送通知。这对于一些应用场景非常有用,例如:

    • 监控缓存失效。

    • 分布式锁的过期通知。

    • 实现一些更复杂的应用逻辑(如事件驱动模型)。

是否有必要配置 notify-keyspace-events

是否需要配置 notify-keyspace-events 取决于你的应用需求,具体说明如下:

为什么要配置 notify-keyspace-events

  1. 监控过期事件和删除事件:如果你的应用需要在键过期或被删除时执行特定的操作(例如更新某个状态或触发某个动作),启用此功能会非常有用。

  2. 用于缓存系统:在缓存系统中,键的过期和删除是常见的操作。如果你想通过通知机制来实时获取哪些键被删除或过期,这个配置非常重要。例如,你可以在某些缓存失效时自动刷新数据。

  3. 分布式锁:在分布式缓存中,notify-keyspace-events 配置可以帮助你监控分布式锁的过期,确保锁过期后自动释放。

  4. 应用级别的事件驱动模型:如果你的应用依赖于 Redis 键的变化来触发某些事件(如过期、删除、修改),启用通知机制将有助于实现更精确的事件驱动模型。

什么时候不需要配置

  1. 没有特殊监控需求:如果你的应用不依赖于键空间的变化,或者只是依赖 Redis 的普通功能(如存储、获取键),那么没有必要启用此配置。

  2. 性能考虑:启用键空间通知会带来额外的性能开销。虽然 Redis 在处理通知时不会阻塞客户端,但对于高频的键变化(如大量的过期和删除事件),可能会影响 Redis 性能。

配置和验证示例

假设你需要在键过期或删除时执行某个操作,可以通过以下方式进行配置和验证:

  1. 修改 Redis 配置文件redis.conf):

    redis.conf 文件中添加或修改:

    notify-keyspace-events Ex
    

    这将启用对过期事件(E)和删除事件(x)的通知。

  2. 使用 PSUBSCRIBE 订阅事件

    你可以使用 PSUBSCRIBE 命令订阅键空间事件。以下是一个订阅过期和删除事件的示例:

    PSUBSCRIBE __keyevent@0__:expired
    PSUBSCRIBE __keyevent@0__:del
    

    这将订阅键空间中所有数据库(假设使用默认的数据库 0)的过期和删除事件。

  3. 验证事件通知

    • 通过 Redis CLI 手动删除或过期某个键。

    • 观察是否收到事件通知(__keyevent@0__:expired__keyevent@0__:del)。

总结

  • maxmemory-policy 是决定 Redis 内存淘汰策略的配置项,与 notify-keyspace-events 配置无直接关系。

  • notify-keyspace-events 配置对 Redis 的键空间事件通知非常有用,尤其是在需要对键的过期、删除等事件做出反应的场景中。

  • 是否启用 notify-keyspace-events 需要根据你的应用需求来决定,开启后可能对性能有一些影响,特别是高频变化的场景。

确实,Redis 并不会直接在 INFO stats 输出中显示 lfu_counterlfu_total_hits,这些字段仅在一些特殊的 Redis 版本中(比如,特定配置的 Redis 或专门的模块)才可能出现。对于默认的 Redis 实例,尤其是启用了 LFU 淘汰策略的实例,LFU 计数器的内部状态并不会直接暴露。

不过,你依然可以通过以下几种方法间接获取有关 LRULFU 的信息:

1. 通过 INFO 命令查看 LFU 相关统计数据(间接方法)

在 Redis 4.0 及以上版本中,LFU 相关的数据会在 INFO memory 输出中显示。例如:

INFO memory

此时,会返回关于内存使用的相关统计信息,其中可能包含以下部分:

  • lfu_algorithm: 显示当前使用的 LFU 算法(比如,LRU-LFU)。

  • evicted_keys: 被驱逐的键数。

这些信息并不直接提供单个键的 LFU 计数器,但它们帮助你了解 LFU 算法的整体行为。

2. 监控 LFU 使用情况:

虽然 Redis 没有直接的命令列出 LFU 计数器,但你可以通过 Keyspace Notifications 来监控某些操作,间接推测哪些键可能是低频访问的。例如,监听 expired 事件,了解何时某个键过期,间接推测该键是否因为低频访问被淘汰。

CONFIG SET notify-keyspace-events Ex

然后,你可以订阅这些事件:

PSUBSCRIBE __keyevent@0__:expired

这将监听键过期事件,可以帮助你了解哪些键被淘汰。

3. 通过 SCAN 命令遍历所有键并查看 TTL(间接查看)

通过 SCAN 命令遍历所有键,并查看它们的 TTL 值,帮助你间接了解哪些键是“最久未访问”的(即没有 TTL 设置或者过期时间很长)。例如:

SCAN 0 MATCH * COUNT 1000

这个命令将遍历 Redis 中的键,并逐个返回。然后,你可以检查键的 TTL:

TTL <key_name>

如果某个键的 TTL 很长,可能表示该键在一段时间内没有被访问。

4. 自定义脚本或监控工具

你也可以写脚本周期性地扫描 Redis 中的键并记录它们的访问时间或 TTL。可以通过这个脚本推断哪些键是“最久未访问”的(低频访问的键)。例如,使用 Python 或其他 Redis 客户端工具,定期检查并统计键的 TTL。

5. 使用 Redis 调试模式

如果你只是想在特定情况下深入查看键的 LRU 或 LFU 状态,可以使用 Redis 的调试命令来跟踪一些操作:

DEBUG OBJECT <key_name>

这个命令会返回关于该键的一些内部状态信息,包括 LRU 时间戳等。

总结

Redis 本身并没有直接提供完整的 lfu_counterlru_counter 统计信息,无法直接查看每个键的访问频率。你可以通过以下方式来间接了解 LFU 或 LRU 相关的信息:

  1. 使用 INFO memory 查看一些内存统计信息。

  2. 利用 Keyspace Notifications 监听过期事件。

  3. 使用 SCAN 命令和 TTL 来间接推测键的访问频率。

  4. 自定义脚本和监控工具来追踪访问时间。

这些方法可以帮助你了解哪些键可能是最久未访问或最低频访问的。

 

下面是 Redis INFO 命令所有模块和字段的完整解释(适用于 Redis 6.x/7.x,支持集群/主从/持久化等场景)。为便于理解,分模块系统讲解:


🔹 1. Server(服务器信息)

字段含义
redis_version Redis 版本
redis_git_sha1 构建时 Git 哈希(开发版)
redis_git_dirty 是否包含未提交更改
redis_build_id Redis 编译时生成的 ID
redis_mode 运行模式(standalone/cluster/sentinel)
os 操作系统信息
arch_bits CPU 架构位数(32/64)
multiplexing_api 网络多路复用库(如 epoll/kqueue)
process_id Redis 进程 PID
run_id 唯一标识符(可用于 Sentinel)
tcp_port TCP 监听端口
uptime_in_seconds Redis 已运行时间(秒)
uptime_in_days Redis 已运行时间(天)
hz Redis 主循环频率
configured_hz 配置的 HZ
lru_clock LRU 时间戳(用于淘汰策略)
executable Redis 执行文件路径
config_file 启动时使用的配置文件路径

🔹 2. Clients(客户端连接信息)

字段含义
connected_clients 当前连接的客户端总数(不包括自身)
cluster_connections cluster 模式下 node-to-node 的连接数量
max_input_buffer 所有客户端中最大输入缓冲区
max_output_buffer 所有客户端中最大输出缓冲区
client_recent_max_input_buffer 最近最大输入缓冲区大小
client_recent_max_output_buffer 最近最大输出缓冲区大小
blocked_clients 正在阻塞的客户端数量(如 BLPOP)

🔹 3. Memory(内存使用)

字段含义
used_memory Redis 当前已分配的总内存
used_memory_human 可读格式的内存
used_memory_rss 实际占用的物理内存(包括碎片)
used_memory_peak 内存使用峰值
used_memory_peak_human 可读格式峰值
used_memory_dataset 存储数据的实际内存(剔除内部结构)
used_memory_dataset_perc 占总内存的百分比
allocator_allocated 分配器分配的内存
allocator_active 活跃内存(分配但未释放)
allocator_resident 驻留内存(映射到物理页)
total_system_memory 系统总内存
used_memory_lua Lua 脚本使用的内存
used_memory_scripts 所有缓存脚本内存占用
number_of_cached_scripts 缓存的 Lua 脚本数量
maxmemory 配置的最大内存上限(0 表示无限)
maxmemory_policy 淘汰策略(如 noeviction, allkeys-lru)
mem_fragmentation_ratio 内存碎片比(rss/used_memory)
mem_fragmentation_bytes 实际碎片字节数
active_defrag_running 是否正在执行主动碎片整理(0/1)
lazyfree_pending_objects 延迟删除的对象数量

🔹 4. Persistence(持久化)

字段含义
loading 是否正在载入 RDB 文件
rdb_changes_since_last_save 距上次保存后变更的 key 数
rdb_bgsave_in_progress 是否正在后台保存 RDB
rdb_last_save_time 上次成功保存时间(Unix 时间戳)
rdb_last_bgsave_status 上次保存结果(ok/fail)
rdb_last_bgsave_time_sec 上次保存耗时(秒)
rdb_current_bgsave_time_sec 当前保存耗时(秒)
aof_enabled 是否启用了 AOF
aof_rewrite_in_progress 是否正在重写 AOF
aof_rewrite_scheduled 是否等待 AOF 重写
aof_last_rewrite_time_sec 上次 AOF 重写耗时(秒)
aof_current_rewrite_time_sec 当前 AOF 重写耗时(秒)
aof_last_bgrewrite_status 上次重写状态
aof_last_write_status 最近一次写入状态
aof_current_size 当前 AOF 文件大小
aof_base_size 上次重写后 AOF 大小
aof_pending_rewrite 是否挂起重写
aof_buffer_length 当前 AOF 缓冲区长度
aof_rewrite_buffer_length AOF 重写缓冲区大小
aof_pending_bio_fsync bio fsync 任务队列长度
aof_delayed_fsync AOF 写入延迟次数

🔹 5. Stats(统计信息)

字段含义
total_connections_received 运行以来连接总数
total_commands_processed 运行以来处理命令总数
instantaneous_ops_per_sec 当前每秒执行的命令数
total_net_input_bytes 网络输入总字节数
total_net_output_bytes 网络输出总字节数
instantaneous_input_kbps 当前输入速度(KB/s)
instantaneous_output_kbps 当前输出速度(KB/s)
rejected_connections 被拒绝的连接数(连接过多)
sync_full 完整复制次数(PSYNC失败)
sync_partial_ok 增量复制成功次数
sync_partial_err 增量复制失败次数
expired_keys 过期 key 数量
evicted_keys 被淘汰 key 数量
keyspace_hits key 查询命中次数
keyspace_misses key 查询未命中次数
pubsub_channels 正在使用的频道数
pubsub_patterns 模式匹配的订阅数
latest_fork_usec 上次 fork 用时(微秒)
migrate_cached_sockets MIGRATE 命令缓存 socket 数
slave_expires_tracked_keys 从节点正在跟踪的过期 key 数
active_defrag_hits/misses 主动 defrag 的命中/未命中统计
active_defrag_key_hits/misses 主动 defrag 命中/未命中 key 数

🔹 6. Replication(复制)

字段含义
role 当前角色(master/slave)
connected_slaves 连接的从节点数量
slave0... 每个从节点状态(IP、port、offset、延迟)
master_replid / replid2 主节点 ID(用于 PSYNC)
master_repl_offset 当前复制偏移量
second_repl_offset 上次主 ID 的复制偏移量
repl_backlog_active 是否启用复制 backlog
repl_backlog_size backlog 大小
repl_backlog_first_byte_offset backlog 的第一个字节 offset
repl_backlog_histlen backlog 的历史长度(数据实际长度)

🔹 7. CPU(CPU 使用情况)

字段含义
used_cpu_sys Redis 主线程内核态耗时(秒)
used_cpu_user Redis 主线程用户态耗时(秒)
used_cpu_sys_children Redis 子进程内核态耗时(RDB/AOF)
used_cpu_user_children Redis 子进程用户态耗时

🔹 8. Cluster(集群状态)

字段含义
cluster_enabled 是否启用集群模式(1/0)

🔹 9. Keyspace(数据库信息)

字段含义
db0:keys=xxx,expires=xxx,avg_ttl=xxx 当前库(db0)中 key 数量、带过期的 key 数、平均 TTL(毫秒)

🔹(可选)Module(模块信息,如 RedisBloom、RedisSearch)

当你加载模块时会显示,例如:

module:name=ReJSON,ver=20000,...

🔹(可选)Keyspace-events / Stream / TLS 等段落

根据启用的功能,INFO 输出可能包含:

  • Stream 指标(消费者组、等待项)

  • TLS 连接统计(TLS 客户端、失败次数)

  • Keyspace events 指标


✅ 小结

模块用途
Server 基本元信息
Clients 客户端连接与缓存情况
Memory 内存用量与碎片
Persistence 持久化状态
Stats 命令和性能统计
Replication 主从状态
CPU 资源消耗分析
Cluster 是否启用集群
Keyspace 各 DB 中的 key 情况

如你有:

  • 特定模块需要重点讲解

  • 想把这些信息转成结构化表格、JSON 或导出

  • INFO 做自动化监控脚本(如 Python、Shell)

可以告诉我,我可继续为你定制。

 

 

下面在你已了解的 Redis INFO 命令输出字段的基础上,补充性能分析相关指标,包括:

  • ✅ 哪些字段与性能强相关

  • ✅ 如何解读性能瓶颈

  • ✅ 常用的性能分析组合

  • ✅ 对于高负载场景的重点监控建议


🧠 一、核心性能分析指标分类汇总

类别字段说明高值可能意味着
命令执行速率 instantaneous_ops_per_sec 每秒处理命令数 命令繁重或压力高
网络带宽 instantaneous_input_kbps, instantaneous_output_kbps 每秒网络 I/O 量(KB) 客户端流量大
查询效率 keyspace_hits, keyspace_misses key 查询命中/未命中数 命中率低 → 内部结构设计不合理
key 命中率 (hits / (hits + misses)) Redis 缓存命中率 命中率低说明缓存失效频繁
慢查询计数 slowlog (外部命令) 记录执行时间超过阈值的命令 命令设计或数据结构存在问题
fork 性能 latest_fork_usec 上次 fork() 耗时(μs) 若频繁 fork 且时间 >1s,性能下降
内存淘汰频率 evicted_keys 淘汰的 key 数量 超出 maxmemory 且策略触发
延迟指标 Redis 需单独开启 latency-monitor 支持查看高延迟命令 命令或后台操作耗时严重
expired keys expired_keys 被动过期的 key 总数 频繁到期可能与业务周期有关
CPU 占用 used_cpu_sys, used_cpu_user, *_children Redis 主/子线程消耗 主线程长时间高耗可能是瓶颈
客户端等待 blocked_clients 阻塞命令客户端数(如 BLPOP) 队列堆积或阻塞逻辑
pub/sub 模式负载 pubsub_channels, pubsub_patterns 当前订阅频道数/通配数 多频道发布场景需关注此项
backlog 长度 repl_backlog_histlen 主从复制 backlog 大小 长期为 backlog_size 说明复制繁忙

🔍 二、关键性能瓶颈指标详解

1. 命令执行效率

instantaneous_ops_per_sec: 当前 QPS
total_commands_processed: 累计命令数
  • 分析建议

    • 结合 CPU 使用情况、client 数量、command type 做关联分析。

    • 可与 MONITOR 命令结合进行实时查看。


2. 查询命中率

keyspace_hits: 成功命中次数
keyspace_misses: 未命中次数
  • 命中率计算

    hit_rate = hits / (hits + misses)
    
  • 命中率过低意味着

    • key 不存在频率高

    • key 频繁过期

    • 使用了错误的数据结构(例如大 key + 低频访问)


3. 内存淘汰监控

evicted_keys: 被主动淘汰 key 的数量
  • 如果该值持续增长说明 Redis 处于“内存吃紧 + 触发 maxmemory 策略”状态。

  • 需要关注:

    • maxmemory_policy 是否合适?

    • 是否可增加内存或做冷热数据分层?


4. fork 性能指标

latest_fork_usec: 最近一次 fork 时间(微秒)
  • Redis 在执行 RDB 或 AOF rewrite 时会 fork(),如果该操作过慢(如 > 1 秒):

    • 会暂停主线程处理请求(短时间卡顿)

    • 原因多为内存太大 → fork 过程页表复制消耗大


5. 延迟指标(需单独开启)

使用以下命令启用并分析 Redis 延迟:

CONFIG SET latency-monitor-threshold 100
LATENCY LATEST
LATENCY HISTOGRAM
  • 可分析 slowlog 记录不到的“内部延迟”

  • 特别适合排查 fork、AOF 写、RDB 保存引起的抖动


6. CPU 分析

used_cpu_sys / used_cpu_user
used_cpu_sys_children / used_cpu_user_children
  • 主线程使用高:请求量大或单线程瓶颈

  • 子线程高:说明 AOF 重写或 RDB 保存频繁

建议每分钟采集两次 used_cpu_xxx 值,求差除时间间隔,得到准确 CPU 使用率


📈 三、性能监控最佳实践建议

场景关注字段
缓存命中率低 keyspace_hits / keyspace_misses
内存高 + 淘汰多 used_memory, evicted_keys, maxmemory_policy
主从复制卡顿 repl_backlog_histlen, master_repl_offset 差值
fork 卡顿、写入慢 latest_fork_usec, used_cpu_children 系列
命令积压或慢 instantaneous_ops_per_sec, blocked_clients
Pub/Sub 过多 pubsub_channels, pubsub_patterns
网络堵塞 instantaneous_output_kbps, backlog 变大

🛠 四、如何持续收集 INFO 性能数据(实用)

可用 shell 脚本/Prometheus 或 Python 收集核心指标:

redis-cli INFO stats | egrep 'evicted_keys|instantaneous_ops_per_sec|keyspace_hits|keyspace_misses|latest_fork_usec'

或者用 Python 每分钟轮询记录变化值做可视化。


✅ 结语

Redis INFO 的性能指标远比普通状态更重要,是监控、排障、优化的基础。
你可以据此做以下:

  • 监控图表(Prometheus/Grafana)

  • 性能基线比较(不同阶段/业务增长)

  • 分析热点 key、命令结构问题(配合 SLOWLOG)


是否还希望我:

  • 提供 Prometheus Redis Exporter 映射字段?

  • 帮你设计一个基于这些指标的监控脚本?

  • 分析你当前 Redis 的性能瓶颈(贴一下几个 INFO 输出)?

欢迎继续提问。

posted on 2025-04-25 19:08  吃草的青蛙  阅读(71)  评论(0)    收藏  举报

导航