redis持久化机制、删除策略、淘汰策略、数据一致性问题及布隆过滤器详解

2021年4月7日 4点热度 0条评论 来源: wadreamer

为了提高系统的访问效率和降低服务器压力,我们通常会采用缓存的策略,而使用缓存可以有效地支持高性能和高并发,而我们常用redis作为缓存。
高性能:
用户第一次访问数据库中的某些数据时,是从硬盘中读取的,该过程缓慢。而操作缓存是直接操作内存,速度快。所以,当第一次访问后,将数据存储在缓存,若数据库中的数据有变动,则同步改变缓存中相应的数据。

高并发:
直接操作缓存能够承受的请求是远远大于直接访问数据库的,可以将热点数据保存到缓存中,从而使部分请求直接到达缓存,而不用经过数据库,降低服务器压力的同时,提高了并发量。

为了更好地引入缓存一致性的问题,先来讲下redis的持久化策略、过期键的删除策略和内存淘汰策略。
一、redis持久化策略。
首先,redis支持RDB(默认)和AOF两种持久化策略。
a) RDB:Redis Database。RDB是Redis默认的持久化方式。每隔一定的时间周期就将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数可以设置生成快照的时间周期。

RDB的优缺点:

优点:
1、只有一个文件dump.rdb,方便持久化;
2、容灾性好,一个文件可以保存到安全的磁盘;
3、性能最大化。使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能;
4、相对于数据集大时,比AOF的启动效率更高

缺点:
1、数据安全性低。因为RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。

b) AOF:Append Only File。将Redis每次执行的写命令记录到单独的日志文件中,当重启Redis时,会从持久化的日志文件中重新恢复数据。
当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

AOF优缺点:

优点:
1、数据安全,AOF持久化可以令属性appendfsync为always,表示将每一次的命令操作记录到AOF文件中;
2、以append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。
3、AOF机制的rewrite模式,在AOF文件还没被rewrite之前(当文件过大时,会对文件中的命令进行合并重写),可以删除其中的一些命令。

缺点:
1、AOF文件比RDB文件大,且恢复速度慢。
2、数据集大的时候,比RDB启动效率低。

c) 对RDB和AOF两者进行对比:
如果同时配置了RDB和AOF,则优先加载AOF。

1、AOF文件比RDB更新频率高,优先使用AOF还原数据;
2、AOF比RDB更安全也更大
3、RDB性能比AOF好

二、过期键的删除策略
使用过Redis的都知道,Redis是key-value的数据库,我们可以设置redis缓存中key的过期时间,通常采用以下三种过期键的删除策略,Redis中同时使用惰性过期和定期过期两种过期策略。

三、Redis内存淘汰策略
Redis的内存淘汰策略是指用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。

好了,接下来讲下使用redis作为缓存时的缓存异常问题,即缓存与数据库的一致性问题,可以大致为分这三种:缓存穿透、缓存击穿和缓存雪崩。

针对上述三种问题,有不同的解决方案。

在上面的策略中,讲到了布隆过滤器,布隆过滤器也是面试中会被问到的一个知识点。
布隆过滤器只占用很小的内存空间,它通过bitmap(位数组)哈希映射函数来判断某个数据是否存在,仅是进行概率判断,即数据要么可能大概率存在,要么一定不存在。
a) 布隆过滤器组成及其执行过程。
布隆过滤器除了一个位数组外,还有k个哈希函数,当一个元素加入布隆过滤器时,会执行如下操作:

1) 使用k个哈希函数对元素进行k次计算,得到k个哈希值;
2) 根据得到的哈希值,在位数组中把对应的索引位置的值置为1.

而当判断一个值是否在布隆过滤器中时,会对该值进行k次哈希计算,再判断位数组中应对的k个位置的值是否都为1,若存在一个不为1,则说明该元素不存在,否则,说明该元素存在。
b) 布隆过滤器的数据结构:其本质是一个如下图所示的位数组,初始值都为0,数组元素能是0或者1,

若此时我们使用多个哈希函数映射若干个值到布隆过滤器中,如下所示:

若此时查询“益禾堂”,可以说该值一定存在吗?在图中可以看到,不同的值是存在哈希冲突的,即不同的值存在部分哈希值映射到位数组的同一个位置上,而随着存储的值增多,会有更多的位置被置为1。当我们查找不存在的值“星巴克”时,若此时哈希函数返回的三个bit位(不一定是3个,根据哈希函数确定)都为1,程序依然会判断该值“星巴克”存在。综上所述,上述问题只能说“益禾堂”可能存在。
此外,布隆过滤器不能删除其中的数据,若要删除某个值,则只能重建布隆过滤器。因为存在哈希冲突,若有两个不同的值映射到了相同的位置,那么,在某个时刻查询另一个数据时,会造成结果的错误。
综上所述,可以得出如下结论:

1、只要返回数据不存在,则肯定不存在;
2、返回数据存在,但只能是大概率存在;
3、不能删除其中的数据;
4、针对布隆过滤器的误判行为,可以采用建立白名单的存储可能被误判的元素;
5、因为redis本身支持setbit和getbit操作,所以可以使用redis实现布隆过滤器,
而其创建位数组的方式比较特殊,通过如下方式创建位数组,
如创建一个长度为10000、名为test的布隆过滤器:setbit test 10000 0
    原文作者:wadreamer
    原文地址: https://blog.csdn.net/weixin_41427129/article/details/105846742
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。