Redis缓存(二)缓存淘汰策略,脏数据/脏页,缓存污染

一、应该给Redis分配多少内存空间

八二原则80%的请求都是访问数据库中同样的20%的数据(热点数据只占20%),所以一般给Redis分配15% - 30%数据总量的内存空间(只保存热点数据,冷数据被访问少,直接到数据库访问)

二、Redis八种内存淘汰机制

请添加图片描述

三、LRU算法

  • 传统LRU算法:底层维护一个双向链表,每个节点存放一个数据,当某个数据被访问时,该节点会被放到链表头部(MRU端),当触发内存淘汰时会先删除链表的尾部(LRU端)。
    缺点:每个数据都要一个链表节点维护,内存开销大,频繁移动链表,CPU压力大,无法保证MRU端是热点数据,可能只是刚好在内存淘汰前被访问,之前都是冷数据。
    请添加图片描述
  • Redis中的LRU算法:Redis对原生LRU算法进行了改进,会随机挑选5个键加入链表,淘汰其中最久未被访问的(不用为每一个数据维护链表节点,且不用在每次访问数据时移动链表)。

四、推荐使用的淘汰算法

  • A) 存在冷热数据的区分时,使用allkeys – lru,可以保留热点数据;
  • B) 没有冷热数据区分,每个数据被访问的频率差不多,使用allkeys-random
  • C) 某些数据有置顶需求,不能被淘汰,使用volatile-lru,给置顶数据不设置过期时间,保证不会被淘汰。

五、MySQL脏数据、脏页与Redis的脏数据

  • MySQL脏数据:读到的数据是其他事务修改后的数据,但最后事务回滚了,数据库中数据还是原来的值,但是读到的当前数据是事务回滚前修改的值,与数据库中不一致。—客户端读到的数据,而不是存在于MySQL内存页中的数据
  • Redis脏数据:Redis内存中数据的值和当前数据库中不一致。
  • MySQL脏页:MySQL内存页上的数据已经更改但是还没刷入到磁盘中。

注:MySQL在清理内存时,会将脏页先更新到数据库,在删除内存中的该数据页
Redis清理内存时,不会将脏数据写到数据库中,所以当数据改变时要同时改变数据库与Redis中该数据的值

六、保证Redis与MySQL中数据的一致性方案:采用分布式事务

两阶段提交(2PC),三阶段提交(3PC),TCC,消息队列


以下补充缓存污染与应对的LFU缓存淘汰策略

七、缓存污染与LFU算法:

缓存污染:访问频率低的数据占用大量内存,造成资源浪费。

解决方法:

  • LFU淘汰机制

按照数据被访问的频率淘汰内存中的数据,在数据的RedisObject结构体中增加一个lru字段存放数据最近被访问的时间戳以及总共被访问的次数。优先比较被访问的次数低的数据被淘汰,如果访问次数一致,再比较时间戳淘汰最近一次访问时间久远的数据。

LFU算法优化

  1. 时间戳 + 计数器(优先比较计数器,再比较时间戳);
  2. 计数器非线性递增(并非访问一次计数器就加一,避免计数器(8bit)越界);
  3. 计数器衰减机制(避免某些数据短期大量访问后不再被访问,会随着未访问时间的增大降低计数器的数值)。

参考文章:

https://time.geekbang.org/column/article/294640

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值