zoukankan      html  css  js  c++  java
  • Redis中的近似LRU超出内存限制后的处理

    【淘汰策略】
    当Redis内存超过物理内存时,内存的数据会开始和磁盘产生频繁地交换(swap),这会大大降低Redis的性能。
    在生产环境我们一般不允许出现Redis的交换行为,为了限制最大使用内存,Redis提供了maxmemory参数,当实际内存超过这个值时,Redis提供了几种可选策略来处理:
    1.noeviction:不能继续写(del可以),但可以读
    2.volatile-lru:尝试淘汰设置了过期时间的key,最少使用的key优先被淘汰,未设置过期时间的key不会被淘汰
    3.volatile-ttl:尝试淘汰设置了过期时间的key,ttl越小的越优先被淘汰,未设置过的不淘汰
    4.volatile-random尝试淘汰设置了过期时间的key,随机淘汰,未设置的不淘汰
    5.allkeys-lru:所有key都可能被淘汰,LRU原则
    6.allkeys-random:所有key都可能被淘汰,随机原则

    volatile有易变/易挥发等含义,所以也能够理解这是要对有过期时间的key下手,而evict有逐出的含义,所以noeviction可以理解为不对现有的key进行删除。

    如果只是拿Redis作缓存,应该使用allkeys-xxx策略,客户端写缓存时不必携带过期时间。如果想使用Redis的持久化功能,那就是用volatile-xxx策略,这样可以保留没有设置过期时间的key,他们是永久的key,不会被LRU算法淘汰。

    【LRU算法思路】
    实现LRU算法除了需要key/value之外,还需要附加一个链表,链表中的元素排列按照元素被访问得顺序设置,当某个元素被访问时,这个元素就放到链表的表头,这样链表元素的排列顺序就是元素最近被访问得时间顺序。当空间满的时候,会踢掉表尾部的元素。

    【近似LRU算法】
    从上面的描述可以看到,如果想实现这个LRU,必须维护这么一个链表,需要额外的空间来支持。
    Redis采用的是近似LRU算法,首先会给每个key增加一个额外的小字段,每个字段的长度是24个bit,填写最后一次被访问的时间戳。然后当内存超出maxmemory的时候,随机采样N个key,然后淘汰掉最旧的key,如果淘汰后还是超出maxmemory,那就继续随机采样淘汰,直到内存低于maxmemory为止。
    之所以不用LRU算法,是因为后者需要消耗大量的额外内存,并对现有的数据结构进行较大的改造。与之前提到的[key过期]处理方式有集中处理和懒惰处理,而[超出内存限制]后的近似LRU的处理方式只有懒惰处理,即写操作发现超过maxmemory时才会进行处理。

  • 相关阅读:
    将PHP文件生成静态文件源码
    Entity Framework Code First 学习日记(6)一对多关系
    Entity Framework Code First 学习日记(5)
    Entity Framework Code First 学习日记(3)
    Entity Framework Code First 学习日记(7)多对多关系
    Entity Framework Code First学习日记(2)
    Entity Framework Code First 学习日记(8)一对一关系
    Entity Framework Code First 学习日记(9)映射继承关系
    Entity Framework Code First 学习日记(10)兼容遗留数据库
    Entity Framework Code First 学习日记(4)
  • 原文地址:https://www.cnblogs.com/bruceChan0018/p/15772658.html
Copyright © 2011-2022 走看看