常见面试题-Redis 切片集群以及主节点选举机制

Redis 切片集群了解吗?

答:

Redis 切片集群是目前使用比较多的方案,Redis 切面集群支持多个主从集群进行横向扩容,架构如下:

在这里插入图片描述

使用切片集群有什么好处?

  • 提升 Redis 读写性能,之前的主从模式中,只有 1 个 master 可以进行写操作,在切片集群中,多个 master 承担写操作压力

  • 多个主从集群进行存储数据,比单个主从集群存储数据更多

    比如10G数据,1个主从集群的话,1个master需要存储10G,对有3个主从集群的切片集群来说,只需要master1存储3G,master2存储3G,master3存储4G即可

  • 具备主从复制、故障转移

    切片集群中的每一个主从集群中,slave 节点不支持读,只做数据备份,因为已经有其他master节点分担压力

切片集群支持水平扩容,可以无限扩容吗?

不可以,官方推荐不要超过1000个,因为各个小集群之间需要互相进行通信,如果水平节点过多,会影响通信效率。

切片集群中插入数据时,数据被放在哪个master中?

Redis 切片集群中,数据是通过 哈希槽分区 来存储的,Redis 切片集群中有 16384 个哈希槽,每一个 master 会拿到一些槽位,在向切片集群中插入数据时,会根据 key 计算对应的哈希槽,插入到对应的哈希槽中,那么计算出来的哈希槽在哪个master中,数据当然也就被存放在对应的master上。(在切片集群中,只有master节点才有插槽,slave节点没有插槽)

故障恢复(Failover):切片集群中如果一个master挂了,如何选举主节点?

当 master 挂了之后,该 master 下的所有 slave 会向所有节点广播 FAILOVER_AUTH_REQUEST 信息,其他节点收到后,只有 master 响应,master 会相应第一个收到的 FAILOVER_AUTH_REQUEST 信息,并返回一个 ack,尝试发送 failover 的 slave 会收集 master 返回的 FAILOVER_AUTH_ACK,当 slave 收到超过半数的 master 的 ack 后,就会变成新的 master。

这样会导致 slave 一直没收到超过半数的 master 的 ack,难道要一直选举吗?

其实不会导致 slave 一直选举的,因为在 slave 知道 master 挂了之后,会经过一个延时时间 delay 之后再去给所有节点发送选举消息

延迟时间计算:delay = 500ms + random(0~500ms) + slave_rank * 1000ms (版本不同可能不一样,原理大致相同)

slave_rank表示slave已经从master复制数据的总量的rank,rank越小,表示复制的数据越新,该slave节点也就越先发起选举。

因此数据量越多的 slave 就越早发送选举消息,也就越早得到 master 的 ack,成为新的 master。

集群切片中的脑裂问题了解吗?如何解决?

比如一个主从集群:master1 对应两个从节点 slave1、slave2,如果master1和两个从节点出现网络分区,两个slave会选举出来一个新的master节点,客户端是可以感知到两个master,但是两个master之间因为网络分区无法感知,客户端会向这两个master都写入数据,之后如果网络分区恢复,其中一个master变为slave,就会导致数据丢失问题。

如何解决?添加redis配置:

min-slave-to-write 1 

表示写数据时,写入master之后,不立即返回客户端写成功,而是去slave同步数据,取值为1表示最少同步1个slave之后,才算数据写成功,如果同步的slave节点数量没有达到我们配置的值,就算数据写失败,取值建议:集群总共3个节点,可以取1,这样集群中超过半数(1个master + 1个slave)都写入数据成功,才算写成功。

但是这个配置为了数据的一致性,牺牲了一定的集群可用性,如果一个master的所有slave都挂了,这个小集群就不可用了,master无法写入数据。

一般不使用,redis丢一点数据也影响不大,所以主要还是保证redis的可用性

集群是否完整才能对外提供服务?

当redis.conf配置 cluster-require-full-coverage no 时,表示如果一个主从集群全部挂掉之后,集群仍然可用,如果为 yes,表示不可用

比如有3个主从集群,其中一个主从集群全部瘫痪,配置为no,则整个集群仍然可以正常工作

Redis集群如何对批量操作命令的支持?

对于 mset、mget 这样的多个 key 的原生批量操作命令,redis 集群只支持所有key落在同一个slot的情况,如果多个key一定要用mset在redis集群上操作,则可以在key之前加上{XX},这样就会根据大括号中的内容计算分片hash,确保不同的key落在同一slot内,例如:

mset {user1}: name zhuge {user1}:age 18

虽然name和age计算出来的 hash slot 值不同,但是前边加上大括号{user1},redis集群就会根据 user1 计算插槽值,最后name和age可以放入同一插槽。

相关推荐

  1. 哨兵机制Redis Sentinel)见面试题

    2023-12-07 02:28:02       28 阅读
  2. Redis见面试题

    2023-12-07 02:28:02       45 阅读
  3. Redis见面试题

    2023-12-07 02:28:02       62 阅读
  4. Redis见面试题

    2023-12-07 02:28:02       39 阅读
  5. redis见面试题

    2023-12-07 02:28:02       40 阅读
  6. Redis 见面试题

    2023-12-07 02:28:02       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-07 02:28:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-07 02:28:02       101 阅读
  3. 在Django里面运行非项目文件

    2023-12-07 02:28:02       82 阅读
  4. Python语言-面向对象

    2023-12-07 02:28:02       91 阅读

热门阅读

  1. opencv滤波技术

    2023-12-07 02:28:02       46 阅读
  2. Android:BackStackRecord

    2023-12-07 02:28:02       55 阅读
  3. Android 11.0 修改Android系统的通知自动成组的数量

    2023-12-07 02:28:02       58 阅读
  4. Uniapp自定义导航栏

    2023-12-07 02:28:02       57 阅读
  5. 基于python和定向爬虫的商品比价系统

    2023-12-07 02:28:02       59 阅读
  6. 关于数据劫持原理(vue2和vue3)

    2023-12-07 02:28:02       55 阅读