Redis面试常问知识点总结

Redis面试常问知识点总结

根据学习搜集的信息,结合网络内容进行的总结。

Redis面试常问知识点总结

思维导图文档地址

错误和不足还请大佬指正 ヽ(=・ω・=)丿

文章目录

  • **Redis面试常问知识点总结**
    • 一、Redis缓存
      • 1、什么是缓存穿透?
        • 解决方案
          • 空值缓存
          • 布隆过滤器
            • 优点
            • 缺点
            • 应用场景
      • 2、什么是缓存击穿?
        • 解决方案
          • 互斥锁
          • 逻辑过期
      • 3、什么是缓存雪崩?
        • 解决方案
          • 分散失效时间
          • 利用Redis集群提高服务可用性
          • 多级缓存
    • 二、双写一致性
      • 什么是双写一致性?
        • 实现方案
          • 延时双删
          • 读写锁
          • cannal组件
    • 三、数据持久化
      • 1、什么是RDB?
        • 优点
        • 缺点
      • 2、什么是AOF?
        • 优点
        • 缺点
      • 3、总结
    • 四、过期策略
      • 1、惰性删除
      • 2、定时清理
        • SLOW模式
        • FAST模式
      • 3、Redis的使用方式
    • 五、淘汰策略
      • 1、可选策略
        • noeviction
        • allkeys-lru
        • volatile-lru
        • allkeys-random
        • volatile-random
        • volatile-ttl
        • allkeys-lfu(Redis 4.0+)
        • volatile-lfu(Redis 4.0+)
      • 2、使用方式
    • 六、Redis集群
      • 1、主从同步
        • 概述
        • 工作流程
          • 配置服务器
          • 建立连接
          • 数据同步
            • (1)全量同步
            • (2)增量同步
            • (3)offset
          • 4、命令传播
        • 工作特点
          • 读写分离
          • 数据冗余
          • 故障转移
          • 非阻塞
        • 存在问题
          • 写操作限制
          • 复制延迟
          • 单点故障
        • 性能优化
      • 2、哨兵模式
        • 概述
        • 工作原理
          • 哨兵集群
          • 主观下线和客观下线
          • leader选举
            • 成为leader的条件
            • 投票原则
          • 故障转移:
          • 客户端重定向:
        • 工作特点
          • 监控
          • 通知
          • 自动故障转移
        • 存在问题
          • 网络分区
          • 配置复杂性
          • 故障转移时间
          • 客户端兼容性
        • 性能优化
      • 3、分片集群
        • 概述
        • 工作原理
          • 哈希散列插槽(Hash Slots)
          • 数据分布
          • 主从复制
          • 故障检测和恢复
          • 重新分片
        • 工作特点
          • 自动分片
          • 高可用性
          • 在线重新分片:
          • 客户端重定向
    • 七、场景模拟
      • 问题一:数据库有1000万条数据,Redis只能缓存20万条数据,怎么保证Redis中缓存的数据都是热点数据?
      • 问题二:Redis的内存用完了会发生什么?
      • 问题三:Redis分布式锁如何实现?
      • 问题四:如何控制Redis实现分布式锁的有效时长
      • 问题五:redisson实现的分布式锁是可重入的吗?
      • 问题六:edisson实现的分布式锁能解决主从一致性的问题吗?
      • 问题七:怎么保证Redis的高并发高可用?
      • 问题八:你们使用Redis是单点还是集群?那种集群?
      • 问题九:怎么解决Redis集群脑裂的问题?
      • 问题十:Redis的分片集群有什么作用?
      • 问题十一:Redis的分片集群中数据是怎样存储和读取的?
      • 问题十二:Redis是单线程的,但是为什么还那么快?
      • 问题十三:解释一下I/O多路复用模型
    • 八、Zookeeper
      • 工作原理
        • 数据模型
        • 会话(Session)
        • 监视(Watches)
        • 一致性保证
      • 解决主从一致性的原理
        • Leader选举
        • 原子广播(Atomic Broadcast)
        • 顺序一致性
        • 临时节点和监视
    • 九、Xmind思维导图

一、Redis缓存

1、什么是缓存穿透?

​ 缓存穿透指的是查询一个缓存和数据库内都不存在的数据,无法将查询数据存入缓存,所以每次查询都需要访问数据库,数据库在高并发的情况下可能会导致数据库宕机,这种情况大概率是遭到了攻击

解决方案
空值缓存

​ 对于查询结果为空的情况,也可以将其缓存起来,设置一个较短的过期时间,这样即使数据不存在,也不会频繁地查询数据库,但是过多的空值数据会占用大量空间。

布隆过滤器

​ 布隆过滤器是用来检测元素是否在集合中,可以使用redisson实现布隆过滤器。布隆过滤器底层先初始化一个bit数组,所有位初始值都为0,当接收到key时对key进行多次(一般为三次)hash计算,获取三个数据下标将对应位数值改为1,这样多个位置就能标明一个key的存在,查找过程同理。

优点

​ 1、空间效率高,相比于其他数据结构,占用的空间非常小

​ 2、查询操作的时间复杂度为O(k),k为hash次数

缺点

​ 存在误判率,可能会错误地报告一个元素存在集合中

​ 解决方法1:增加数组长度,会占用大量空间

​ 解决方法2:设置误判率,不超过5%,不支持删除操作

应用场景

​ 1、网络爬虫:判断一个 URL 是否已经被爬取过。

​ 2、数据库系统:快速判断一个键是否存在于数据库中。

​ 3、缓存穿透:防止不存在的键频繁访问数据库。

​ 4、垃圾邮件过滤:快速判断一个邮件地址是否在黑名单中。

2、什么是缓存击穿?

​ 缓存击穿指的是对于设置了过期时间的key,在这个key过期的恰好有大量的并发请求,这些请求会直接访问数据库,这些高并发的请求可能会瞬间让数据库宕机

解决方案
互斥锁

​ 当缓存失效时,不立即去访问数据库加载数据,先通过Redis的setnx设置互斥锁,然后从数据库加载数据并进行缓存,此间如果有其他线程访问缓存数据发现数据过期时,因为无法获取到锁,所以只能等第一个线程将数据加载并存入缓存后从缓存中获取数据,保证了数据的强一致性,但是会非常影响性能,并且存在死锁的风险

逻辑过期

​ 设置key的时候,同时设置一个过期时间字段,从缓存中取出数据进行查询时先判断是否过期,如果过期则创建一个新的线程进行数据同步,当前线程返回过期数据。高可用,性能好,但是数据做不到强一致性,会返回过期数据

3、什么是缓存雪崩?

​ 缓存雪崩指的是设置缓存时,大量缓存设置了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到数据库,数据库瞬间压力激增导致雪崩。

解决方案
分散失效时间

​ 可以在原有的时间基础上增加一个随机值,这样就可以使缓存过期时间的重复率降低很多

利用Redis集群提高服务可用性

​ 集群模式、哨兵模式

多级缓存

​ Guava、Caffeine

二、双写一致性

什么是双写一致性?

​ 双写一致性指的是在数据库或分布式系统中,为了保证缓存和数据库数据的一致性和完整性,对同一份数据进行两次写入操作,并且这两次写入操作必须保持一致。

实现方案
延时双删

​ 在对数据库进行写操作时,先把缓存中的数据删除,然后更新数据库,最后再延时删除缓存中的数据

存在问题:延时时间难以确定,在延时过程中可能会出现脏数据,并且不能保证强一致性

读写锁

​ 通过redisson实现读写锁,在读的时候添加共享锁,多线程进行读的操作时不互斥,读写互斥。在写的时候添加排它锁,多线程读和写都互斥,保证写数据时不会让其他线程读到数据,避免了脏数据。读方法和写方法需要使用同一把锁,底层使用了setnx

cannal组件

​ 通过部署阿里的cannal服务实现数据同步,cannal会伪装为数据的从库,从数据库实时的获取binlog二进制日志,解析提取数据库的增删改查操作获取数据变更信息,然后从cannal客户端获取数据更新缓存,支持高可用和水平拓展,如果网络延迟过高,导致cannal同步数据库操作缓慢可能会导致脏数据

三、数据持久化

1、什么是RDB?

​ RDB是一种快照持久化方式,它会在指定的时间间隔内将内存中的数据集快照写入磁盘

优点

​ 1、高效:RDB是一个非常紧凑的单文件,适合备份和灾难恢复。

​ 2、性能:生成RDB文件时,Redis主进程会fork一个子进程来处理所有持久化工作,这样主进程就不需要进行任何磁盘I/O操作。

​ 3、恢复速度快:因为RDB文件是数据的完整快照,所以恢复数据时速度较快。

缺点

​ 1、数据丢失风险:如果在最近一次快照后发生故障,那么这段时间内的数据将会丢失。

​ 2、Fork操作:对于大规模数据集,fork操作可能会比较耗时,导致Redis在一段时间内无法响应客户端请求。

2、什么是AOF?

​ AOF是一种日志持久化方式,它记录了服务器接收到的每一个写操作,这些操作会在服务器启动时重新执行,以重建原始数据集。

优点

​ 1、数据安全性高:AOF提供了更好的数据持久性保证,可以配置不同的fsync策略(如每次写入、每秒fsync等)。

​ 2、可读性:AOF文件是一个只进行追加操作的日志文件,即使日志写入中途失败,也很容易修复。

​ 3、灵活性:可以在不重启Redis的情况下,通过redis-check-aof工具修复AOF文件。

缺点

​ 1、文件体积大:AOF文件通常比RDB文件大。

​ 2、性能:对于相同的数据集,AOF文件的写入操作通常比RDB文件的写入操作慢。

​ 3、恢复速度慢:因为AOF需要重放所有写命令,所以恢复数据时速度较慢。

3、总结

​ RDB是二进制文件,在保存时候体积比较小,恢复速度比较快,但是可能会出现丢数据的情况。AOF恢复的速度慢一些,但是丢数据的风险小很多,在AOF文件中可以设置刷盘策略,间隔多久批量写入一次命令

四、过期策略

1、惰性删除

​ 在设置的key过了过期时间后,不直接删除,当需要该key时检查是否过期,如果过期则删除,未过期则返回

2、定时清理

​ 每隔一段时间,对一些key进行检查,删除过期的key,一定时间内完全检查一遍

SLOW模式

​ 执行默认频率为10hz,每次不超过25ms,可以通过修改配置文件redis.conf的hz选项来调整频率

FAST模式

​ 执行频率不固定,每次事件循环会尝试执行,但两次间隔不低于2ms,每次耗时不超过1ms

3、Redis的使用方式

​ 惰性删除+定时清理

五、淘汰策略

1、可选策略

noeviction

​ 当内存不足以容纳新写入数据时,新写入操作会报错。

​ 适用场景:适用于不允许数据丢失的场景。

allkeys-lru

​ 在所有键中使用LRU(Least Recently Used,最近最少使用)算法淘汰键。

​ 适用场景:适用于大多数键都有访问模式,且希望保留最近访问的键的场景。

volatile-lru

​ 在设置了过期时间的键中使用LRU算法淘汰键。

​ 适用场景:在设置了过期时间的键中使用LRU算法淘汰键。

allkeys-random

​ 在所有键中随机淘汰键。

​ 适用场景:适用于键的访问模式没有明显规律的场景。

volatile-random

​ 在设置了过期时间的键中随机淘汰键。

​ 适用场景:适用于部分键设置了过期时间,且希望随机淘汰键的场景。

volatile-ttl

​ 优先淘汰即将过期的键(TTL较小的键)。

​ 适用场景:适用于希望尽快释放即将过期键的内存的场景。

allkeys-lfu(Redis 4.0+)

​ 在所有键中使用LFU(Least Frequently Used,最不经常使用)算法淘汰键。

​ 适用场景:适用于键的访问频率有明显差异,且希望保留访问频率高的键的场景。

volatile-lfu(Redis 4.0+)

​ 在设置了过期时间的键中使用LFU算法淘汰键。

​ 适用场景:适用于部分键设置了过期时间,且希望保留访问频率高的键的场景。

2、使用方式

​ Redis默认策略为noeviction,不删除任何数据,内存不足时报错,可以在Redis的配置文件中进行设置。常用的两个概念为LRU和LFU,LRU是最少最近使用,即当前时间和最后一次访问时间的差值,值越大则淘汰的优先级越高,LFU是最少频率使用,统计每个key的访问频率,值越小则淘汰优先级越高

六、Redis集群

1、主从同步

概述

​ Redis的主从同步是一种数据复制机制,它允许将Redis主服务器Master的数据复制到一个或多个Redis从服务器Slave,用于提高数据的可靠性和读取性能。

工作流程
配置服务器

​ 在从服务器的配置文件中指定主服务器的地址和端口,或者在运行时使用SLAVEOF命令动态设置。

建立连接

​ 从服务器会尝试与主服务器建立网络连接

数据同步

​ 从服务器向主服务器发送一个同步请求,主服务器会生成一个RDB文件,并将这个文件发送给从服务器,从服务器接收到RDB文件进行加载,从而获得与主服务器一致的数据集。

(1)全量同步

​ 第一阶段:从服务器replicaof命令建立连接时会发送自身replid和offset到主服务器, 主服务器会检测是否和自身一致,不一致则会返回主服务器的replid和offset,从服务器继承主服务器的replid和offset,并保存版本信息。

​ 第二阶段:主服务器执行bgsave,生成RDB文件,记录RDB期间所有命令到repl_baklog,发送RDB文件到从服务器,从服务器清空本地数据,加载RDB文件

​ 第三阶段:如果在RDB生成执行期间有请求到了主节点,主节点会以命令的方式记录到repl_baklog缓冲区日志文件中,最后把这个日志文件发送给从节点,这样就能保证主节点与从节点完全一致

(2)增量同步

​ 第一阶段:当从节点服务重启之后,从节点数据和主节点数据就不同步了,这时只需要进行增量同步,增量同步只更新slave与master存在差异的部分数据,建立连接时,主服务器检测到replid一致,则会回复continue

​ 第二阶段:主服务根据从服务器的offset,从repl_baklog中获取offset后的数据命令,发送到从服务区,从服务器执行命令进行数据同步

(3)offset

​ 数据偏移量,随着记录在repl_baklog中的数据增多而逐渐增大,从服务器完成同步时会记录当前同步的offset,用于后续进行数据同步,从服务器offset小于主服务offset说明从服务器的数据落后,需要更新。

4、命令传播

​ 在初始同步后,主服务器会将后续命令发送到从服务器,从服务器执行这些命令以保持与主服务器的一致性

工作特点
读写分离

​ 主服务器负责处理写操作,从服务器负责读操作,这样可以分散读请求,提升系统读的效率

数据冗余

​ 通过复制,数据在多个从服务器上都有备份,提高了数据的可靠性

故障转移

​ 如果主服务器发生故障,可以将从服务器提升为新的主服务器

非阻塞

​ 主服务器在处理复制操作时,不会阻塞处理客户端的请求

存在问题
写操作限制

​ 所有的写操作都必须在主服务器上执行,从服务器只能进行读操作

复制延迟

​ 由于网络和命令传播的延迟,从服务器的数据可能会有一定的滞后

单点故障

​ 主服务器仍然是单点故障的潜在风险,如果主服务器宕机,需要手动进行故障转移。

性能优化

​ 1、在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO。

​ 2、Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO

​ 3、适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步

​ 4、限制一个master上的slave节点数量,slave过多时可才用主-从-从链式结构,减少master压力

2、哨兵模式

概述

​ Redis哨兵模式(Redis Sentinel)是Redis官方提供的一种高可用性解决方案。它主要用于监控Redis主从复制架构中的主节点,并在主节点发生故障时自动进行故障转移,选举新的主节点。

工作原理
哨兵集群

​ 通常会有多个Sentinel实例组成一个哨兵集群,以提高系统的容错能力。

主观下线和客观下线

​ 当一个Sentinel实例检测到某个Redis节点不可用时,会将其标记为“主观下线”,当有超过quorum(一般设置为节点数量的一半)实例都认为该节点不可到达,则会将其标记为“客观下线”

leader选举

​ 当主节点被客观下线后,第一个确认master客观下线的从节点会立刻发起投票,根据投票原则此从节点会成为leader

成为leader的条件

​ (1)最先获得超过半数的投票

​ (2)获得的投票数不小于quorum值(一般会设置为节点数量的一半)

投票原则

​ (1)优先投票给目前得票最多的

​ (2)如果目前没有任何节点的票,就投给自己

故障转移:

​ 当master客观下线后,Sentinal给选举出的节点发送slaveof no one命令,让该节点成为master,并给其他节点发送slaveof命令让其他节点称为新master的从节点,开始从新的master上同步数据,故障的master恢复后也会收到Sentinel信号执行slaveof命令称为从节点

客户端重定向:

Sentinel会通知客户端新的主节点地址,客户端需要根据新的配置重新连接到新的主节点。

工作特点
监控

​ Sentinel持续监控Redis实例的健康状态,包括主节点和从节点。

通知

​ 当监控的Redis实例出现问题时,Sentinel可以通过API通知系统管理员或其他应用程序。

自动故障转移

​ 当主节点不可用时,Sentinel会自动将一个从节点提升为新的主节点,并通知其他从节点和客户端更新配置。

存在问题
网络分区

​ 在网络分区的情况下,Sentinel可能会错误地进行故障转移,导致脑裂(split-brain)问题。

配置复杂性

​ Sentinel的配置和管理可能比较复杂,尤其是在大规模部署时。

故障转移时间

​ 故障转移需要一定时间,期间Redis可能处于不可用状态

客户端兼容性

​ 客户端需要支持Sentinel模式,否则无法正确处理故障转移。

性能优化

​ (1)部署更多的Sentinel实例可以提高系统的容错能力,减少单点故障的风险。

​ (2)设置合理的仲裁数(quorum)可以减少网络分区导致的错误故障转移。

​ (3)使用自动化管理工具来简化Sentinel的配置和管理,例如使用Ansible、Puppet等。

​ (4)通过优化Sentinel的配置参数,如减少down-after-milliseconds和failover-timeout的值,可以加快故障转移的速度。

3、分片集群

概述

​ Redis分片集群(Redis Cluster)是Redis官方提供的分布式解决方案,用于在多个Redis节点之间自动分割数据集,适用于需要处理大量数据和高吞吐量的场景。

工作原理
哈希散列插槽(Hash Slots)

​ Redis Cluster将整个数据集划分为16384个哈希槽,每个节点负责一部分哈希槽

数据分布

​ 当数据被写入集群时,Redis根据键的哈希值决定它属于哪个哈希槽,并将数据存储在负责该哈希槽的节点上。

主从复制

​ 每个哈希槽可以有一个主节点和多个从节点,从节点复制主节点的数据,以提供冗余和故障转移的能力。

故障检测和恢复

​ 集群中的节点汇相互监控,当主节点不可用时,集群会从其从节点中选举一个新的主节点。

重新分片

​ 当集群需要扩展或缩小时,可以通过工具(如Redis-trib.rb或Rdis-cli)在线重新分配哈希槽

工作特点
自动分片

​ Redis Cluster将数据自动分布在多个节点上,每个节点负责一部分数据。

高可用性

​ 集群中的每个节点都可以配置主从复制,以提供故障转移能力。

在线重新分片:

​ 可以在不停止服务的情况下,动态调整集群的分片配置。

客户端重定向

​ 客户端可以连接到任意节点,如果请求的数据不在该节点上,节点会返回重定向信息,指导客户端连接到正确的节点。

七、场景模拟

问题一:数据库有1000万条数据,Redis只能缓存20万条数据,怎么保证Redis中缓存的数据都是热点数据?

答:

​ 可以使用allkeys-lru淘汰策略,留下来的都是经常访问的热点数据

问题二:Redis的内存用完了会发生什么?

答:

​ 根据Redis的淘汰策略如何设置,如果是默认设置则用完了会直接报错,常用的allkeys-lru策略,把最常访问的数据留在缓存中

问题三:Redis分布式锁如何实现?

答:

​ 使用redisson实现的分布式锁,底层是Redis中提供了一个命令setnx(set if not exists)和lua脚本(保证原子性),由于redis单线程的,使用了命令之后只能有一个客户端对一个key设置值,在没有过期或删除key的时候其他客户端不能设置这个key的值

问题四:如何控制Redis实现分布式锁的有效时长

答:

​ Redis的setnx指令不便于控制这个问题,我们采用的是redis的一个框架,redisson实现的,在redisson总进行手动加锁并可以控制锁的失效时间和等待时间,当锁住的业务还没有执行完成时,redisson中的看门狗机制会每隔一段检查当前业务是否还持有锁,如果持有则延长锁的持有时间,当业务完成后释放锁。

​ 还有一个好处,在高并发下,一个业务有可能会执行的很快,客户1持有锁的时候,客户2来了以后并不会马上拒绝,会不断地尝试获取锁,如果客户1释放了锁,客户2就可以马上持有锁,性能会有一定提升

问题五:redisson实现的分布式锁是可重入的吗?

答:

​ 是可以重入的,可重入锁允许同一个线程多次获取同一个锁而不会导致死锁,这是通过在锁的实现中维护一个计数器和一个线程标识来实现的。当一个线程尝试获取锁时,Redisson会检查Redis中是否已经存在该线程的锁记录,如果锁记录不存在,线程会尝试获取锁,并在Redis中创建一个新的锁记录,初始化线程标识和锁计数器。如果锁记录存在且线程标识与当前线程匹配,说明当前线程已经持有该锁,此时只需要增加锁计数器即可,不需要再次获取锁。

​ 当线程释放锁时,Redisson会减少锁计数器,如果锁计数器减少到零,说明当前线程不再持有该锁,此时可以删除Redis中的锁记录。如果锁计数器大于零,说明当前线程仍然持有该锁,此时只需要减少锁计数器,不需要删除锁记录。

问题六:edisson实现的分布式锁能解决主从一致性的问题吗?

答:

​ Redisson实现的分布式锁本身并不能直接解决Redis主从复制中的数据一致性问题,因为Redis的主从复制是异步的,存在一定的延迟。这意味着在主节点上获取的锁可能在复制到从节点之前就已经过期或被释放,从而可能导致锁的不一致性。

​ 比如,线程1加锁成功后,master节点数据会异步复制到slave节点,此时如果master节点宕机,slave节点汇被提升为新的master节点,线程2接入并再次加锁,会在新的master节点上加锁成功,这时候就会出现两个节点同时持有一把锁的问题

解决方法:

​ RedLock算法,Redisson支持RedLock算法,这是一种多节点分布式锁算法,通过在多个独立的Redis实例上获取锁来提高锁的可靠性。RedLock算法要求在大多数(超过一半)的Redis实例上成功获取锁才算成功,这样即使某个Redis实例出现故障,也不会影响锁的正确性。

存在问题:

​ 实现复杂,高并发情况下,因为需要同时在多个节点上都添加锁,所以性能很差,运行维护非常繁琐,不建议使用,如果业务要求强一致性可以使用zookeeper

问题七:怎么保证Redis的高并发高可用?

答:

​ 可以搭建主从集群,再加上使用Redis中的哨兵模式,哨兵模式可以实现主从集群的自动故障恢复,包括对主从服务的监控、自动故障恢复、通知等。如果master故障,Sentinel胡即将一个slave提升为master。当故障实例恢复后将成为slave。同时Sentinel也会充当Redis客户端的服务发现来源,当集群发现故障转移时,会将最新消息推送给Redis的客户端,所以一般项目都会采用哨兵模式来保证Redis的高并发高可用

问题八:你们使用Redis是单点还是集群?那种集群?

答:

​ 我们使用的是主从加哨兵,一般单节点不超过10G内存,如果Redis内存不足则可以给不同服务分配独立的Redis主从节点。尽量不做分片集群,因为分片集群维护起来比较麻烦,而且集群之间的心跳检测和数据通信会消耗大量的网络宽带,也没有办法用lua脚本和事务

问题九:怎么解决Redis集群脑裂的问题?

答:

​ Redis集群脑裂在项目中比较少见,出现脑裂的原因是我们现在使用Sentinel哨兵模式集群的时候,由于网络等原因Redis的master节点和Sentinel处于不同的网络分区,Setninel检测不到master的心跳感知就会让master下线选举新的master节点。这就导致存在两个master节点,客户端在旧的master节点写入数据,当网络恢复旧的master节点会降为slave节点,旧的master节点的数据和这部分写入数据就丢失了

解决的方法,在Redis配置中进行设置

​ 1、设置最少的salve节点个数,比如设置至少存在一个从节点才可以同步数据

​ 2、设置主从数据复制和同步的演示,达不到要求就拒绝请求,可以避免大量的数据丢失

问题十:Redis的分片集群有什么作用?

答:

​ 分片集群主要是解决海量数据存储的问题,集群中有多个master节点,每个master保存不同的数据,并可每个master节点可以有多个slave节点,这样就可以增加集群的高并发能力。客户端请求可以访问集群的任意master节点,最终都会被转发到请求数据所在的节点。

问题十一:Redis的分片集群中数据是怎样存储和读取的?

答:

​ Redis集群引入了哈希槽的概念,有16384个哈希槽,集群中每个主节点绑定了一定范围的哈希槽,key通过CRC16校验后对16384取余数决定放置在哪个槽,通过槽找到对应的节点进行存储,取值时逻辑是一样的

问题十二:Redis是单线程的,但是为什么还那么快?

答:

​ Redis读写速度快的原因有这么几个:

​ 1、Redis是完全基于内存的,内存的读写速度是非常快的

​ 2、Redis是单线程,避免了线程之间切换,以及加锁和解锁的损耗

​ 3、Redis采用多路I/O复用模型,是一种非阻塞IO

​ bgsave和bgrewriteaof都是在后台执行操作,不影响主线程的正常使用,不会产生阻塞

问题十三:解释一下I/O多路复用模型

答:

​ I/O多路复用模型,Redis通过使用单线程同时监听多个Socket实现,多个Socket中只要有某个Socker可读可读时就会得到通知,从而避免了无效的等待,充分利用cpu资源。目前的I/O多路复用都是采用的epoll模式,他会在通知用户进程Socker就绪的同时,把已就绪的Socket写入用户空间,不需要挨个遍历Socket来判断时哪个就绪了,提升了性能。

​ 附:因为Redis是基于内存进行读写,速度非常快,所以Redis处理请求的瓶颈在于网络延迟,所以Redis的网络模型使用了I/O多路复用结合事件处理器来应对多个Socket请求,比如停了链接答应处理器、命令回复处理器、命令请求处理器

​ 附:Redis6.0之后,为了更好地提升性能,在命令回复处理器使用了多线程来处理回复时间。命令请求处理器中,命令的转换也使用了多线程,增加命令转换速度,但在命令执行的时候依然是单线程串行执行

八、Zookeeper

​ ZooKeeper是一个分布式协调服务,ZooKeeper的核心功能包括配置管理、命名服务、分布式锁和组成员管理等。

工作原理

数据模型

​ ZooKeeper的数据模型类似于一个文件系统,由一系列的ZNode(ZooKeeper节点)组成,这些节点以树状结构组织。

​ 每个ZNode可以存储数据,并且可以有子节点。

​ ZNode有两种类型:

​ 持久节点(Persistent):持久节点在创建后一直存在,直到被显式删除;

​ 临时节点(Ephemeral):临时节点在创建它的会话结束时自动删除。

会话(Session)

​ 客户端与ZooKeeper服务器建立一个会话,通过这个会话进行所有的交互操作。

​ 会话有一个超时时间,如果客户端在超时时间内没有与服务器进行通信,会话将被视为无效。

监视(Watches)

​ 客户端可以在ZNode上设置监视点,当ZNode的数据或子节点发生变化时,ZooKeeper会通知设置了监视点的客户端。

​ 监视是一次性的触发器,触发后需要重新设置。

一致性保证

​ ZooKeeper使用ZAB(ZooKeeper Atomic Broadcast)协议来保证分布式环境下的事务处理顺序一致性。

​ ZAB协议确保所有的事务请求按照它们被接收的顺序进行处理,并且所有服务器都以相同的顺序应用这些事务。

解决主从一致性的原理

Leader选举

​ ZooKeeper集群中的服务器通过选举机制选出一个Leader,其他服务器成为Follower。

​ Leader负责处理所有的事务请求,并将事务广播给所有的Follower。

原子广播(Atomic Broadcast)

​ Leader将事务请求以原子广播的方式发送给所有Follower。

​ Follower接收到事务请求后,将其应用到本地状态机,并返回确认给Leader。

顺序一致性

​ ZooKeeper保证所有的事务按照它们被接收的顺序应用到所有服务器上。

​ 这意味着所有服务器上的数据视图是一致的,从而保证了主从一致性。

临时节点和监视

​ 在主从复制场景中,可以使用临时节点来表示主节点(Master)。

​ 如果主节点崩溃,其对应的临时节点会自动删除,其他从节点(Slave)可以通过监视这个节点的变化来感知主节点的状态变化,并尝试成为新的主节点。

九、Xmind思维导图

版权声明:如无特殊标注,文章均来自网络,本站编辑整理,转载时请以链接形式注明文章出处,请自行分辨。

本文链接:https://www.shbk5.com/dnsj/74460.html