type
status
date
slug
summary
tags
category
icon
password

1、Redis键空间

默认情况下,Redis中有16个数据库,编号从0-15,每个Redis数据库使用一个redisDb对象来表示,每个redisDb对象实际上是一个dict结构的数据集合。
其中dict保存了该db中的所有键值对。键值对中键是一个字符串对象,每个值可以是字符串对象、列表对象、哈希表对象、集合对象和有序集合对象在内的任意一种 RedisObject。
notion image
redis通过全局哈希表保存所有的key值,所以查找key的时间为O(1)。redis一下次写入太多数据有可能会产生哈希冲突,全局哈希表也是通过渐进式rehash来解决大量hash冲突的问题

2、过期删除策略

我们可以设置Redis中缓存的key的过期时间。过期删除策略就是指当Redis中缓存的key过期了Redis会如何删除,通常有以下策略:
过期策略
描述
优点
缺点
定时删除
每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。
节省内存
cpu不友好,频繁的删除可能会影响性能
惰性删除
只有当访问一个key时,才会判断该key是否已过期,过期则清除。
内存不友好,可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
节省CPU资源
定期删除
每隔一段时间,扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。
前两者的一个折中方案,使得CPU和内存资源达到最优的平衡效果。
Redis同时使用了惰性过期和定期过期两种过期策略
  1. 每当我们设置一个key的过期时间时,Redis就会将该key带上过期时间存放到一个过期dict中。
  1. 当我们查询一个键时,Redis便首先检查该键是否存在过期字典中,如果存在,那就获取其过期时间。然后将过期时间和当前系统时间进行比对,比系统时间大,那就没有过期;反之判定该键过期。
  1. Redis 默认会每100ms扫描一次,但不会遍历过期dict中所有的 key,而是采用了一种简单的贪心策略。
    1. 从过期字典中随机 20 个 key。
    2. 删除这 20 个 key 中已经过期的 key。
    3. 如果过期的 key 比率超过 1/4,那就重复步骤 1。

3、内存淘汰策略

虽然我们有过期策略来淘汰已过期的数据,但是如果大量数据过期时间还没到,但此时内存已经快被占满了,我们就需要通过内存淘汰策略选择淘汰哪些数据。
内存淘汰策略
描述
noeviction
不淘汰数据,默认策略。
volatile-ttl
在设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除。
volatile-random
在设置了过期时间的键值对中,进行随机删除。
volatile-lru
在设置了过期时间的键值对,使用LRU算法筛选,删除最近最长时间不使用的key。redis对LRU的优化:每次随机选出N个数据,比较该N个数据的最近访问的时间戳,然后最长时间不访问的数据。
volatile-lfu
在设置了过期时间的键值对,使用LFU算法选择,删除最近使用次数最少的key。
allkeys-random
从所有键值对中随机选择数据进行删除。
allkeys-lru
在所有数据中进行筛选,使用LRU算法,删除最近最长时间不使用的key。
allkeys-lfu
在所有数据中进行筛选,使用LFU算法,删除最近使用次数最少的key。
这八种策略大体分为「不进行数据淘汰」和「进行数据淘汰」两类策略。针对「进行数据淘汰」这一类策略,又可以细分为「在设置了过期时间的数据中进行淘汰」和「在所有数据范围内进行淘汰」这两类策略。
notion image
LRU和LFU算法比较:
  • LRU(Least Recently Used):淘汰最长时间未被使用的页面,强调的是最近访问时间。链表按访问时间进行排序,表头是最近访问的页面。如果访问命中了页面,就把页面移动到链表表头;如果没有命中就从表尾删除页面,然后把新页面放在表头,是比较符合正常思维逻辑的算法。
  • LFU(Least Frequently Used):淘汰最近被访问次数最少的页,强调的是最近访问频率。链表按访问次数进行排序,表头是访问次数最多的页面。如果访问命中了页面,就把页面的访问次数加一,此时如果该页面的访问次数大于前一个页面就互相交换位置;如果没有命中页面就从表尾删除数据。这种算法有一个明显的问题:如果某页面开始访问次数较多,但后面没有再被访问,这些页面无法被删除。所以LFU算法用的比较少。
淘汰策略选择建议:
  • 优先使用 allkeys-lru 策略。这样,可以充分利用LRU这一经典缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。如果你的业务数据中有明显的冷热数据区分,我建议你使用 allkeys-lru 策略。
  • 如果业务应用中的数据访问频率相差不大,没有明显的冷热数据区分,建议使用 allkeys-random 策略, 随机选择淘汰的数据就行。
  • 如果你的业务中有置顶的需求,比如置顶新闻、置顶视频,那么,可以使用 volatile-lru 策略,同时不给这些置顶数据设置过期时间。这样一来,这些需要置顶的数据一直不会被删除,而其他数据会在过期时根据 LRU规则进行筛选。
Redis持久化Redis数据结构和对象
mcbilla
mcbilla
一个普通的干饭人🍚
Announcement
type
status
date
slug
summary
tags
category
icon
password
🎉欢迎来到飙戈的博客🎉
-- 感谢您的支持 ---
👏欢迎学习交流👏