<span id="ubbei"><video id="ubbei"></video></span>
<span id="ubbei"></span>
<span id="ubbei"><video id="ubbei"></video></span>
<strike id="ubbei"><video id="ubbei"></video></strike><th id="ubbei"></th>
<span id="ubbei"><video id="ubbei"></video></span><span id="ubbei"></span><span id="ubbei"><video id="ubbei"></video></span>
<th id="ubbei"><video id="ubbei"><span id="ubbei"></span></video></th>
<span id="ubbei"></span>
<th id="ubbei"><video id="ubbei"><span id="ubbei"></span></video></th><strike id="ubbei"><dl id="ubbei"><ruby id="ubbei"></ruby></dl></strike>
<span id="ubbei"></span>
<th id="ubbei"></th>
<span id="ubbei"></span>
<th id="ubbei"></th>
<span id="ubbei"></span>
<span id="ubbei"></span>
<span id="ubbei"></span>
<span id="ubbei"><video id="ubbei"><strike id="ubbei"></strike></video></span>
<strike id="ubbei"><video id="ubbei"></video></strike>

  • <output id="ubbei"></output>
          1. <li id="ubbei"><s id="ubbei"><strong id="ubbei"></strong></s></li>
          2. Redis 内存管理赏析

            声明:本文是对 4.0.6版本 Redis的 内存管理部分的(xuexi)总结,有些YY的成分,作者本意不想误导, 如有错误, 敬请谅解。

            一、凡事先问个为什么

            Redis是互联网公司主流的分布式缓存解决方案,缓存的本质是“ 就近暂存 ”,解决的是“ 减少去较远的地方拿我想要的东西要耗费较大成本 ”的问题。本小节我们要探究的不是为什么要用缓存,而是Redis为什么要做内存管理这件事情。决定一件事情做不做的理由 绝对不是 “这件事情可以做”,我认为Redis做内存管理的主要原因是: 内存(RAM)资源宝贵,内存管理让内存的使?#20204;?#20917;可控

            二、遵循底线、条条大路通罗马

            那么怎么做内存管理呢?管理包括对个体的管理和对总体的管理,个体上比如对Redis中存储的每个对象的大小,质量等进行管理;Redis的做法遵循 简单原则 ,在内存使用的总?#21487;?#21010;一道“ 允许最大使用内存量 ”这条底线。为了遵循这条底线,Redis在实现上是这么做的:当使用内存量高于这条底线的时候,所有的写操作将会直接失败,绝不手软,但是这个时候仍然理智地支持读操作。在底线的基础之上Redis提供的管理手段是“淘汰机制”,注意 淘汰机制是管理的一?#36136;?#27573; 。那么怎么淘汰呢??#21019;?#23567;?按年龄?Redis提供以?#24405;?#31181;选择淘汰KEY的策略:

            LRU: 看看哪个KEY最长时间没有被使用啦,就选你吧,你看你这么长时间都没被使用了,就别站着地方了。

            LFU: 如果说上面的方法较为片面,那这里?#22270;由?#19968;个期限,看看哪个KEY在一段时间内访问的频率最低好吧,谁最低,淘汰谁。

            RANDOM: 不想那么多了,整个世界都是随机的,随机的世界就随机选择一个KEY吧,爱咋咋地。

            TTL: 选择最近即将过期的KEY进行淘汰。

            最后一种比较有意思,那就是—— 不淘汰 ,哈哈, 对于一个问题不去解决往往也是一种解决方案

            三、难易相成、长短相形

            在主从模式且主库开启maxmemory策略的情况下,对于与主库来说,如果用于从库同步的缓冲区也被作为内存使用量计算进来,在某些极端情况下,比如:主从之间网络出现异常,这个时候内存使用又达到阈值,显然Redis此时会进行eviction操作,eviction操作本身会产生大量的DELs操作日志用于同步给从库,这部分日志有会填充在主从同步缓存中,由于这部分内存会被计算进内存使用量,因此又会触发eviction操作,?#32531;?#32487;续恶性循环……,直至最后内存被清空。 引入一种方案时长会伴随着引入新的问题和忧患,这需要我们提高警惕 ,那么怎么解决这个问题呢?Redis的做法很简单,就是用于从库同步的缓冲区内存大小不作为使用内存计算的,这样就不会存在上述问题了。在?#23548;?#20351;用中,当以主从模式使用Redis且开启了maxmemory策略的时候,建议maxmemory这个值设置稍微小一些,预留一部分给主动同步缓冲区使用。

            四、损有余、补不足

            在?#23548;?#23454;现LRU、LFU和最小TTL算法的时候面临一些问题,比如LRU算法要求淘汰最长时间没有使用的KEY,如果要精准满足“ 最长时间没有使用 ”这个条件,我们必须要遍历所有的KEY?#32531;?#25165;能根据其上?#38382;?#29992;的时间计算出哪个KEY是最长时间没有被访问的。问题来了,?#23548;?#19978;Redis中可能存在成千上万个KEY,每次都要挨个遍历岂不是要疯了? ?#23548;?#24819;一想精确真的是我们想要的吗? ?#23548;蔙edis实现的LRU、LFU和最小TTL算法都是基于近似算法计算的,用 精确?#28982;?#26102;间 (扩展一下hyperloglog是用准确性换空间),关键算法是?#32791;?#35748;情况下Redis每次只随机选择5(可以通过maxmemory-samples?#38382;?#35774;置,maxmemory-samples越大的时候?#36739;?#32791;内存,maxmemory-samples越小的时候越快,但是越不精确)个KEY,?#32531;?#20174;这5个KEY中?#19994;?#26368;符合条件的,这个思想其实也类似选择择局部最优,放弃全局最优的贪心算法。

            五、精益求精、追求卓越

            无论是LRU、LFU还是TTL都是基于?#20302;?#26102;间的,在一般操作?#20302;?#20013;,读取?#20302;?#30340;当前时间需要进行system call,system call意味着操作?#20302;?#38656;要陷入内核态,陷入内核态意味着用户态与内核态的上下文切换,上下文切换意味着成本……。为了实现内存淘汰,Redis需要为每个KEY都维护着一个这样的时间,而?#20197;贙EY被访问的时候需要读取操作?#20302;?#24403;前时间将其更新,试想一下,在上W QPS的应用场景下,每次都要去system call在高性能的场景下是一件多么恐怖的事情。?#23548;蔙edis是怎?#21019;?#29702;的呢?这里有个背景,Redis所谓的单线程指的是Redis对于客户端读写的处理和内部的一些日常事务处理都是由一个eventloop线程?#21019;?#29702;的,这里的日常事务包括一项:每次读取当前?#20302;?#26102;间记录在一个变量里面。一般情况Redis所读取的时间都是从这里读取的,也就是由于eventloop线程提前计算好的,?#27604;?#22914;果eventloop的loop频?#26102;?#36739;低的话这个值将会具有一定延迟。

            我来评几句
            登录后评论

            已发表评论数()

            相关站点

            +订阅
            ?#35753;?#25991;章
            陕西高频十一选五 上海快三开奖最新 必赢客新时时彩 网球场地标准尺寸 六合六合图库网址大 太原那有老时时彩 广东11选5杀号预测 11选5漏洞赚千万 黑龙江快乐十分号码遗漏 建22选5开奖走势 第88期现场开彩结果 内蒙古快三专家预测号码 体育彩票双色球开奖结果开奖结果 白小姐6合规律 河北时时彩玩法 湖北11选5交流