1、缓存应用 一个系统中不同层面数据访问速度不一样,以计算机为例,CPU、内存和磁盘这三层的访问速度从几十 ns 到 100ns,再到几 ms,性能的差异很大,如果每次 CPU 处理数据时都要到磁盘读取数据,系统运行速度会大大降低。 所以,计算机系统中,默认有两种缓存: (1)CPU 里面的末级缓存
缓存应用
缓存系统在计算机中非常重要,因为不同层级的数据访问速度差异很大。CPU、内存和磁盘的访问速度从几十纳秒到几毫秒不等。为了避免每次CPU处理数据都需从磁盘读取数据,系统会大大降低运行速度。为了解决这一问题,计算机系统中默认有两种缓存:CPU中的末级缓存(LLC)用于缓存内存中的数据,避免每次从内存中存取数据,内存中的高速页缓存(page cache)用于缓存磁盘中的数据,避免每次从磁盘中存取数据。
在层次化的系统中,缓存是一个快速子系统,在数据存在缓存中时,能够避免每次从慢速子系统中存取数据。在互联网应用中,Redis被视为快速子系统,而数据库则是慢速子系统。Redis是一个独立的系统软件,如果应用程序想使用Redis缓存,就需要增加相应的代码。因此,Redis也被称为旁路缓存,即读取缓存、读取数据库和更新缓存的操作都需要在应用程序中完成。Redis缓存根据是否接受写请求,分为只读缓存和读写缓存两种类型。只读缓存能够加速读请求,而读写缓存可以同时加速读写请求。读写缓存又分为同步直写和异步写回,可以根据业务需求在保证性能和数据可靠性之间进行选择。
淘汰机制
缓存的容量是有限的,需要按一定规则淘汰数据以腾出空间,提高缓存命中率,提升应用的访问性能。缓存容量的规划通常需要综合考虑应用数据实际访问特征和成本开销,建议把缓存容量设置为总数据量的15%到30%。对容量的设置可以通过命令CONFIG SET maxmemory 4gb来进行设置。同时,Redis提供8种淘汰策略:noeviction、volatile-random、volatile-ttl、volatile-lru、volatile-lfu、allkeys-lru、allkeys-random和allkeys-lfu。
这些策略大体可以分为两类,其中noeviction(不淘汰数据)表示当缓存已经被写满时再有写请求时Redis不再提供服务,直接返回错误。另外7种策略按一定范围对缓存数据进行淘汰,针对设置过期时间的数据进行淘汰以及对所有数据进行淘汰。具体包括volatile-ttl,volatile-rando,volatile-lru,volatile-lfu,allkeys-random,allkeys-lru和allkeys-lfu。LRU算法
LRU算法全称Least Recently Used,按照最近最少使用的原则来筛选数据,把最不常用的数据淘汰出去,而最近频繁使用的数据会留在缓存中。LRU会把所有的数据组织成一个链表,链表的头和尾分别表示MRU端和LRU端,分别代表最近最常使用的数据和最近最不常用的数据。LRU算法在实际实现时,需要用链表管理所有的缓存数据,并对被访问的数据进行链表移动操作。为了减轻数据淘汰对缓存性能的影响,Redis默认会记录每个数据的最近一次访问的时间戳(由键值对数据结构RedisObject中的lru字段记录)。 Redis在需要选择淘汰的数据时,首先会随机选择N个数据将它们作为一个候选集合,并比较它们的lru字段,最后淘汰lru字段最小的数据。淘汰数据时,Redis也会再随机选择一些lru字段比候选集合中最小lru字段还要小的数据,将它们放入候选集,如果候选集的数据个数达到了maxmemory-sample配置的个数,Redis就开始将lru字段值最小的数据淘汰。
LFU策略增加了一个计数器用以统计访问次数。淘汰数据时,首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。如果两个数据的访问次数相同,则再比较这两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出缓存。在实现LFU策略时,Redis把原来24bit大小的lru字段拆分成了两部分:ldt值和counter值。counter只有8bit,记录的最大值是255。因此,LFU策略采用了一个非线性递增的计数规则,通过配置不同的lfu_log_factor控制计数器值的增加速度。此外,Redis还设计了一个counter值的衰减机制,通过配置衰减因子lfu_decay_time来控制访问次数的衰减。具体操作是计算当前时间和数据最近一次访问时间的差值,再换算成分钟单位,再除以lfu_decay_time值,就是数据counter要衰减的值。
小编推荐阅读