大厂系列:Redis八股文,速速收藏(四)

32.如何为分布式锁设置合理的超时时间?

可以基于续约的方式设置超时时间:先给锁设置一个超时时间,然后启动一个守护线程,让守护线程在一段时间后,重新设置这个锁的超时时间。实现方式就是:写一个守护线程,然后去判断锁的情况,当锁快失效的时候,再次进行续约加锁,当主线程执行完成后,销毁续约锁即可,不过这种方式实现起来相对复杂。

33.Redis解决集群情况下分布式锁的可靠性?

分布式锁算法 Redlock(红锁)。基于多个 Redis 节点的分布式锁,即使有节点发生了故障,锁变量仍然是存在的,客户端还是可以完成锁操作。官方推荐是至少部署 5 个 Redis 节点,而且都是主节点,它们之间没有任何关系,都是一个个孤立的节点。

基本思路:是让客户端和多个独立的 Redis 节点依次请求申请加锁,如果客户端能够和半数以上的节点成功地完成加锁操作,那么就认为,客户端成功地获得分布式锁,否则加锁失败。即使有某个 Redis 节点发生故障,锁的数据在其他节点上也有保存,客户端仍然可以正常地进行锁操作,锁的数据也不会丢失。

Redlock 算法加锁三个过程:

  • 第一步是,客户端获取当前时间(t1)。
  • 第二步是,客户端按顺序依次向 N 个 Redis 节点执行加锁操作:加锁操作使用 SET NX,EX/PX 选项,以及带上客户端的唯一标识。如果某个 Redis 节点发生故障了,为了保证在这种情况下,Redlock 算法能够继续运行,需要给「加锁操作」设置一个超时时间,加锁操作的超时时间需要远远地小于锁的过期时间。
  • 第三步是,一旦客户端从超过半数(大于等于 N/2+1)的 Redis 节点上成功获取到了锁,就再次获取当前时间(t2),然后计算计算整个加锁过程的总耗时(t2-t1)。如果 t2-t1 < 锁的过期时间,此时,认为客户端加锁成功,否则认为加锁失败。

加锁成功要同时满足两个条件:有超过半数的 Redis 节点成功的获取到了锁,并且总耗时没有超过锁的有效时间,那么就是加锁成功。

加锁成功后,客户端需要重新计算这把锁的有效时间,计算的结果是「锁最初设置的过期时间」减去「客户端从大多数节点获取锁的总耗时(t2-t1)」。如果计算的结果已经来不及完成共享数据的操作了,可以释放锁,以免出现还没完成数据操作,锁就过期了的情况。加锁失败后,客户端向所有 Redis 节点发起释放锁的操作,执行释放锁的 Lua 脚本就可以。

34.Redis管道有什么用?

管道技术是客户端提供的一种批处理技术,用于一次处理多个 Redis 命令,从而提高整个交互的性能。使用管道技术可以解决多个命令执行时的网络等待,它是把多个命令整合到一起发送给服务器端处理之后统一返回给客户端,这样就免去了每条命令执行后都要等待的情况,从而有效地提高了程序的执行效率。

但使用管道技术也要注意避免发送的命令过大,或管道内的数据太多而导致的网络阻塞。管道技术本质上是客户端提供的功能,而非 Redis 服务器端的功能。

35.Redis如何处理大key?

定义:String 类型的值大于 10 KB;Hash、List、Set、ZSet 类型的元素的个数超过5000个;

影响:

  • 客户端超时阻塞:由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时。客户端认为很久没有响应。
  • 引发网络阻塞:每次获取大 key 产生的网络流量较大。
  • 阻塞工作线程:如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
  • 内存分布不均:集群模型在 slot 分片均匀情况下,会出现数据和查询倾斜情况,部分有大 key 的 Redis 节点占用内存多,QPS 也会比较大。

处理:

  • 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
  • 当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的key,使用multiget等操作实现事务读取。
  • 分拆成几个key-value,存储在一个hash中,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性
  • 当value是list/set等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

36.Redis支持事务回滚吗?

不支持,Redis 提供的 DISCARD 命令只能用来主动放弃事务执行,把暂存的命令队列清空,起不到回滚的效果。因为Redis 事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以官方认为没有必要为 Redis 开发事务回滚功能。

37.Redis集群模式有哪些?

主从:选择一台作为主服务器,将数据到多台从服务器上,构建一主多从的模式,主从之间读写分离。主服务器可读可写,发生写操作会同步给从服务器,而从服务器一般是只读,并接受主服务器同步过来写操作命令。主从服务器之间的命令复制是异步进行的,所以无法实现强一致性保证(主从数据时时刻刻保持一致)。

哨兵:当 Redis 的主从服务器出现故障宕机时,需要手动进行恢复,为了解决这个问题,Redis 增加了哨兵模式,哨兵监控主从服务器,并且提供主从节点故障转移的功能。

切片集群:当数据量大到一台服务器无法承载,需要使用Redis切片集群(Redis Cluster)方案,它将数据分布在不同的服务器上,以此来降低系统对单主节点的依赖,提高 Redis 服务的读写性能。

38.Redis切片集群的工作原理?

切片集群会采用哈希槽来进行数据和节点的映射,一个切片集群一共有16384个槽位,每个存储数据的key会经过运算映射到16384个槽位中,映射关系如下:

  • 由key通过CRC16算法计算出一个16bit的数字
  • 根据上面计算得到的数字对16384取模来确定对应的哈希槽

39.哈希槽和Redis节点是如何对应的?

主要有平均分配和手动分配两种方式。平均分配是集群创建时,Redis自动将哈希槽平均分配到集群节点上;手动分配是使用命令指定每个节点上面的哈希槽数目,使用手动分配时要把16384个槽位给分完,否则集群不会正常工作。

40.主从模式的同步过程?

第一次同步

主要分为建立连接协商、主从数据同步、发送新操作三个步骤:

  • 连接协商:从服务器先发送命令给主服务器表示要进行数据同步,命令内容包括主服务器的runID和复制进度两个参数,主服务器收到命令之后会给从服务响应命令,响应包括主服务器的runID和复制进度。从服务器收到响应之后会记录这两个值。
  • 主从数据同步:主服务器生成RDB文件并发送给从服务器,从服务器收到RDB之后先清空自己的数据,再载入RDB文件。为了主从数据的一致性,这个期间主服务器后续的写操作会记录到replication buffer缓冲区里
  • 发送新操作:主服务器发送replication buffer里面的写操作给从服务器,从服务器执行这些操作。第一次同步完成。

命令传播

第一次同步完成之后双方会维护一个TCP连接,后续主服务器的写命令通过TCP连接发送给从服务器,保证主从一致。

压力分摊

为了分摊服务器的压力,生成和传输RDB的工作可以分摊到经理从服务器上。

增量复制

如果服务器网路断开,在恢复之后,会把网络断开期间主服务器接收到的写操作命令同步给从服务器。#牛客AI配图神器#

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-20 10:05
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务