论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
数据库
›
PostgreSQL
›
【Redis】Redis 缓存应用、淘汰机制—(四) ...
【Redis】Redis 缓存应用、淘汰机制—(四)
南飓风
金牌会员
|
2024-8-25 13:26:02
|
显示全部楼层
|
阅读模式
楼主
主题
878
|
帖子
878
|
积分
2634
一、缓存应用
一个体系中不同层面数据访问速度不一样,以盘算机为例,CPU、内存和磁盘这三层的访问速度从几十 ns 到 100ns,再到几 ms,性能的差别很大,如果每次 CPU 处理数据时都要到磁盘读取数据,体系运行速度会大大低落。
以是,盘算机体系中,默认有两种缓存:
(1)CPU 里面的末级缓存,即 LLC,用来缓存内存中的数据,避免每次从内存中存取数据。
(2)内存中的高速页缓存,即 page cache,用来缓存磁盘中的数据,避免每次从磁盘中存取数据。
在一个层次化的体系中,缓存一定是一个快速子体系,数据存在缓存中时,能避免每次从慢速子体系中存取数据。对应到互联网应用来说,Redis 就是快速子体系,而数据库就是慢速子体系了。
Redis 是一个独立的体系软件,如果应用程序想使用 Redis 缓存,就需要增长相应的代码。以是,我们也把 Redis 称为旁路缓存,也就是说,读取缓存、读取数据库和更新缓存的操作都需要在应用程序中来完成。
Redis 缓存按照是否接受写哀求,分为只读缓存和读写缓存两种类型,只读缓存能加速读哀求,而读写缓存可以同时加速读写哀求。读写缓存又分为同步直写和异步写回,可以根据业务需求在保证性能和保证数据可靠性之间进行选择。
二、淘汰机制
缓存的容量终究是有限的,需要按一定规则淘汰出去,为新来的数据腾出空间,提高缓存掷中率,提拔应用的访问性能。缓存容量的规划通常是需要结合应用数据现实访问特性和本钱开销来综合考虑的,建议把缓存容量设置为总数据量的 15% 到 30%,分身访问性能和内存空间开销。设置容量下令(如4gb):CONFIG SET maxmemory 4gb
8种淘汰计谋:noeviction、volatile-random、volatile-ttl、volatile-lru、volatile-lfu、allkeys-lru、allkeys-random、allkeys-lfu
大体分为两类,noeviction(不淘汰数据),缓存被写满了,再有写哀求时 Redis 不再提供服务,直接返回错误。另外7种是一类,按照一定范围对缓存数据进行淘汰,对设置过期时间的数据进行淘汰,和对所有数据进行淘汰。分类如图:
具体计谋如下:
(1)volatile-ttl: 根据过期时间的先后进行删除,越早过期的越先被删除。
(2)volatile-rando: 在设置了过期时间的键值对中,进行随机删除。
(3)volatile-lru: 使用 LRU 算法筛选设置了过期时间的键值对。
(4)volatile-lfu: 使用 LFU 算法选择设置了过期时间的键值对。
(5)allkeys-random:从所有键值对中随机选择并删除数据。
(6)allkeys-lru: 使用 LRU 算法在所有数据中进行筛选。
(7)allkeys-lfu: 使用 LFU 算法在所有数据中进行筛选。
三、LRU 算法
LRU 算法全称 Least Recently Used,按照近来最少使用的原则来筛选数据,最不常用的数据会被筛选出来,而近来频繁使用的数据会留在缓存中。
LRU 会把所有的数据组织成一个链表,链表的头和尾分别表现 MRU 端和 LRU 端,分别代表近来最常使用的数据和近来最不常用的数据。
举个栗子:数据 20 和 3 被访问后,它们在链表中的位置移动到了 MRU 端,LRU 算法选择删除数据时,都是从 LRU 端开始,以是当新数据15被写入时,LRU 端的数据5被删除。
LRU 算法在现实实现时,需要用链表管理所有的缓存数据,这会带来额外的空间开销。而且,当有数据被访问时,需要在链表上把该数据移动到 MRU 端,如果有大量数据被访问,就会带来很多链表移动操作,会很耗时,进而会低落 Redis 缓存性能。
以是,在 Redis 中,LRU 算法被做了简化,以减轻数据淘汰对缓存性能的影响,具体实现原理是 Redis 默认会记录每个数据的近来一次访问的时间戳(由键值对数据布局 RedisObject 中的 lru 字段记录),在需要选择淘汰的数据时,Redis首先会随机选择N个数据将它们作为一个候选集合,然后比较他们的lru字段,将lru字段最小的数据淘汰掉。
N 可以通过下令设置:
CONFIG SET maxmemory-samples 100
复制代码
当再次淘汰时,Redis会再挑选一些lru字段比候选集合中最小lru字段还要小的键值对,将它们放入候选集,如果候选集的数据的个数到达了 maxmemory-sample 配置的个数,Redis就开始将lru字段值最小的数据淘汰
四、LFU 算法
与 LRU 计谋相比,LFU 计谋中会从两个维度来筛选并淘汰数据:一是,数据访问的时效性(访问时间离当前时间的远近);二是,数据的被访问次数。就是在 LRU 计谋基础上,为每个数据增长了一个计数器,来统计访问次数。淘汰数据时,首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。如果两个数据的访问次数相同,再比较这两个数据的访问时效性,把间隔上一次访问时间更久的数据淘汰出缓存。
具体实现是把原来 24bit 大小的 lru 字段,又进一步拆分成了两部门:ldt 值(lru 字段的前 16bit,表现数据的访问时间戳)、counter 值(lru 字段的后 8bit,表现数据的访问次数)。但是 counter 只有 8bit,记录的最大值是 255,显然不能因对数据成千上万次的访问。现实 LFU 计谋实现时,数据访问并不是简单的 counter 值加 1 的计数规则,而是采用了一个更优化的计数规则。
每当数据被访问一次时,首先,用计数器当前的值乘以配置项 lfu_log_factor 再加
1,再取其倒数,得到一个 p 值;然后,把这个 p 值和一个取值范围在(0,1)间的随机数 r 值比大小,只有 p 值大于 r
值时,计数器才加 1,通过设置不同的 lfu_log_factor 配置项,来控制计数器值增长的速度。以下是盘算方式部门代码
(baseval当前值)和 lfu_log_factor 设置不同值的变化情况:
double r = (double)rand()/RAND_MAX;
...
double p = 1.0/(baseval*server.lfu_log_factor+1);
if (r < p) counter++;
复制代码
正是因为使用了非线性递增的计数器方法,即使缓存数据的访问次数成千上万,LFU 计谋也可以有效地区分不同的访问次数,从而进行合理的数据筛选。从刚才的表中,我们可以看到,当 lfu_log_factor 取值为 10 时,百、千、十万级别的访问次数对应的 counter 值已经有显着的区分了,以是,我们在应用 LFU 计谋时,一般可以将 lfu_log_factor 取值为 10。
有些数据在短时间内被大量访问后就不会再被访问了,按访问次数筛选时,这些数据会被留存在缓存中,但不会提拔缓存掷中率。为此,Redis 在实现 LFU 计谋时,还设计了一个 counter 值的衰减机制。通过配置衰减因子 lfu_decay_time 来控制访问次数的衰减。
具体操作是盘算当前时间和数据近来一次访问时间的差值,换算身分钟单位,再除以 lfu_decay_time 值,就是数据 counter 要衰减的值。lfu_decay_time 值越大,相应的衰减值会变小,衰减效果也会减弱。以是,如果业务应用中有短时高频访问的数据的话,建议把 lfu_decay_time 值设置为 1,它们不再被访问后,会较快地衰减它们的访问次数,尽早把它们从缓存中淘汰出去,避免缓存污染。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
南飓风
金牌会员
这个人很懒什么都没写!
楼主热帖
零信任介绍
开源SPL助力JAVA处理公共数据文件(txt ...
容斥原理
数理逻辑第1-3章
使用 Helm 安装 MQTT 服务器-EMQX ...
Ubuntu如何安装Mysql+启用远程连接[完 ...
DOS窗口命令和单表简单查询
Java笔记(13) 简单的Lambda表达式 ...
dotnet 修复在 Linux 上使用 SkiaSharp ...
.gitignore文件配置以及gitee提交报Pus ...
标签云
挺好的
服务器
快速回复
返回顶部
返回列表