大家好,我是程序员阿药。接上一篇LRU算法的优化手段(一),今天分享的是优化手段(二),也就是如何优化LRU算法解决缓存污染问题。
话不多说,发车!
当一次读取批量数据页时,这些数据页都将加入到activeList链表头部或hot区的链表头部,很有可能就会将之前的热点数据页从activeList或hot区中淘汰。此时如果这些新加入的数据页只访问了一次,在后面很长一段时间都没有被访问的话,那么就造成了缓存污染。
由于出现了缓存污染,当再次访问之前的热点数据时命中率将大大降低,此时会出现大量的磁盘IO,系统性能会急速下降。
我以Linux中activeList链表和noActiveList链表举例说明。假设需要批量读取11、12、13、14、15、16、17这七个页。如图:
在批量读取后这七个页都会被加入到activeList链表的头部,然后将4、5、6、7、8、9、10这七个页淘汰。如图:
可以看到,原本在activeList中的4、5号页都被淘汰了,如果后面很长一段时间内都不会对11、12、...17这七个页访问的话,那么activeList就被污染了。如果此时再对4、5号页访问的话,由于缓存不能命中,那么就需要到磁盘中进行读取,降低了Linux的性能。
既然出现了问题,那么就要有相应的解决办法。
通过对问题的分析可以发现,出现此问题的原因是数据页添加到activeList链表头部或hot区的链表头部的门槛太低了。所以想解决这个问题,那么就要提高数据页访问时进入activeList或hot区的门槛,只要将这个门槛提高,那么热点数据页就不容易被轻易淘汰。
在Linux和MySQL中提高门槛的方法如下。
-
Linux:在内存中的数据页第二次访问后,才会从noActiceList链表中移动到activeList链表头部。
-
MySQL:在内存中的数据页第二次访问后,再判断该数据页在cold区中的停留时间。如果第一次访问和第二次访问的时间间隔在1秒内那么就不会将数据页从cold区移动到hot区,如果超过1秒则进行移动。
通过提高进入activeList链表和hot区的门槛就可以很好的避免缓存污染问题。当批量访问数据页时,如果这些数据页只被访问一次那么他们只能进入noActiveList链表或cold区中,并不会对原本存在的热点数据页造成任何影响,同时这些只访问一次的数据页也会很快被淘汰。
到此为止,LRU算法的优化手段全部和大家分享完毕。如果有写的不好的地方,希望大家可以批评指正;同时希望我的分享对大家有所帮助。
我是程序员阿药,喜欢的小伙伴可以点赞收藏支持一下,更多文章可以关注我的微信公众号:“程序员阿药”。