2026/5/13 0:09:50
网站建设
项目流程
保定网站优化排名,做网站需要哪个专业,办公室装修一般多少钱一个平方,做户型图的网站文章目录键值淘汰策略使用 maxmemory 配置指令为复制或持久化实例设置 maxmemory淘汰策略使用 INFO 命令近似 LRU 算法LFU 淘汰键值淘汰策略
Redis 常被用作缓存#xff0c;以加速对较慢服务器或数据库的读取访问。由于缓存条目是持久存储数据的副本#xff0c;当缓存内存不…文章目录键值淘汰策略使用 maxmemory 配置指令为复制或持久化实例设置 maxmemory淘汰策略使用 INFO 命令近似 LRU 算法LFU 淘汰键值淘汰策略Redis 常被用作缓存以加速对较慢服务器或数据库的读取访问。由于缓存条目是持久存储数据的副本当缓存内存不足时淘汰它们通常是安全的必要时将来可以再次缓存。Redis 允许你指定一个淘汰策略当缓存大小超过设定的内存限制时自动淘汰键。每当客户端运行一个向缓存添加更多数据的新命令时Redis 会检查内存使用情况。如果超过限制Redis 会根据选择的淘汰策略淘汰键直到总内存使用量回到限制以下。注意当一个命令向缓存添加大量数据例如将一个大集合的交集存储到一个新键中时内存可能会暂时大幅度超过限制。下面的部分解释了如何为缓存配置内存限制也描述了可用的淘汰策略以及何时使用它们。使用 maxmemory 配置指令maxmemory配置指令指定用于缓存数据的最大内存量。你可以在启动时通过redis.conf文件设置maxmemory。例如要配置 100 兆字节的内存限制你可以在redis.conf中使用以下指令maxmemory 100mb你也可以使用CONFIG SET在运行时通过redis-cli设置maxmemory CONFIG SET maxmemory 100mb将maxmemory设置为零表示你不想限制数据集的内存。这是 64 位系统的默认行为而 32 位系统使用 3GB 的隐式内存限制。 当缓存大小超过maxmemory设置的限制时Redis 将强制执行你选择的淘汰策略以防止缓存进一步增长。否是否是客户端发送写入命令内存是否超限?正常写入数据执行淘汰策略移除一个或多个键现在内存是否超限?为复制或持久化实例设置 maxmemory如果你正在为服务器使用复制或持久化Redis 会使用一部分 RAM 作为缓冲区用于存储等待写入副本或 AOF 文件的更新集。此缓冲区使用的内存不包括在用于判断是否需要淘汰的总内存中。这是因为淘汰键本身也会生成必须添加到缓冲区的更新。如果更新被计入已用内存那么在某些情况下通过淘汰键节省的内存会立即被添加到缓冲区的更新数据消耗掉。这反过来会触发更多的淘汰产生的反馈循环可能会不必要地从缓存中淘汰许多项目。如果你正在使用复制或持久化我们建议你设置maxmemory以留出一点空闲 RAM 来存储缓冲区。注意对于noeviction策略这并非必要有关淘汰策略的更多信息请参阅下面的部分。INFO命令在内存部分返回一个mem_not_counted_for_evict值你可以使用INFO memory选项仅查看此部分。这是缓冲区当前使用的内存量。虽然确切数量会有所不同但你可以使用它来估计在设置maxmemory之前要从总可用 RAM 中减去多少。下面的示意图展示了在使用复制或 AOF 时Redis 内存的划分情况其中“复制缓冲区”不计入maxmemory限制70%20%10%Redis 实例内存分布 (启用复制/AOF)maxmemory 限制 (数据集)复制缓冲区 (不计入 maxmemory)其他开销淘汰策略使用maxmemory-policy配置指令来选择当达到maxmemory设置的限制时你想要使用的淘汰策略。 以下策略可用noeviction不淘汰键但当你尝试执行缓存新数据的命令时服务器将返回错误。如果你的数据库使用复制则此条件仅适用于主数据库。注意仅读取现有数据的命令仍然正常工作。allkeys-lru淘汰最近最少使用 (LRU) 的键。allkeys-lfu淘汰最不经常使用 (LFU) 的键。allkeys-random随机淘汰键。volatile-lru淘汰设置了过期字段为 true 的键中最近最少使用的键。volatile-lfu淘汰设置了过期字段为 true 的键中最不经常使用的键。volatile-random仅在键设置了过期字段为 true 时随机淘汰键。volatile-ttl淘汰设置了过期字段为 true 且剩余生存时间 (TTL) 值最短的键。你应该选择一种适合你的应用程序访问键的方式的淘汰策略当你期望有一部分元素的访问频率远高于其他元素时使用allkeys-lru。根据帕累托原则这是一个非常常见的情况所以如果你没有理由更喜欢其他策略allkeys-lru是一个很好的默认选项。当你期望所有键的访问频率大致相等时使用allkeys-random。例如当你的应用程序以重复循环的方式读取数据项时。如果你的代码可以估算哪些键是淘汰的良好候选者并给它们分配较短的 TTL请使用volatile-ttl。另请注意如果你充分利用了键过期那么你不太可能遇到缓存内存限制因为键通常会在需要淘汰之前就过期了。volatile-lru和volatile-random策略主要在你想使用单个 Redis 实例进行缓存和存储一组持久键时有用。但是如果可能的话你应该考虑在这种情况下运行两个独立的 Redis 实例。另外请注意为键设置过期值会消耗内存所以像allkeys-lru这样的策略更节省内存因为它不需要过期值就能运行。是 (纯缓存)否 (需保留部分键)是, 符合二八定律否, 分布均匀关注访问频率是否未设置 TTL最近最少使用最不经常使用开始选择策略是否所有键都可以被淘汰?访问模式是否有热点?淘汰的键是否有 TTL?allkeys-lruallkeys-randomallkeys-lfuvolatile-ttlnoeviction关注时间还是最近访问?volatile-lruvolatile-lfu使用 INFO 命令INFO命令提供了一些有用的数据来检查缓存的性能。特别是INFO stats部分包括两个重要的条目keyspace_hits在缓存中成功找到键的次数和keyspace_misses请求了一个键但不在缓存中的次数。下面的计算给出了从缓存满足的尝试访问的百分比keyspace_hits / (keyspace_hits keyspace_misses) * 100检查这是否大致符合你对你应用程序的预期自然百分比越高表示缓存性能越好。注意当EXISTS命令报告键不存在时这被计为键空间未命中。如果命中率低于预期这可能意味着你没有使用最佳的淘汰策略。例如如果你相信一小部分“热”数据可以轻松放入缓存应该占大约 75% 的访问你可以合理地预期键空间命中百分比在 75% 左右。如果实际百分比较低请检查evicted_keys的值也由INFO stats返回。高比例的淘汰表明你选择的策略过于频繁地淘汰了错误的键所以allkeys-lru可能是一个不错的选择。如果evicted_keys的值很低并且你正在使用键过期请检查expired_keys以查看有多少键已过期。如果这个数字很高你可能使用的 TTL 太低或者你选择了错误的键进行过期这导致键在应该保留之前就从缓存中消失了。INFO返回的其他有用信息包括used_memory_dataset内存部分用于缓存数据的内存量。如果这大于maxmemory那么差值就是maxmemory被超出的量。current_eviction_exceeded_time统计部分自缓存上次开始超过maxmemory以来的时间。commandstats 部分除其他事项外这报告了向服务器发出的每个命令被拒绝的次数。如果你正在使用noeviction或volatile_xxx策略之一你可以使用它来查找哪些命令被maxmemory限制阻止以及这种情况发生的频率。近似 LRU 算法Redis LRU 算法使用最近最少使用的键的近似值而不是精确计算它们。它随机抽取少量的键然后淘汰自上次访问以来时间最长的键。从 Redis 3.0 开始该算法还跟踪一个良好的淘汰候选池。这提高了算法的性能使其成为真正的 LRU 算法的接近近似值。你可以通过maxmemory-samples配置指令更改每次淘汰前要检查的样本数来调整算法的性能maxmemory-samples 5Redis 不使用真正的 LRU 实现是因为它消耗更多的内存。然而对于使用 Redis 的应用程序来说该近似值实际上等同于真正的 LRU。该图比较了 Redis 使用的 LRU 近似值与真正的 LRU。 下面的示意图展示了 Redis LRU 算法如何通过随机采样来寻找淘汰目标而不是遍历所有键Redis 内存随机抽取所有键集合随机抽取 5 个样本比较访问时间找出最旧的键淘汰LFU 淘汰从 Redis 4.0 开始最不经常使用 淘汰模式可用。在某些情况下此模式可能效果更好提供更好的命中/未命中率。在 LFU 模式下Redis 将尝试跟踪项目的访问频率因此很少使用的项目被淘汰。这意味着经常使用的键有更高的机会保留在内存中。要配置 LFU 模式有以下策略可用volatile-lfu在设置了过期的键中使用近似 LFU 进行淘汰。allkeys-lfu使用近似 LFU 淘汰任何键。LFU 像 LRU 一样被近似它使用一个概率计数器称为 Morris 计数器仅使用每个对象的几位来估计对象访问频率并结合一个衰减期以便计数器随时间减少。在某个时刻我们不再想将键视为经常访问的即使它们在过去是这样以便算法能够适应访问模式的变化。该信息类似于 LRU如本文档上一节所解释的进行采样以选择淘汰候选者。然而与 LRU 不同LFU 具有某些可调参数例如如果频繁的项目不再被访问其排名降低的速度应该有多快还可以调整 Morris 计数器范围以更好地将算法适应特定用例。默认情况下Redis 配置为计数器在大约 100 万次请求时饱和。每一分钟衰减一次计数器。这些应该是合理的值并且已经过实验测试但用户可能想要尝试这些配置设置以选择最佳值。有关如何调整这些参数的说明可以在源代码分发中的示例redis.conf文件中找到。简而言之它们是lfu-log-factor 10 lfu-decay-time 1衰减时间显而易见它是计数器应该衰减的分钟数当采样并发现它早于该值时。特殊值 0 意味着我们永远不会衰减计数器。计数器对数因子改变饱和频率计数器需要多少次命中它仅在 0-255 范围内。因子越高达到最大值所需的访问越多。因子越低计数器对低访问的分辨率越好根据下表factor100 hits1000 hits100K hits1M hits10M hits01042552552552551184925525525510101814225525510081149143255所以基本上因子是在更好地区分低访问项目的访问和区分高访问项目访问之间的权衡。更多信息可以在示例redis.conf文件中找到。下面的图表展示了 LFU 计数器的衰减机制随着时间推移如果不被访问计数器会逐渐减少从而允许新的“热”数据进入。T1: 访问 计数器 10T2: 访问 计数器 10等待... 衰减期T3: 访问 计数器 10T4: 未访问 计数器 -1