maxmemory 是否表示 Redis 使用内存的最大值?

最后更新时间:2024 年 4 月 18 日

问题

配置后,maxmemory 是否表示 Redis 可以使用的最大内存量?

回答

maxmemory 并不代表 Redis 实例可以使用的确切最大内存量。即使内存使用量超过 maxmemory,每个新命令都可能会将数据添加到数据库。但是,Redis 将根据配置的策略开始逐出键,具体取决于键的类型(持久或易失)以及使用的算法(LRU 或 LFU)。请参阅文档中有关不同 逐出策略 的说明。以下是超过 maxmemory 阈值时触发的算法概述。

  • 使用随机采样找到要逐出的键,这决定了 LRU 和 LFU 实现方式的近似值。
  • 对一些良好的候选键进行采样(5-10 个)。
  • 逐出其中最旧的键。

该算法的描述在 evict.c 源代码文件中。

/* LRU approximation algorithm
 *
 * Redis uses an approximation of the LRU algorithm that runs in constant
 * memory. Every time there is a key to expire, we sample N keys (with
 * N very small, usually in around 5) to populate a pool of best keys to
 * evict of M keys (the pool size is defined by EVPOOL_SIZE).
 *
 * The N keys sampled are added in the pool of good keys to expire (the one
 * with an old access time) if they are better than one of the current keys
 * in the pool.
 *
 * After the pool is populated, the best key we have in the pool is expired.
 * However note that we don't remove keys from the pool when they are deleted
 * so the pool may contain keys that no longer exist.
 *
 * When we try to evict a key, and all the entries in the pool don't exist
 * we populate it again. This time we'll be sure that the pool has at least
 * one key that can be evicted, if there is at least one key that can be
 * evicted in the whole database. */

逐出算法的近似值是由于需要在延迟和内存使用量之间取得良好的平衡而产生的。在进行规模考虑时,请考虑这些因素。大量流量可能会给内存使用量带来压力,并导致 Redis 服务器进程出现 OOM 问题。

确保对真实的工作负载进行基准测试,以确认内存使用量在可接受的范围内,这将避免 OOM 杀手问题。一个好的保守规则是,在系统中保持比配置的 maxmemory 多 **20% 的可用内存**。也可以通过使用自定义配置来测试更激进的逐出策略;检查配置参数,例如 maxmemory-samplesmaxmemory-eviction-tenacity。请参阅 配置文件 以了解这些参数的描述。

参考资料