接入
- 接上篇文章:《mysql的buffer pool》https://blog.csdn.net/weixin_44048287/article/details/133984593
引入-内存淘汰策略-LRU
LRU,最近最少使用(Least Recently Used)。
- 会用一个链表维护缓存中的每个数据的访问情况,并根据数据的实时访问,调整数据在链表的位置,如果数据在链表的头部则表明最近才被访问过,如果位于链表末尾,则说明该数据是长时间没有被访问过的。
- LRU算法把链表的头和尾分别设为MRU和LRU端,其中LRU端此处的数据最近最少被访问的数据。
对于常规的LRU算法,是把我们的数据比作为一个链表,永远淘汰链表末尾的数据(即不常用的数据)。
buffer pool的LRU淘汰算法
-
buffer pool的lru淘汰算法是一个特殊的:冷热区别的LRU策略。
-
对于buffer pool的LRU淘汰策略,LRU链表会被拆分成两部分,一部分是冷数据,一部分是热数据,其中冷热占比为3:8。
为什么要做冷热分区
- 为了更高的提高内存利用率和系统性能。
- 将链表进行冷热分区可以更有效地管理内存,冷热区别是基于数据块的使用频率来划分的,热数据:经常被访问的数据块,冷数据:不经常访问的数据块。通过将冷热分开,可以使得热数据更容易被缓存并快速访问,冷数据可以较少占用内存资源。
- 采用3:5分区比例可以更好的满足实际数据的访问的特征,使得热数据可以得到缓存,增加缓存命中率,提高系统响应速度。
数据页第一次加载进来,放在LRU链表的什么地方
- 放在链表冷区域的头部
为什么要放在冷区域的头部呢,因为第一次去使用这个数据,并不代表着以后都一直使用这个数据,所以没有必要把这个数据直接放到热数据区域,而是放在冷区的顶端,如果你后续不在访问这条数据,就慢慢地把这个数据从冷区淘汰掉。
冷数据区域的缓存页什么时候放入到热区
如果在某个时间范围内,再次对这个缓存页进行访问,这个时候就会把它放到热区,在mysql中有一个规则:有可能在一秒内频繁访问某条数据,但是在1秒之后就再也不访问了,此时就会设置一个参数:innodb_old_blocks_time,默认1000毫秒。意味着,只有把数据页加载到缓存里,在经过1s之后再次对次缓存页进行访问才会将缓存页放到LRU链表的热区的头部。
为什么是1秒呢?
因为通过预读机制和全表扫描加载进来的数据页通常是1秒内就加载了很多,然后对他们访问一下,这些都是一秒内完成,他们会存放在冷数据区等待
刷盘清空
,基本上不太有机会进入到热区,除非1秒后还有人访问,说明后续可能还有人访问,才会放入热区的头部。