Redis 几个容易弄混的概念
redis能干啥?
MySQL说,其实有一大半的用户请求都是读操作,而且经常都是重复查询一个东西,浪费它很多时间去进行磁盘I/O。
后来有人就琢磨,是不是可以学学CPU,给数据库也加一个缓存呢?于是redis就诞生了!
缓存的数据都是在内存中,可是就算是在服务器上,内存的空间资源还是很有限的。
如何处理内存不足?
1、给缓存内容设置一个超时时间,具体设置多长交给应用程序们去设置,我要做的就是把过期了的内容从我里面删除掉,及时腾出空间就行了。
定期删除,我决定100ms就做一次,一秒钟就是10次!
2、惰性删除
那些原来逃脱我随机选择算法的键值,一旦遇到查询请求,被我发现已经超期了,那我就绝不客气,立即删除。
这种方式因为是被动式触发的,不查询就不会发生,所以也叫惰性删除!
3、内存淘汰策略
我提供了8种策略供应用程序选择,用于我遇到内存不足时该如何决策:
-
noeviction:返回错误,不会删除任何键值
-
allkeys-lru:使用LRU算法删除最近最少使用的键值
-
volatile-lru:使用LRU算法从设置了过期时间的键集合中删除最近最少使用的键值
-
allkeys-random:从所有key随机删除
-
volatile-random:从设置了过期时间的键的集合中随机删除
-
volatile-ttl:从设置了过期时间的键中删除剩余时间最短的键
-
volatile-lfu:从配置了过期时间的键中删除使用频率最少的键
-
allkeys-lfu:从所有键中删除使用频率最少的键
缓存穿透
有时候遇到些烦人的请求,查询的数据不存在,MySQL就要白忙活一场!不仅如此,因为不存在,我也没法缓存啊,导致同样的请求来了每次都要去让MySQL白忙活一场。我作为缓存的价值就没得到体现啦!这就是人们常说的缓存穿透。
布隆过滤器
直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中。
和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一个标志,用来判断key是否在集合中。
算法:
1. 首先需要k个hash函数,每个函数可以把key散列成为1个整数
2. 初始化时,需要一个长度为n比特的数组,每个比特位初始化为0
3. 某个key加入集合时,用k个hash函数计算出k个散列值,并把数组中对应的比特位置为1
4. 判断某个key是否在集合时,用k个hash函数计算出k个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,认为在集合中。
优点:不需要存储key,节省空间
缺点:
1. 算法判断key在集合中时,有一定的概率key其实不在集合中
2. 无法删除
如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit Array)中的一个点。这样一来,我们只要看看这个点是不是 1 就知道可以集合中有没有它了。这就是布隆过滤器的基本思想。
布隆过滤器是在缓存之前设定的。
1.不存在的元素直接返回,不能进Redis里面
2.存在的元素,可能在Redis中,Redis要是有的对应的数据的话直接返回数据,要是没有数据访问数据库返回数据 这样减少数据库的压力。
缓存击穿 && 缓存雪崩
缓存击穿:有一个热点数据到了过期时间,被我删掉了,不巧的是随后就有对这个数据的大量查询请求来了,我这里已经删了,所以请求都发到你那里来了”。
缓存雪崩:这一次是一大批数据几乎同时过了有效期,然后又发生了很多对这些数据的请求,所以比起上一次这规模更大了”。
找应用程序商量了,不仅把键值的过期时间随机了一下,还设置了热点数据永不过期,这个问题缓解了不少。
引用如下:
https://www.cnblogs.com/xuanyuan/p/13665170.html