redis持久化策略
原因
redis数据是记录在内存中的,一旦出现断电、宕机等意外,数据则会丢失。
持久化模式(RDB+AOF)
RDB模式
是redis默认是持久化策略。
特点:redis会定期执行RDB持久化操作。
RDB记录的是内存数据的快照,并且后续的快照会覆盖之前的,每次都是最新的快照。
优势:效率高,速度快。 缺点:当空挡期间有可能存在数据丢失的风险。
redis指令:save 立即执行持久化策略 当有可能带来线程阻塞(该操作会生成快照文件dump.rdb)
bgsave 后台执行持久化策略。 异步操作,不会带来线程阻塞,当不会立即执行。
AOF模式
默认是关闭的,需要手动开启,开启后,RDB模式会失效,当如果手动执行了sava操作,则也会生成RDB文件。
开启AOF模式
指令 vim redis.conf :set nu 显示文件行号 将文件中大楷在702行改为 appendonly yes
退出并保存 指令: Esc :wq
也可以通过其他工具打开文件修改
AOF模式的特点:
记录程序执行的过程,可以保证数据不丢失
由于记录的是程序的执行过程,文件比较大,需要定期维护。也造成了速度慢、效率比较低。
RDB与AOF模式的对比
1).RDB模式
save 900 1 如果在900秒内,执行了一次更新操作则持久化一次
save 300 10
save 60 10000 操作越快 ,持久化的周期越短.
2).AOF模式
appendfsync always 用户执行一次更新操作,则持久化一次 异步操作
appendfsync everysec 每秒操作一次
appendfsync no 不主动操作 一般不用.
如果允许数据少量丢失,首先考虑RDB,不允许,则用AOF。一般主机采用RDB,从机采用AOF。
如果不小心在redis服务器中执行了flushAll指令? 在从库中执行save指令,将aof文件拷贝过去。
Redis内存策略
内存的空间是有限的,当有新的数据来的时候,内存不够会通过一些算法删除部分数据
1 LRU算法
最近最少使用算法 根据时间顺序删除一些之前的数据
2 LFU算法
最不经常使用页置换算法 删除使用次数最少的,根据频率来判断 frequency: 频率
3 随机算法
随机删除
4 TTL算法
对于那些有时间限定的数据,谁剩的最少谁先被删除
Redis的内存优化策略
1 volatile-lru 在设定超时时间的数据中采用LRU算法
2 allkeys-lru 所有的数据采用LRU算法删除
3 volatile-lfu 设定了超时时间的数据采用LFU算法删除
4 allkeys-lfu 所有数据采用LFU算法删除
5 volatile-random 设定了超时时间的数据采用随机算法
6 allkeys-random 所有数据的随机算法
7 volatile-ttl 设定了超时时间之后采用TTL算法
8 noeviction 不做任何操作,只是返回报错信息
关于Redis常见的面试题
什么是缓存穿透?
无效数据(内存、数据库中不存在的数据,一般为恶意攻击)大量访问访问数据库; 出现访问超时等现象。
解决方案:
禁用ip
限流
布隆过滤器
布隆过滤器原理:利用二进制向量存储,预加载时通过hash求模的方式来判断是否存在 误差大
解决方案:
1 增加二进制向量的位数
2 增加hash函数的个数
这里引用一位大佬对布隆过滤器的理解
布隆过滤器数据结构
布隆过滤器是一个 bit 向量或者说 bit 数组,这样:
如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1,例如针对值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7,则上图转变为:
Ok,我们现在再存一个值 “tencent”,如果哈希函数返回 3、4、8 的话,图继续变为:
值得注意的是,4 这个 bit 位由于两个值的哈希函数都返回了这个 bit 位,因此它被覆盖了。现在我们如果想查询 “dianping” 这个值是否存在,哈希函数返回了 1、5、8三个值,结果我们发现 5 这个 bit 位上的值为 0,说明没有任何一个值映射到这个 bit 位上,因此我们可以很确定地说 “dianping” 这个值不存在。而当我们需要查询 “baidu” 这个值是否存在的话,那么哈希函数必然会返回 1、4、7,然后我们检查发现这三个 bit 位上的值均为 1,那么我们可以说 “baidu” 存在了么?答案是不可以,只能是 “baidu” 这个值可能存在。
这是为什么呢?答案跟简单,因为随着增加的值越来越多,被置为 1 的 bit 位也会越来越多,这样某个值 “taobao” 即使没有被存储过,但是万一哈希函数返回的三个 bit 位都被其他值置位了 1 ,那么程序还是会判断 “taobao” 这个值存在。
支持删除么
目前我们知道布隆过滤器可以支持 add 和 isExist 操作,那么 delete 操作可以么,答案是不可以,例如上图中的 bit 位 4 被两个值共同覆盖的话,一旦你删除其中一个值例如 “tencent” 而将其置位 0,那么下次判断另一个值例如 “baidu” 是否存在的话,会直接返回 false,而实际上你并没有删除它。
如何解决这个问题,答案是计数删除。但是计数删除需要存储一个数值,而不是原先的 bit 位,会增大占用的内存大小。这样的话,增加一个值就是将对应索引槽上存储的值加一,删除则是减一,判断是否存在则是看值是否大于0。
如何选择哈希函数个数和布隆过滤器长度
很显然,过小的布隆过滤器很快所有的 bit 位均为 1,那么查询任何值都会返回“可能存在”,起不到过滤的目的了。布隆过滤器的长度会直接影响误报率,布隆过滤器越长其误报率越小。
另外,哈希函数的个数也需要权衡,个数越多则布隆过滤器 bit 位置位 1 的速度越快,且布隆过滤器的效率越低;但是如果太少的话,那我们的误报率会变高。
个人的理解
如果使用了多个hash算法,二进制向量的个数应该也会增加,不然很容易出现bit位上的值覆盖。而二进制向量的个数就相当于对数据库的数据进行了这么多次排序,可能还不如采用像坐标的方式(二维向量)来进行映射。
可能我的理解出现了点问题,以及知识点不够全面,希望有好心的大佬看到了能够给点建议。
缓存穿击
某个(一个)热点数据在缓存中突然失效(一般对于哪些设置了超时时间的数据)导致大量用户直接访问数据库
解决方案:
超时时间设置长一点
设置多台缓存,不同算法的
缓存雪崩
在缓存服务器中,有大量的缓存数据失效,倒是用户访问的命中率过低,从而直接访问数据库。(一般执行flushAll指令会导致)
解决方案:
设置超时时间时,采用随机算法。
采用多级缓存