Redis 内存模型、持久化方式、主从复制、哨兵机制,一致性哈希原理,常用的数据类型、缓存穿透以及缓存雪崩原理和解决方案,过布隆过滤器的实现原理

底层模型

  • 底层模型

    • Redis底层

      跳表-跳着的链表

      什么是Redis

      • 高性能非关系型(NoSQL)的键值对数据库。

      • Redis 除了做缓存之外,Redis 也经常用来做分布式锁,甚至是消息队列。

      • Redis 提供了多种数据类型来支持不同的业务场景。Redis 还支持事务 、持久化、Lua 脚本、多种集群方案。

      分布式缓存有哪些

      使用的比较多的主要是 MemcachedRedis。不过,现在基本没有看过还有项目使用 Memcached 来做缓存,都是直接用 Redis

      缓存数据的处理流程是怎样的?

      • 如果用户请求的数据在缓存中就直接返回。

      • 缓存中不存在的话就看数据库中是否存在。

      • 数据库中存在的话就更新缓存中的数据。

      • 数据库中不存在的话就返回空数据。

持久化方式

  • 持久化机制和特点

    • Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制:

    • RDB:是Redis DataBase缩写快照

      RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。

    • 优点:

      • 1、只有一个文件 dump.rdb,方便持久化。

      • 2、容灾性好,一个文件可以保存到安全的磁盘。

      • 3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能

      • 4.相对于数据集大时,比 AOF 的启动效率更高。

      缺点:

      • 1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)

      • 2、AOF(Append-only file)持久化方式:是指所有的命令行记录以 redis 命令请 求协议的格式完全持久化存储)保存为 aof 文件。

      AOF:持久化

      • AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。

      • 当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

    • 优点:

      • 1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。

      • 2、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

      • 3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))

      缺点:

      • 1、AOF 文件比 RDB 文件大,且恢复速度慢。

      • 2、数据集大的时候,比 rdb 启动效率低。

    • 优缺点是什么?

      • AOF文件比RDB更新频率高,优先使用AOF还原数据。

      • AOF比RDB更安全也更大

      • RDB性能比AOF好

      • 如果两个都配了优先加载AOF

主从复制-哨兵机制

  • Redis 支持简单且易用的主从复制(master-slave replication)功能, 这一功能可以让从服务器(slave server)成为主服务器(master server)的精确复制品,实现了数据的备份。一个主服务器可以有多个从服务器,而且不仅主服务器可以有从服务器, 从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个图状结构。

  • 主服务器如果发生故障,最好让服务器自动完成主从转换,并修改其他从服务器的从属。这就涉及到redis的哨兵(sentinel)了。

  • 哨兵任务:

    • Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: 1)监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。   2)提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。   3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

一致性哈希原理

  • 使用Hash的Redis集群进行遍历服务器时,不需要对所有的服务器进行遍历而提升了性能,使用Hash算法缓存时出现了一些问题,Redis服务器变动时,所有缓存的位置都会发生改变,为了解决这一办法,采用一致行哈算法,一致性的Hash算法是对2的32方取模使用该算法定位到相应的服务器;

  • 如有容错性和扩展性;

缓存穿透

  • 缓存穿透

    缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

    在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

    如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

    • 解决方案

    1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;

    2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

    3. 布隆过滤器。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小。

缓存击穿

  • 缓存击穿

    缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

    • 解决方案

    1、设置热点数据永远不过期。

    2、接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。

    3、加互斥锁

缓存雪崩

  • 缓存雪崩

    缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

    有哪些解决办法?

    (中华石杉老师在他的视频中提到过,视频地址在最后一个问题中有提到):

    • 事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。

    • 事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉

    • 事后:利用 redis 持久化机制保存的数据尽快恢复缓存

布隆过滤器

  • 布隆过滤器

    我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。理论情况下添加到集合中的元素越多,误报的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。

    布隆过滤器的原理介绍

    当一个元素加入布隆过滤器中的时候,会进行如下操作:

    1. 使用布隆过滤器中的哈希函数对元素值进行计算,得到哈希值(有几个哈希函数得到几个哈希值)。

    2. 根据得到的哈希值,在位数组中把对应下标的值置为 1。

    当我们需要判断一个元素是否存在于布隆过滤器的时候,会进行如下操作:

    1. 对给定元素再次进行相同的哈希计算;

    2. 得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。

    当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后将对应的位数组的下标设置为 1(当位数组初始化时,所有位置均为0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。

    如果我们需要判断某个字符串是否在布隆过滤器中时,只需要对给定字符串再次进行相同的哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。

    不同的字符串可能哈希出来的位置相同,这种情况我们可以适当增加位数组大小或者调整我们的哈希函数。

    综上,我们可以得出:布隆过滤器说某个元素存在,小概率会误判。布隆过滤器说某个元素不在,那么这个元素一定不在。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值