illx10000

青春不是年华,而是心境

cache淘汰策略

2019年5月23日 星期四, 发表于 深圳

如果你对本文有任何的建议或者疑问, 可以在 这里给我提 Issues, 谢谢! :)

cache通常用来缓存热点数据,用于加速访问等; 业务这边有一些防重放的需求,简单学习一些cache淘汰策略的需求

1. lru

1.1 lru原理

lru(least recentl used)最近最久未使用,将最近最久没有使用的数据淘汰。这种cache算法基于这样一种思路:最近访问过的数据,在接下来也有可能会被访问;

从实现来看:将所有数据放入链表,有访问过的数据,放入链表的头部,当链表的容量超过限制的时候,淘汰链表尾部的数据;

1.2 lru c++ 实现

通常在c++实现中,使用std::listunordered_map

参考例子:https://github.com/illx10000/relax/blob/master/leetcode-cn/0146.cpp

2. lru-k

当有周期性的批量存取消息在lru 缓存中,cache会被污染,命中率下降,因此引入LRU-K的方式应对缓存污染

2.1 lru-k原理

LRU-K中的K代表最近使用的次数,因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。

2.2 lru-k c++实现

通常lru-k实现,会有两条队列,高优先级队列和低优先级队列,大概的思路是冷热分离,如果冷数据访问次数够多,也就变为热数据了;

3. lru & innodb

《MySQL技术内幕:InnoDB存储引擎(第2版)》 书中介绍到innodb使用了LRUCache管理,但是在LRU列表中就如了Midpoint位置,每次新读入的页,不是直接放入LRU的首部,而是放在列表的5/8地方;

innodb将数据分为old列表和new列表,Midpoint到首部的数据是热数据,MidPoint到数据队尾的数据是冷数据,

================================================================

以下内容来自于:https://blog.51cto.com/14227759/2384690?source=dra

================================================================

一般生产的机器,内存比较大。我们会把innodb_old_blocks_pct值调低,防止热数据被刷出内存。

数据何时在old区,何时进入young区?

好,数据页第一次被加载进BufferPool时在old区头部。

当这个数据页在old区,再次被访问到,会做如下判断

如果这个数据页在LRU链表中old区存在的时间超过了1秒,就把它移动到young区

这个存在时间由innodb_old_blocks_time控制