Redis数据的淘汰策略及Redis穿透导致的雪崩效应

        不管是在sql数据库中还是在Redis这种nosql数据库中,每个数据都会有一定数据大小的限制,在Redis中String最大长度为512M,list、set、hash的元素最大数量都是2^32-1,即4294967295个,我们可以根据实际情况对数据类型进行控制,默认在redis.conf中list、set、hash的配置如下,当超过配置的值时将会开启内存压缩


#hash类型的数据结构在编码上可以使用ziplist和hashtable。
#ziplist的特点就是文件存储(以及内存存储)所需的空间较小,在内容较小时,性能和hashtable几乎一样。
#因此redis对hash类型默认采取ziplist。如果hash中条目的条目个数或者value长度达到阀值,将会被重构为hashtable。
#这个参数指的是ziplist中允许存储的最大条目个数,,默认为512,建议为128。
hash-max-ziplist-entries 512

#ziplist中允许条目value值最大字节数,默认为64,建议使用1024。
hash-max-ziplist-value 64

#当取正值的时候,表示按照数据项个数来限定每个quicklist节点上的ziplist长度。
#比如,当这个参数配置成5的时候,表示每个quicklist节点的ziplist最多包含5个数据项。
#当取负值的时候,表示按照占用字节数来限定每个quicklist节点上的ziplist长度。
#这时,它只能取-1到-5这五个值,每个值含义如下:
#1).-5: 每个quicklist节点上的ziplist大小不能超过64 Kb。(注:1kb => 1024 bytes)
#2).-4: 每个quicklist节点上的ziplist大小不能超过32 Kb。
#3).-3: 每个quicklist节点上的ziplist大小不能超过16 Kb。
#4).-2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(-2是Redis给出的默认值)
#5).-1: 每个quicklist节点上的ziplist大小不能超过4 Kb。
list-max-ziplist-size -2


#这个参数表示一个quicklist两端不被压缩的节点个数。
#注:这里的节点个数是指quicklist双向链表的节点个数,而不是指ziplist里面的数据项个数。
#实际上,一个quicklist节点上的ziplist,如果被压缩,就是整体被压缩的。参数list-compress-depth的取值含义如下:
#1).0: 是个特殊值,表示都不压缩。这是Redis的默认值。
#2).1: 表示quicklist两端各有1个节点不压缩,中间的节点压缩。
#3).2: 表示quicklist两端各有2个节点不压缩,中间的节点压缩。
#4)3: 表示quicklist两端各有3个节点不压缩,中间的节点压缩。
#5). 依此类推…
#由于0是个特殊值,很容易看出quicklist的头节点和尾节点总是不被压缩的,以便于在表的两端进行快速存取。
list-compress-depth 0

#数据量小于等于set-max-intset-entries用intset,大于set-max-intset-entries用set。
set-max-intset-entries 512

#数据量小于等于zset-max-ziplist-entries用ziplist,大于zset-max-ziplist-entries用zset。
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

       虽然经过上面压缩后数据占用内存会变小,但是它也会一直增长,因此我们需要去配置Redis数据占用的总的内存大小,防止出现内存溢出,配置如下

#指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key。
#当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。
#Redis新的vm机制,会把Key存放内存,Value会存放在swap区,格式:maxmemory <bytes>。
maxmemory <bytes>

#当内存使用达到最大值时,redis使用的清除策略。有以下几种可以选择:
#1).volatile-lru   利用LRU算法移除设置过过期时间的key (LRU:最近最少使用 Least Recently Used )。
#2).allkeys-lru   利用LRU算法移除任何key。
#3).volatile-random 移除设置过过期时间的随机key。
#4).allkeys-random  移除随机key。
#5).volatile-ttl   移除即将过期的key(minor TTL)。
#6).noeviction  noeviction   不移除任何key,只是返回一个写错误 ,默认选项。
#7).volatile-lfu   利用LFU算法移除设置过过期时间的key (LFU:最不经常使用 Least Frequently Used)。
#8).allkeys-lfu   利用LFU算法移除任何key。
maxmemory-policy noeviction

#LRU 和 minimal TTL 算法在Redis中都不是精准的算法,但是相对精确的算法(为了节省内存) 你可以随意选择样本大小进行检查
#redis默认选择5个样本进行检测,你可以通过maxmemory-samples进行设置样本数。值越大,越接近LRU算法的精准度,但消耗CPU的性能就越高。
maxmemory-samples 5

       在默认情况下64位的操作系统的maxmemory设置的是0,表示没有内存限制,32位的操作系统为3GB。当到达内存使用最大值时我们就需要对内存中的数据进行清除,清除策略就如上面配置中解释的一样,这里主要解释下LRU和LFU的概念。

       LRU:Least Recently Used,最近最少使用,它是根据数据的历史访问记录来淘汰数据。如果数据最近被访问过,那么它再次被访问的概率就很高,这样的数据就会被保留下来,而很久没有被访问的数据就会被淘汰掉。

       LFU:Least Frequently Used,最不经常使用,它是在Redis4.0开始才出现的,它是根据数据历史访问频率来淘汰数据的。如果数据过去被访问过多次,那么它再次被访问的概率也很高,每次对key进行访问时,Redis会使用一个对数计算器来记录访问次数,同时这个对数计算器会随着时间的推移而不断变小。它首先比较的是访问次数,然后才是最近使用时间,它一般需要以一个时间段为基础,比如5分钟内,1分钟内等等。在Redis中启用该策略我们可以通过 redis-cli --hotkeys进行热点数据的分析。

       在使用Redis缓存数据时,哪些数据适合进行缓存呢?一般情况下下面3种数据是比较适合的:

       1).访问频率高的数据。

       2).读多写少的数据。

       3).一致性要求低的数据。

       在Redis执行完清除策略后,这个时候刚好有大量的客户端来访问被删除的数据,这个时候会出现什么呢?是不是我们就需要到数据库执行查询操作,这个时候就出现了Redis的缓存击穿。如果这个时候数据库的内存数量有限,而查询操作超过了数据库服务器能够承受的范围,这个时候是不是会导致内存溢出,数据库服务器是不是崩溃,这个时候就会出现所谓的雪崩现象。

        我们先了解下缓存击穿和缓存穿透的区别,从总体的来说它们没有区别,都是指数据在Redis缓存中不能进行查询到,都要到数据库进行查询从而返回给客户端:

        1).缓存击穿:它是指热点key因为设置了过期时间在这个时候刚好大面积的过期或者非热点key突然变成了热点key,但是因为淘汰机制提前把这种key淘汰掉了,导致客户端去数据库查询数据。

        2).缓存穿透:它是指客户端去查询不存在的key或者已经删除了的key,导致在Redis缓存中查询不到,从而去数据库中查询。

       那么针对缓存击穿和缓存穿透导致的缓存雪崩我们怎么预防呢?我们可以通过下面一些方法来预防:

      1.针对热点key大面积过期,我们可以设置不同的过期时间来在不同的时间过期不同的数据。

      2.针对淘汰机制这种情况,我们完全可以互斥锁的方式使用一个客户端去数据库获取key即可。

      3.针对数据库中不存在的数据,我们也可以把该key在Redis中进行缓存,同时针对这种key设置一个过期时间,这样就可以防止客户端不停的去数据库获取数据。

      4.通过布隆过滤进行一些不存在的key过滤。

      5.使用主从复制防止master服务器宕机造成的数据库服务器雪崩。

      6.针对每个客户端访问的进行限流限次限频,从而达到资源隔离。

      7.服务降级,针对一些特定的key在有无值时,根据实际情况直接返回给定的信息。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值