19、MySQL是如何将LRU链表的使用性能优化到极致的
00 分钟
2022-8-26

19、MySQL是如何将LRU链表的使用性能优化到极致的

1、上篇文章的思考题

在LRU链表的冷数据区域中的都是什么样的数据呢?
大部分应该都是预读加载进来的缓存页,加载进来1s之后没人访问的,然后包括全表扫描或者一些大的查询语句,加载一堆数据到缓存页,结果都是1s之内访问了一下,后续就不再访问这些表的数据了。类似这些数据,统统都会放在冷数据区域里。

2、思考题

对于我们开发的Java系统,如果在Redis里存放了很多缓存数据,那么此时会不会有类似冷热数据的问题?应该如何优化和解决呢?
常见的一个场景就是电商系统里的商品缓存数据,假设你有1亿个商品,然后只要查询商品的时候发现商品不再缓存里,就给他放到缓存里去,你要这么做的话,必然导致大量的不怎么经常访问的商品会被放在Redis缓存里
经常被访问的商品其实就是热数据,不经常被访问的商品其实就是冷数据,我们应该尽量让Redis里放的都是经常访问的热数据,而不是大量的冷数据。因为你放一大堆不怎么经常访问的商品在Redis里,那么他占用了很多内存,而且后续还不怎么会访问到他们。
所以我们在设计缓存机制的时候,经常会考虑热数据的缓存预加载
也就是说,每天统计出来哪些商品被访问的次数最多,然后晚上的时候,系统启动一个定时作业,把这些热门商品的数据,预加载到Redis里。那么第二天是不是对热门商品的访问就自然会优先走Redis缓存了?

3、LRU链表的热数据区域是如何进行优化的?

接着我们来看看LRU链表的热数据区域的一个性能优化的点,就是说,在热数据区域中,如果你访问了一个缓存页,是不是应该要把他立马移动到热数据区域的链表头部去?
我们看下图的图示;
notion image
但是你要知道,热数据区域里的缓存页可能是经常被访问的,所以这么频繁的进行移动是不是性能也并不是太好?也没这个必要。
所以说,LRU链表的热数据区域的访问规则被优化了一下,即你只有在热数据的后3/4部分的缓存页被访问了,才会给你移动到链表头部去。
如果你是热数据区域的前面1/4的缓存页被访问,他是不会移动到链表头部去的。
举个例子,假设热数据去的链表里有100个缓存页,那么排在前面的25个缓存页,他即使被访问了,也不会移动到链表头部去,但是对于排在后面的75个缓存页,他只要被访问,就会移动到链表头部去。
这样的话,他就可以尽可能的减少链表中的节点移动了。

4、思考

如果一个缓存页的冷数据区域的尾巴上,已经超过1s了,此时这个缓存页被访问了一下,那么他此时会移动到冷数据区域的链表头部吗?注意,是冷数据区域的链表头部

评论