八股文---Redis(2)

目录

2.Redis分布式锁

redisson实现的分布式锁-可重入

redisson实现的分布式锁-主从一致性

2.1.redis分布式锁,是如何实现的?

回答

2.2.Redisson实现分布式锁如何合理的控制锁的有效时长?

回答

2.3.Redisson的这个锁,可以重入吗?

回答

2.4.Redisson锁能解决主从数据一致的问题吗

回答

3.Redis其他面试问题

Redis集群有哪些方案, 知道嘛

3.1.主从复制

主从数据同步原理

主从全量同步:

主从增量同步(slave重启或后期数据变化)

3.1.1.介绍一下redis的主从同步

回答:

3.1.2.能说一下,主从同步数据的流程

回答

3.2.哨兵模式

服务状态监控

redis集群(哨兵模式)脑裂

解决方法:

3.2.1.怎么保证Redis的高并发高可用

回答:

3.2.2.你们使用redis是单点还是集群,哪种集群

回答

3.2.3.redis集群脑裂,该怎么解决呢?

回答

3.3分片集群结构

怎么路由到正确的节点(数据读写)

3.3.1redis的分片集群有什么作用

回答

3.3.2Redis分片集群中数据是怎么存储和读取的?

回答

Redis是单线程的,但是为什么还那么快

回答

能解释一下I/O多路复用模型?

回答



2.Redis分布式锁

Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在,则 SET)的简写。

获取锁:

# 添加锁,NX是互斥、EX是设置超时时间
SET lock value NX EX 10

释放锁:

# 释放锁,删除即可
DEL key

redisson实现的分布式锁-执行流程

redisson实现的分布式锁-可重入

利用hash结构记录线程id和重入次数

当执行add1的时候,线程第一次获取锁,redis中当前value应该是1,当方法1调用方法2,,value就会加1,方法2释放锁之后value就会减1,最后方法1释放锁之后,就将value为0.

 

redisson实现的分布式锁-主从一致性

RedLock(红锁):不能只在一个redis实例上创建锁,应该是在多个redis实例上创建锁(n / 2 + 1),避免在一个redis实例上加锁。

缺点:实现复杂,性能差,运维繁琐

2.1.redis分布式锁,是如何实现的?

回答

  • 先按照自己简历上的业务进行描述分布式锁使用的场景
  • 我们当使用的redisson实现的分布式锁,底层是setnx和lua脚本(保证原子性

2.2.Redisson实现分布式锁如何合理的控制锁的有效时长?

回答

在redisson的分布式锁中,提供了一个WatchDog(看门狗),一个线程获取锁成功以后, WatchDog会给持有锁的线程续期(默认是每隔10秒续期一次)

2.3.Redisson的这个锁,可以重入吗?

回答

可以重入,多个锁重入需要判断是否是当前线程,在redis中进行存储的时候使用的hash结构,来存储线程信息和重入的次数

2.4.Redisson锁能解决主从数据一致的问题吗

回答

不能解决,但是可以使用redisson提供的红锁来解决,但是这样的话,性能就太低了,如果业务中非要保证数据的强一致性,建议采用zookeeper实现的分布式锁

这个是不能的。比如,当线程1加锁成功后,master节点数据会异步复制到slave节点,此时如果当前持有Redis锁的master节点宕机,slave节点被提升为新的master节点,假如现在来了一个线程2,再次加锁,会在新的master节点上加锁成功,这个时候就会出现两个节点同时持有一把锁的问题。

我们可以利用Redisson提供的红锁来解决这个问题,它的主要作用是,不能只在一个Redis实例上创建锁,应该是在多个Redis实例上创建锁,并且要求在大多数Redis节点上都成功创建锁,红锁中要求是Redis的节点数量要过半。这样就能避免线程1加锁成功后master节点宕机导致线程2成功加锁到新的master节点上的问题了。

但是,如果使用了红锁,因为需要同时在多个节点上都添加锁,性能就变得非常低,并且运维维护成本也非常高,所以,我们一般在项目中也不会直接使用红锁,并且官方也暂时废弃了这个红锁。

3.Redis其他面试问题

Redis集群有哪些方案, 知道嘛

在Redis中提供的集群方案总共有三种

  • 主从复制

  • 哨兵模式

  • 分片集群

3.1.主从复制

单节点的Redis的并发能力是有限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现去写分离


主从数据同步原理
主从全量同步:

Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid

offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

主从增量同步(slave重启或后期数据变化)

3.1.1.介绍一下redis的主从同步
回答:

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 一般都是一主多从,主节点负责写数据,从节点负责读数据

3.1.2.能说一下,主从同步数据的流程
回答

全量同步:

1.从节点请求主节点同步数据(replication id、 offset )

2.主节点判断是否是第一次请求,是第一次就与从节点同步版本信息(replication id和offset)

3.主节点执行bgsave,生成rdb文件后,发送给从节点去执行

4.在rdb生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)

5.把生成之后的命令日志文件发送给从节点进行同步

增量同步:

1.从节点请求主节点同步数据,主节点判断不是第一次请求,不是第一次就获取从节点的offset值 2.主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步

3.2.哨兵模式

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下:

监控:Sentinel 会不断检查您的master和slave是否按预期工作

自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主

通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端

服务状态监控

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线
  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

哨兵选主规则

  1. 首先判断主与从节点断开时间长短,如超过指定值就排该从节点
  2. 然后判断从节点的slave-priority值,越小优先级越高
  3. 如果slave-prority一样,则判断slave节点的offset值,越大优先级越高
  4. 最后是判断slave节点的运行id大小,越小优先级越高。

redis集群(哨兵模式)脑裂

正常的主从架构,配合了哨兵模式

加入因为网络原因,主节点和哨兵在不同的网络分区,哨兵只能检测到从节点,这时候哨兵就会从从节点选取一个为主节点。但是老的主节点只是因为网络分区还没有挂,这时候就有俩主节点(就像大脑分裂一样),目前客户端连接的是原来的主节点,会持续的往老的主节点写入数据。这时候新的主节点不能同步数据到从节点。

加入现在网路恢复了,哨兵会将老的主节点强制降维成从节点,这时候从节点就会从新主节点中同步数据,就会把自己的数据清空。(客户端写的数据就会丢失)

解决方法:

redis中有两个配置参数:

min-replicas-to-write 1   表示最少的salve节点为1个

min-replicas-max-lag 5  表示数据复制和同步的延迟不能超过5秒

3.2.1.怎么保证Redis的高并发高可用
回答:

哨兵模式:实现主从集群的自动故障恢复(监控、自动故障恢复、通知)

3.2.2.你们使用redis是单点还是集群,哪种集群
回答

主从(1主1从)+哨兵就可以了。单节点不超过10G内存,如果Redis内存不足则可以给不同服务分配独立的Redis主从节点

3.2.3.redis集群脑裂,该怎么解决呢?
回答

集群脑裂是由于主节点和从节点和sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到主节点,所以通过选举的方式提升了一个从节点为主,这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在老的主节点那里写入数据,新节点无法同步数据,当网络恢复后,sentinel会将老的主节点降为从节点,这时再从新master同步数据,就会导致数据丢失

解决:我们可以修改redis的配置,可以设置最少的从节点数量以及缩短主从数据同步的延迟时间,达不到要求就拒绝请求,就可以避免大量的数据丢失

3.3分片集群结构

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:

  • 海量数据存储问题
  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征:

  • 集群中有多个master,每个master保存不同数据
  • 每个master都可以有多个slave节点
  • master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

怎么路由到正确的节点(数据读写)

Redis 分片集群引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

3.3.1redis的分片集群有什么作用
回答
  • 集群中有多个master,每个master保存不同数据     ----海量数据存储,高并发写
  • 每个master都可以有多个slave节点                          -----高并发读
  • master之间通过ping监测彼此健康状态                    -----哨兵
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点     

3.3.2Redis分片集群中数据是怎么存储和读取的?
回答
  • Redis 分片集群引入了哈希槽的概念,Redis 集群有 16384 个哈希槽
  • 将16384个插槽分配到不同的实例
  • 读写数据:根据key的有效部分计算哈希值对16384取余(有效部分,如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例

Redis是单线程的,但是为什么还那么快

回答

  • Redis是纯内存操作,执行速度非常快
  • 采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题
  • 使用I/O多路复用模型,非阻塞IO

能解释一下I/O多路复用模型?

回答

Redis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度, I/O多路复用模型主要就是实现了高效的网络请求

1.用户空间和内核空间

2.常见的IO模型

  • 阻塞IO(Blocking IO)
  • 非阻塞IO(Nonblocking IO)
  • IO多路复用(IO Multiplexing)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值