zoukankan      html  css  js  c++  java
  • 常用缓存淘汰策略

    常用缓存策略

    常用的缓存淘汰策略有以下

    • 先进先出算法(FIFO)
    • Least Frequently Used(LFU)
      淘汰一定时期内被访问次数最少的页面,以次数作为参考
    • Least Recently Used(LRU)
      淘汰最长时间未被使用的页面,以时间作为参考

    这些算法在不同层次的缓存上执行时拥有不同的效率和代价,需根据具体场合选择最合适的一种。

    FIFO

    FIFO(First in First out),先进先出。在FIFO Cache设计中,核心原则就是:如果一个数据最先进入缓存中,则应该最早淘汰掉。

    1、利用一个双向链表保存数据,
    2、当来了新的数据之后便添加到链表末尾,
    3、如果Cache存满数据,则把链表头部数据删除,
    4、然后把新的数据添加到链表末尾。
    5、在访问数据的时候,如果在Cache中存在该数据的话,则返回对应的value值;
    6、否则返回-1。如果想提高访问效率,可以利用hashmap来保存每个key在链表中对应的位置。

    LFU

     
    image.png

    1、新加入数据插入到队列尾部(因为引用计数为1);
    2、 队列中的数据被访问后,引用计数增加,队列重新排序;
    3、当需要淘汰数据时,将已经排序的列表最后的数据块删除。

    LRU

     
    image.png

    1、新数据插入到链表头部;
    2、每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
    3、当链表满的时候,将链表尾部的数据丢弃。

    Two queues(2Q)

    2Q算法有两个缓存队列,一个是FIFO队列,一个是LRU队列。当数据第一次访问时,2Q算法将数据缓存在FIFO队列里面,当数据第二次被访问时,则将数据从FIFO队列移到LRU队列里面,两个队列各自按照自己的方法淘汰数据。详细实现如下:

     
    image.png
    1. 新访问的数据插入到FIFO队列;
    2. 如果数据在FIFO队列中一直没有被再次访问,则最终按照FIFO规则淘汰;
    3. 如果数据在FIFO队列中被再次访问,则将数据移到LRU队列头部;
    4. 如果数据在LRU队列再次被访问,则将数据移到LRU队列头部;
    5. LRU队列淘汰末尾的数据。

    这种情况适用与以下场景
    当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。

    周期性的批量操作,会立即淘汰LRU队列中的大量数据,导致缓存命中率大幅度下降。而APP常规操作中,有大量偶发批量操作,比如:进入页面后立即返回,就是很典型的一种。

    所以LRU算法并不是一个非常好的选择。

  • 相关阅读:
    cantor 数表
    利用form的“acceptcharset”在不同编码的页面间提交表单
    <li>标签,在文字超出宽度时引起混乱的解决办法
    java中 Integer.getInteger(String str)的疑惑
    SQL语句集锦
    禁用鼠标右键
    ROW_NUMBER() OVER函数的基本用法
    listview
    decodeResource
    LinkedList
  • 原文地址:https://www.cnblogs.com/zhangfengshi/p/11466263.html
Copyright © 2011-2022 走看看