REDIS是基于内存存储的键值数据库。我们知道,尽管记忆很快,但是空间很小。当物理内存到达上限时,系统将缓慢运行。这是因为掉期机制将部分内存的数据传递到中国的交换分区,保证系统继续通过交换开关运行。但是交换是硬盘存储,远非内存。特别是对于诸如REDIS之类的QPS的高度服务,无法接收这种情况。(请注意,如果交换分区内存已满,则系统将出现错误!)
Linux操作系统可以通过免费-M查看交换大小:
因此,如何防止Redis发生(访调员要求Redis几乎没有知识点)。
REDIS为上述问题提供了最大值配置。此配置可以指定REDIS内存的最大数据集。通常,它在redis.conf文件中配置。您还可以在运行时使用config set命令进行一次性配置。
redis.conf文件中的频繁图:
默认情况下未启用MaxMemory配置项。REDIS正式将64位的操作系统引入了默认情况下,而无需内存限制,32 -bit操作系统默认3GB隐藏内存配置。
因此,当我们进行缓存体系结构时,我们必须根据硬件资源+业务需求进行合适的最大配置。
显然,配置了最大内存。当MaxMemory达到最大上限时,REDIS无法正常工作。那么Redis如何处理这个问题?这是本文的重点。REDIS提供了MaxMemory-Policy消除策略(本文仅告诉LRU不涉及LFU,LFU在下一篇文章中描述),删除满足条件的关键,并欢迎旧的旧条件。
Maxmemory-Policy消除策略:
还有挥发性LFU/Allkeys-LFU。这与两种算法不同!
随机随机消除一些键以随机删除它,并释放内存空间;TTL到期时间可以首先消除。您可以通过比较TTL的大小并释放内存空间来用小的TTL值删除键。
那么LRU如何实现?
让我们使用Java容器来实现简单的LRU算法。我们使用ConcurRentHashMap作为键值结果来存储存储元素的映射关系,并使用ContrentLinkedDeque维护密钥的访问顺序。
LRU实施代码:
测试代码:
检测结果:
从上一个数字的测试结果可以看出。第一个Key0,Key1被淘汰,最后的密钥也是拯救序列团队的最新键。
通过该方案,LRU算法可以非常简单。但是缺点也很明显。该解决方案需要使用其他数据结构来保存关键访问订单。显然,消耗大量内存不好。
为了应对这种情况,Redis使用了近似LRU算法,该算法并未完全准确地消除以消除最常用的密钥,但也可以保证总体精度。
LRU算法的近似非常简单。在REDIS的关键对象中,将24位增加了以存储最新访问的系统时间戳。当客户端将密钥发送到Redis服务器以编写相关请求时,发现内存到达MaxMemory。目前,它触发了触发删除;通过随机抽样进行重新服务,选择满足条件的5个键(请注意,此随机采样Allkeys-lru是所有键的随机样本,volatile-lru是所有键的随机样品,从所有键设置了到期时间),随机抽样),随机抽样)比较钥匙对象记录的最近访问时间戳,以消除这5个键的最古老钥匙;如果内存还不够,请继续此步骤。
请注意,5是redis的默认随机采样值。它可以通过redis.conf中的maxmemory_samples进行配置:
对于上述随机LRU算法,Redis正式提供了测试准确性的数据图:
当Redis 3.0 MaxMemory_samples设置为10时,REDIS的近似LRU算法非常接近真实的LRU算法,但是显然,MaxMemory_samples设置为10比MaxMemory_samples。由于每个样品的样本数据增加。large,计算时间将增加。
redis3.0的LRU比Redis2.8的LRU算法更准确,因为Redis3.0添加了一个与MaxMemory_samples相同的消除池。当钥匙被取消时,将其与消除池的钥匙进行比较。最后,消除了最古老的钥匙,实际上,将选定的钥匙放在一起并进行了比较,并消除了最古老的钥匙。
LRU算法似乎相对易于使用,但是也有不合理的位置,例如A和B两个键,在消除前一天,它们同时增加了Redis。但是接下来的11分钟无法访问;B在这个小时仅59分钟内一次访问B;目前,如果使用了LRU算法,如果A和B由Redis样品选择,则A将被消除。
在这种情况下,REDIS 4.0添加了LFU算法。(最少使用)是最常用的。该算法比LRU更合理。该算法将在下面消除。如有必要,请注意我的专栏。