maxmemory 是已使用内存的最大值吗?

最后更新于 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 Server 进程出现 OOM(内存不足)问题。

务必对实际工作负载进行基准测试,以确认内存使用量在可接受范围内,这将避免 OOM killer 问题。一个保守且经验性的好建议是,在配置的 maxmemory 之外,系统中保留20% 的可用空闲内存。也可以通过自定义配置来测试更激进的驱逐策略;检查配置参数,例如 maxmemory-samplesmaxmemory-eviction-tenacity。请参阅配置文件,以了解这些参数的说明。

参考资料