当前位置: 首页 > news >正文

Redis高频面试题汇总(中)

目录

1.什么是redis事务?

2.如何使用 Redis 事务?

3.Redis 事务为什么不支持原子性

4.Redis 事务支持持久性吗

5.Redis事务基于lua脚本的实现

6.Redis集群的主从复制模型是怎样的?

7.Redis集群中,主从复制的数据同步的步骤

8.Redis 增量复制的流程?

9.Redis 为什么主从全量复制使用RDB而不使用AOF?

10.Redis 为什么还有无磁盘复制模式?

11.什么是Redis Sentinel? 有什么用?

12.Redis Sentinel集群是通过什么方式组建的?

13.Redis 哨兵是如何监控Redis集群的?

14.Sentinel 如何检测节点是否下线?主观下线与客观下线的区别?

15.哨兵的选举机制是什么样的?

16.Redis主库判定客观下线了,那么如何从剩余的从库中选择一个新的主库呢?

17.新的主库选择出来后,如何进行故障的转移?

18.Sentinel 可以防止脑裂吗?

19.为什么需要 Redis Cluster?解决了什么问题?有什么优势?

20.Redis Cluster 是如何分片的?

21.为什么 Redis Cluster 的哈希槽是 16384 个?

22.如何确定给定 key 的应该分布到哪个哈希槽中?

23.Redis Cluster 支持重新分配哈希槽吗?

24.Redis Cluster 扩容缩容期间可以提供服务吗?

25.Redis Cluster 中的节点是怎么进行通信的?


1.什么是redis事务?

Redis事务是指在Redis数据库中进行一组命令的操作,这些命令可以被作为一个单独的、原子性的操作进行提交或者回滚。事务可以保证一组命令的原子性,即在一个事务中的所有命令要么全部被执行成功,要么全部不执行。

2.如何使用 Redis 事务?

在Redis中使用事务需要使用MULTI、EXEC、WATCH和DISCARD等命令。下面是一个简单的例子,展示如何使用Redis事务。

假设我们需要在Redis中将用户的账户余额减去一定数量的钱,并将这些钱转移到另一个账户。我们可以使用Redis事务来保证这两个操作的原子性。

首先,使用MULTI命令来开始一个事务:

MULTI

然后,将要执行的命令添加到事务中,例如:

DECRBY user:100:balance 50
INCRBY user:101:balance 50

这里我们使用DECRBY命令来减少用户100的余额,使用INCRBY命令来增加用户101的余额。注意,这些命令并没有直接执行,而是被添加到了事务中。

接下来,使用EXEC命令来提交事务:

EXEC

如果事务执行成功,Redis将返回一个包含每个命令执行结果的数组,如果事务执行失败,Redis将返回一个空数组。

如果在事务执行期间,我们需要监视一个或多个键,以便在其他客户端对它们进行修改时取消事务,我们可以使用WATCH命令。例如,我们可以使用以下命令来监视用户100的余额键:

WATCH user:100:balance

 如果在事务执行期间,其他客户端修改了被监视的键,那么事务将被取消,所有已添加到事务中的命令都不会被执行。此时,我们可以使用DISCARD命令来取消事务并清除所有已添加到事务中的命令:

DISCARD

这样,我们就可以使用Redis事务来保证一组操作的原子性,避免由并发操作引起的数据不一致问题。

3.Redis 事务为什么不支持原子性

虽然Redis的事务可以在多个命令之间执行,但是在执行事务期间,Redis不会将它们视为一个单独的操作单元。因此,如果在一个事务中执行多个命令,其中一个命令失败,那么其他命令仍然会执行,这就违反了原子性的要求。

Redis事务的主要目的是减少多个命令之间的通信开销,并确保在执行事务期间,其他客户端不能干扰正在执行的事务。因此,Redis事务只是一种逻辑分组命令的方式,并不能保证原子性。

Redis 官网也解释了自己为啥不支持回滚。简单来说就是 Redis 开发者们觉得没必要支持回滚,这样更简单便捷并且性能更好。Redis 开发者觉得即使命令执行错误也应该在开发过程中就被发现而不是生产过程中。

4.Redis 事务支持持久性吗

Redis 的持久化方式都是异步执行的,因为同步持久化会对 Redis 的性能造成很大的影响。因此,在使用 Redis 事务时,虽然事务本身可以保证一组命令的原子性,但是对于这些命令对 Redis 中的数据所做的修改是否被持久化到磁盘上,Redis 并不能做出保证。

5.Redis事务基于lua脚本的实现

Redis 事务可以基于 Lua 脚本来实现。在 Lua 脚本中,可以使用 Redis 的 MULTI 命令和 EXEC 命令来开启和提交事务,并在事务中执行多个 Redis 命令。Lua 脚本可以将多个 Redis 命令封装为一个整体,从而保证这些命令的原子性执行。

以下是一个使用 Lua 脚本实现 Redis 事务的示例:

-- 定义 Lua 脚本,其中包含多个 Redis 命令
local script = [[-- 开启 Redis 事务redis.call('MULTI')-- 执行多个 Redis 命令redis.call('SET', 'name', 'Alice')redis.call('INCR', 'count')-- 提交 Redis 事务return redis.call('EXEC')
]]-- 加载 Lua 脚本
local sha = redis.call('SCRIPT', 'LOAD', script)-- 执行 Lua 脚本,即执行 Redis 事务
redis.call('EVALSHA', sha)

上述 Lua 脚本使用了 Redis 的 MULTI 命令开启一个事务,然后执行了两个 Redis 命令(SET 和 INCR),最后使用 EXEC 命令提交事务。通过使用 EVALSHA 命令来执行 Lua 脚本,从而实现了 Redis 事务的功能。

在 Lua 脚本中,还可以使用 Redis 的 WATCH 命令来监控一个或多个键,并在事务执行之前检查这些键的值是否被其他客户端修改过。如果这些键的值被修改过,则事务执行失败,需要重新执行。通过使用 WATCH 命令,可以保证事务执行期间,所操作的键值不会被其他客户端修改,从而避免了其他客户端的干扰。

6.Redis集群的主从复制模型是怎样的?

Redis集群采用主从复制模型实现高可用性和可扩展性。在Redis集群中,每个节点可以是主节点或从节点。

主节点负责处理客户端请求,并将写操作同步到所有从节点。从节点接收来自主节点的同步复制数据,并复制主节点上的所有写操作,以保持自己的数据与主节点同步。

当主节点失效时,Redis集群会自动将其中一个从节点升级为主节点,以确保服务的可用性和数据的完整性。当新的主节点选举完成后,其他从节点将开始同步新的主节点,以便它们能够快速接管主节点的工作并继续服务。

Redis集群的主从复制模型通过实现数据的多个副本,提高了系统的可用性和可靠性。同时,通过添加更多的从节点,Redis集群还可以水平扩展,以处理更多的并发请求。

 7.Redis集群中,主从复制的数据同步的步骤

1.同步命令:当从节点重新上线后,它会向主节点发送SYNC命令,表示要进行全量同步。

2.全量同步:主节点接收到SYNC命令后,会将自己的所有数据发送给从节点,从节点会将这些数据写入自己的内存中。

3.增量同步:全量同步完成后,主节点会将新的写操作发送给从节点,从节点也会在自己的内存中执行这些写操作,以保持数据同步。

需要注意的是,当主节点接收到写操作后,它会先将数据写入自己的内存中,然后才会将命令传递给从节点。因此,如果主节点在传递命令之前崩溃了,可能会导致从节点的数据不完整。在这种情况下,从节点需要重新向主节点发送SYNC命令,进行全量同步。

 8.Redis 增量复制的流程?

Redis 增量复制是 Redis 主从复制的一种方式,用于将主节点的数据同步到从节点。其流程如下:

  1. 从节点发送 SYNC 命令到主节点,请求全量复制。主节点接收到请求后开始生成 RDB 快照文件,并将文件的数据同步给从节点,从节点接收到数据后将其保存到本地。

  2. 主节点在生成 RDB 文件的过程中,将所有的写命令(包括读写命令)缓存到内存中,并将缓存的写命令追加到一个专门用于增量复制的内存缓冲区中。这个缓冲区称为复制缓冲区(replication buffer)。

  3. 主节点将 RDB 文件传输完毕后,开始将复制缓冲区中的命令同步给从节点。主节点会将自己的复制缓冲区中的命令传输给从节点,并等待从节点对其进行确认。主节点会记录每个从节点在哪个位置接收到了命令,以便在下一次传输时只传输从这个位置开始的命令。

  4. 从节点接收到主节点的命令后,将其保存到本地的数据库中,并向主节点发送一个 ACK 命令,表示已经接收到了这些命令。主节点接收到 ACK 命令后,更新自己的记录,标记该从节点已经同步到了哪个位置。

  5. 从节点定期向主节点发送 PSYNC 命令,请求增量复制。主节点接收到请求后,判断是否可以进行增量复制。如果从节点的复制偏移量(replication offset)在主节点的复制缓冲区中,则可以进行增量复制;否则需要进行全量复制。

  6. 如果可以进行增量复制,则主节点会将从节点当前的复制偏移量所对应的命令以及其之后的命令传输给从节点。从节点接收到这些命令后,将其保存到本地数据库中。

  7. 如果不能进行增量复制,则主节点会重新生成 RDB 文件,并将其传输给从节点。

  8. 重复执行步骤 5 到 7,直到从节点与主节点同步完成。

需要注意的是,增量复制的缓存空间是有限的,如果主节点的缓存区已经满了,就无法再缓存新的写命令了,此时主节点只能进行全量复制。

9.Redis 为什么主从全量复制使用RDB而不使用AOF?

  1. RDB 文件的数据格式更加简单,可以更快地进行数据加载和恢复。RDB 文件只包含一份数据的快照,而 AOF 文件则记录了所有的写命令,因此 AOF 文件的数据格式更加复杂。

  2. RDB 文件的体积更小,传输速度更快。RDB 文件只包含一份数据的快照,因此其体积相对于 AOF 文件更小,传输速度也更快。在进行数据同步时,传输速度是一个重要的考虑因素。

  3. RDB 文件可以在不停止 Redis 服务的情况下进行数据备份和恢复。由于 RDB 文件只包含一份数据的快照,因此可以在 Redis 不停止服务的情况下进行数据备份和恢复。而 AOF 文件则需要在 Redis 停止服务时进行备份和恢复。

10.Redis 为什么还有无磁盘复制模式?

Redis 无磁盘复制模式(Diskless replication)是一种新的主从复制方式,其主要优点是可以减少网络带宽的占用,提高主从同步的速度,同时也减轻了主节点的磁盘负载。其原理是将主节点中的数据直接传输给从节点,而不需要将数据先写入到磁盘中。在无磁盘复制模式下,主节点不需要生成 RDB 文件或 AOF 文件,因此也不需要进行磁盘的读写操作。

无磁盘复制模式的优点在于可以提高主从同步的速度,尤其是在大规模的集群中。由于数据传输是通过网络进行的,因此在数据量较大的情况下,会占用较大的带宽。使用无磁盘复制模式可以减少网络带宽的占用,提高主从同步的速度。同时,无磁盘复制模式还可以减轻主节点的磁盘负载,避免了磁盘读写带来的性能问题。

然而,无磁盘复制模式也存在一些缺点。由于数据传输是通过网络进行的,因此会增加网络的负担,特别是在数据量较大的情况下。此外,由于数据传输是直接从主节点到从节点,因此如果从节点数量较多,可能会增加主节点的负载压力。

启用 Redis 无磁盘复制模式需要同时满足以下两个条件:

  1. 从节点必须运行在 Redis 6.0 及以上版本。

  2. 主节点必须运行在 Redis 6.2 及以上版本,并且需要在配置文件中设置 "repl-diskless-sync" 选项为 "yes"。

11.什么是Redis Sentinel? 有什么用?

Redis Sentinel 的主要作用是监控 Redis 主节点和从节点的健康状况,并在发生故障时自动切换到备用节点,保证 Redis 服务的连续性和可用性。具体来说,Redis Sentinel 提供了以下功能:

  1. 故障检测:Redis Sentinel 可以周期性地检测 Redis 主从节点的健康状态,包括网络连接状态、CPU 使用率、内存使用率等。

  2. 故障转移:当 Redis 主节点宕机或不可达时,Redis Sentinel 会自动将其中一台从节点切换为新的主节点,使得 Redis 服务可以继续提供服务。

  3. 自动故障恢复:当 Redis 主节点恢复正常运行时,Redis Sentinel 会将其重新添加到主从复制架构中,使得 Redis 服务恢复正常运行。

  4. 配置管理:Redis Sentinel 可以动态地管理 Redis 主从节点的配置,包括添加、删除、修改节点、设置节点权重等。

Redis Sentinel 的主要作用是提高 Redis 服务的可靠性和可用性,保证 Redis 服务在出现故障时能够快速地自动切换到备用节点,从而实现无缝切换。在生产环境中,Redis Sentinel 经常被用于构建高可用的 Redis 集群,保证 Redis 服务能够持续、稳定地运行。

12.Redis Sentinel集群是通过什么方式组建的?

Redis Sentinel(哨兵)实例之间可以通过 Redis 提供的 pub/sub(发布/订阅)机制相互发现。当一个 Sentinel 实例启动时,它会向 Redis 主节点发送 SENTINEL is-master-down-by-addr 命令,询问主节点是否宕机。如果主节点未响应,哨兵实例会向其他 Sentinel 实例发送同样的命令,以尝试确认主节点是否宕机。这个过程就利用了 Redis 的 pub/sub 机制,哨兵实例可以通过订阅特定的频道,接收其他 Sentinel 实例发送的状态更新消息,以便及时发现主节点故障。

在哨兵集群中,每个 Sentinel 实例都会向特定的频道发送状态更新信息,包括主节点的状态、从节点的状态以及哨兵实例的状态等。其他 Sentinel 实例可以通过订阅这些频道,接收并处理状态更新信息,从而保证 Redis Sentinel 集群的稳定性和可用性。

在主从集群中,主库上有一个名为__sentinel__:hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的。在下图中,哨兵 1 把自己的 IP(172.16.19.3)和端口(26579)发布到__sentinel__:hello频道上,哨兵 2 和 3 订阅了该频道。那么此时,哨兵 2 和 3 就可以从这个频道直接获取哨兵 1 的 IP 地址和端口号。然后,哨兵 2、3 可以和哨兵 1 建立网络连接。

 通过这个方式,哨兵 2 和 3 也可以建立网络连接,这样一来,哨兵集群就形成了。它们相互间可以通过网络连接进行通信,比如说对主库有没有下线这件事儿进行判断和协商。

13.Redis 哨兵是如何监控Redis集群的?

Redis Sentinel(哨兵)通过定期发送命令检查 Redis 主从节点的健康状况,以及通过 Redis 提供的 pub/sub 机制实时监控 Redis 集群状态,从而保证 Redis 集群的可用性和稳定性。具体来说,Redis Sentinel 主要通过以下几个方面来监控 Redis 集群:

1.定期发送命令检查 Redis 主从节点的健康状况

Redis Sentinel 会定期向 Redis 主从节点发送命令,例如 PING 命令或 INFO 命令,检查节点是否正常运行。如果节点未能正常响应命令,Redis Sentinel 会将其标记为 DOWN 状态,并开始进行自动故障转移操作。

2.通过 pub/sub 机制实时监控 Redis 集群状态

Redis Sentinel 使用 Redis 提供的 pub/sub 机制,订阅特定的频道,以接收 Redis 集群状态的更新信息。例如,当一个 Redis 主节点发生故障时,哨兵会向订阅的频道发布故障信息,通知其他哨兵实例进行故障转移操作。其他哨兵实例也会通过订阅这些频道,接收更新信息,从而保证集群状态的一致性和正确性。

3.定义故障转移策略和选举算法

Redis Sentinel 可以通过配置文件或命令行参数定义故障转移策略和选举算法,以满足不同场景下的需求。例如,可以定义故障转移操作的超时时间和重试次数,或者指定选举算法的优先级和权重等。

14.Sentinel 如何检测节点是否下线?主观下线与客观下线的区别?

Redis Sentinel 是一个高可用性的解决方案,它通过监控 Redis 实例的状态来实现自动故障转移。为了检测 Redis 节点是否下线,Redis Sentinel 会使用以下两种方式:

1.主观下线(Subjective Down)

在 Redis Sentinel 中,每个 Sentinel 进程会定期向其他 Sentinel 进程发送 PING 命令来检查 Redis 实例是否正常运行。如果一个 Sentinel 进程在指定时间内没有收到 Redis 实例的 PONG 响应,那么它就会将该 Redis 实例标记为主观下线。这个判断是基于 Sentinel 进程本身的主观认定。

2.客观下线(Objective Down)

除了主观下线外,Redis Sentinel 还支持客观下线的检测。当多个 Sentinel 进程都认为某个 Redis 实例已经下线时,该 Redis 实例就会被标记为客观下线。具体来说,当超过一半的 Sentinel 进程在指定时间内都认为某个 Redis 实例已经下线时,该 Redis 实例就会被标记为客观下线。

15.哨兵的选举机制是什么样的?

哨兵的选举机制使用的是Raft选举算法。

Raft选举算法是一种分布式一致性算法,它将节点分为三种角色:leader(领导者)、follower(跟随者)和candidate(候选者)。在初始状态下,所有节点都是follower。如果某个follower节点无法与leader节点保持通信,它就会变成candidate,并且开始新一轮的选举。

选举过程分为以下几个步骤:

  1. 选举超时(Election Timeout):candidate节点会在随机的时间间隔内成为candidate状态。此时它会向其他节点发送请求投票的消息,并开始计时。

  2. 收集投票(Request Vote):收到投票请求的节点会检查候选者的term(任期)是否比自己的大,如果是,则转换为follower状态,并将自己的vote for设置为候选者的ID。如果已经投过票或者发现候选者的term比自己小,则拒绝投票。

  3. 获得多数投票(Winning the Election):如果候选者收到了超过半数的投票,则它将成为新的leader,并向其他节点发送心跳消息,让它们知道新的leader已经产生。

  4. 防止分裂(Preventing Split Votes):如果候选者的term比follower节点的term大,则follower节点会转换为candidate状态,开始新一轮的选举。

在哨兵中,每个sentinel节点都可以成为candidate,通过相互之间的投票,选出新的leader节点。为了确保选举的稳定性和可靠性,哨兵中的选举过程还加入了一些附加机制,例如quorum机制,即必须得到大部分节点的投票才能选举成功。这些机制都是为了确保哨兵集群在出现故障或者网络分裂等情况下能够快速地选出新的leader节点,保证系统的可用性。

16.Redis主库判定客观下线了,那么如何从剩余的从库中选择一个新的主库呢?

1.首先,通过 Sentinel 或其他监控工具,检测出当前可用的所有从库,并且筛选出健康的、回复哨兵 ping 响应的从节点。

2.接着,从健康的从节点中选择一个作为新的主库,可以依据以下优先级:

  • 优先选择配置文件中设置了 slave-priority 优先级最高的从节点。

  • 如果有多个从节点的 slave-priority 优先级相同,那么就选择其中的一个复制偏移量最大的从节点作为新的主库。因为复制偏移量最大的从节点的数据最新,因此成为新的主库后,数据的损失最小。

  • 如果多个从节点的复制偏移量也相同,那么可以随机选择其中的一个作为新的主库。

3.在选择新的主库后,需要更新其他所有健康的从节点的配置文件,使其成为新的从节点,开始复制新的主库。这样可以确保数据的一致性。

总之,通过筛选健康的、回复哨兵 ping 响应的从节点,并优先选择 slave-priority 优先级最高的节点和复制偏移量最大的节点,可以选择出最适合成为新主库的从节点,从而实现 Redis 的高可用性。

17.新的主库选择出来后,如何进行故障的转移?

Redis Sentinel 实现故障转移的过程如下:

1.主节点失效检测

Sentinel 定期向主节点发送 PING 命令检测主节点是否还处于正常状态。如果 Sentinel 在指定时间内未能收到主节点的 PONG 响应,或者收到了一个认为主节点已经下线的 Sentinel 的通知,那么 Sentinel 将判断主节点已经失效。

2.选择新的主节点

当 Sentinel 发现主节点已经失效后,它会从 Redis 从节点中选择一个作为新的主节点。在选择新的主节点时,Sentinel 会考虑多个因素,比如从节点的复制偏移量、优先级等。

3.执行故障转移操作

一旦 Sentinel 确定了新的主节点,它会向其他 Sentinel 进程发送一条 SENTINEL is-master-down-by-addr 命令,要求其他 Sentinel 进程执行故障转移操作。在执行故障转移操作时,Sentinel 会:

  • 将从节点切换到新的主节点,以确保数据的一致性。
  • 更新 Redis 配置,使从节点成为新的主节点,并通知客户端连接新的主节点。

4.恢复原来的主节点

一旦 Sentinel 检测到原来的主节点已经恢复,它会将原来的主节点重新加入 Redis 集群中,并将其作为新的从节点进行复制。

18.Sentinel 可以防止脑裂吗?

Sentinel 可以一定程度上防止 Redis 节点的脑裂问题。

脑裂是指由于网络分区或者硬件故障等原因,导致 Redis 集群中的节点互相失去连接,无法进行正常的通信和数据同步。在这种情况下,Redis 集群会分裂成多个部分,每个部分认为自己是正确的,从而导致数据一致性和可用性的问题。

Sentinel 可以通过以下方式防止脑裂:

  1. 选举主节点:当 Sentinel 监测到主节点无法正常工作时,它会通过 Sentinel 集群中的选举机制,选举一个新的主节点。只有一个节点被选举为主节点,其他节点成为从节点。

  2. 故障转移:当 Sentinel 发现主节点无法正常工作时,它会将新主节点的地址广播给从节点,让它们切换到新的主节点。这种方式可以避免脑裂问题,因为只有一个新的主节点,从节点之间的数据同步也是在这个新主节点下进行的。

  3. Quorum:Sentinel 使用 quorum 机制来保证故障转移的正确性。Quorum 是指在集群中需要多少个 Sentinel 才能执行故障转移操作。通常情况下,Quorum 设置为 (Sentinel 数量/2 +1)。这样设置可以确保故障转移只会在大多数 Sentinel 都同意的情况下进行,从而避免脑裂问题。

尽管 Sentinel 能够一定程度上防止脑裂问题,但在极端情况下,仍然有可能发生脑裂,例如网络分区过大或者 Sentinel 数量过少等情况。因此,为了进一步提高 Redis 集群的高可用性,建议采用 Redis Cluster 等分布式 Redis 方案来避免脑裂问题。

19.为什么需要 Redis Cluster?解决了什么问题?有什么优势?

Redis Cluster 是 Redis 的分布式集群方案,可以解决单机 Redis 的容量和性能瓶颈问题,并提供更高的可用性和可扩展性。

具体来说,需要 Redis Cluster 主要是为了解决以下问题:

  1. 容量限制:单机 Redis 的容量受限于内存大小,如果需要存储更多的数据,就需要使用更多的 Redis 实例,而这样会导致数据分散在多个实例中,管理和维护难度增加。

  2. 性能瓶颈:单机 Redis 的性能在处理大规模数据时会受到限制,例如大量的读写请求会导致单机 Redis 的响应速度变慢。

  3. 可用性:单机 Redis 面临单点故障问题,如果 Redis 实例出现故障,就会导致整个 Redis 服务不可用。

Redis Cluster 通过将数据分片到多个 Redis 节点上,实现数据的分布式存储和访问。每个 Redis Cluster 节点都可以同时处理多个请求,从而提高了 Redis 的性能和吞吐量。此外,Redis Cluster 还可以自动进行数据备份和故障转移,从而保证 Redis 集群的高可用性。

Redis Cluster 的优势主要包括:

  1. 横向扩展:Redis Cluster 可以方便地实现数据的横向扩展,通过增加 Redis 节点的数量,可以增加集群的容量和性能,而无需更改应用程序。

  2. 高可用性:Redis Cluster 采用主从复制机制来保证数据的高可用性。当主节点失效时,可以自动切换到从节点,从而避免单点故障问题。

  3. 分布式管理:Redis Cluster 可以方便地进行节点的添加、删除和重分片等操作,而无需停止服务。

  4. 自动负载均衡:Redis Cluster 可以根据每个节点的负载情况,自动将请求分配到最适合的节点上,从而实现负载均衡。

总之,Redis Cluster 提供了更高的可扩展性、高可用性、性能和灵活性,适用于需要存储大量数据和高并发访问的场景。

20.Redis Cluster 是如何分片的?

Redis Cluster 使用哈希槽(hash slot)分片策略,将数据按照键名的哈希值映射到一个 0 到 16383 的哈希槽上,然后将每个哈希槽分配到不同的节点上进行存储。

具体来说,Redis Cluster 会将每个节点分配一定数量的哈希槽,每个哈希槽都对应一个键值对。当客户端发送命令时,Redis Cluster 会根据命令所涉及的键名的哈希值,将命令分配到相应的哈希槽所在的节点上进行处理。

例如,如果一个 Redis Cluster 集群有 3 个节点 A、B、C,每个节点被分配了 5461 个哈希槽,那么哈希槽 0 到 5460 就属于节点 A,5461 到 10921 属于节点 B,10922 到 16383 属于节点 C。当客户端发送一个 SET key1 value1 命令时,Redis Cluster 会将 key1 的哈希值计算出来,并将该命令分配到对应的哈希槽所在的节点上进行处理。如果 key1 的哈希值在 0 到 5460 范围内,那么该命令就会被分配到节点 A 上进行处理。

哈希槽分片策略可以保证每个节点存储的数据均衡分布,同时也保证了集群的可扩展性。当需要扩容或缩容时,只需将哈希槽重新分配到新的节点上即可。此外,哈希槽分片策略还可以保证节点之间的数据相互独立,避免了单点故障的风险。

21.为什么 Redis Cluster 的哈希槽是 16384 个?

Redis实例之间「通讯」会相互交换「槽信息」,那如果槽过多(意味着网络包会变大),网络包变大,意味着会「过度占用」网络的带宽,Redis作者认为集群在一般情况下是不会超过1000个实例,那就取了16384个,即可以将数据合理打散至Redis集群中的不同实例,又不会在交换数据时导致带宽占用过多。

22.如何确定给定 key 的应该分布到哪个哈希槽中?

在 Redis 集群中,每个 key 都会被映射到一个哈希槽中,确定给定 key 的哈希槽可以按照以下步骤进行:

  1. 对 key 计算哈希值,使用的哈希函数为 CRC16 校验和算法,这个算法会返回一个 16 位的无符号整数。

  2. 将这个 16 位无符号整数除以哈希槽的数量(默认为 16384),取余数,得到的结果就是 key 应该被映射到的哈希槽编号。

例如,对于一个 key "hello",可以按照以下步骤计算其应该被映射到的哈希槽编号:

  1. 计算 "hello" 的 CRC16 校验和值为 2229。

  2. 将 2229 对 16384 取余数,得到的结果为 1093,所以 key "hello" 应该被映射到哈希槽编号为 1093。

23.Redis Cluster 支持重新分配哈希槽吗?

是的,Redis Cluster 支持重新分配哈希槽,也称为“resharding”。在 Redis Cluster 运行过程中,可能会遇到新增节点、节点故障、节点扩容等情况,这些变化可能会导致哈希槽的分布不再均匀,进而影响集群的性能和可用性。

为了解决这个问题,Redis Cluster 提供了一种叫做“resharding”的机制,可以重新分配哈希槽,使其均匀地分布在新的节点上。具体来说,resharding 的过程如下:

  1. 添加新节点:当新节点加入集群时,它的哈希槽数量会被平均分配给所有节点。

  2. 节点故障:当某个节点故障时,它的哈希槽会被重新分配给其他节点。

  3. 节点扩容:当某个节点需要扩容时,它可以请求集群管理员为其分配一部分哈希槽,管理员将这些哈希槽分配给该节点。

在这些操作中,Redis Cluster 会使用一些算法来保证哈希槽的均匀分布,例如,在添加新节点或故障转移时,集群会尝试将不同节点的哈希槽数量调整到差不多相同的水平。

需要注意的是,resharding 操作可能会对集群的性能和可用性产生影响,因此应该在必要时进行,避免过于频繁地进行哈希槽的重新分配。

24.Redis Cluster 扩容缩容期间可以提供服务吗?

在 Redis Cluster 扩容或缩容期间,集群仍然可以提供服务,但可能会对集群的性能和可用性产生一定的影响。

当集群需要扩容时,新节点会被添加到集群中,并且哈希槽会重新分配。在这个过程中,集群的性能可能会受到一定的影响,因为节点之间需要进行大量的数据传输和同步。如果数据量较大,这个过程可能会持续相当长的时间,这期间集群的响应时间可能会变慢,而且可能会出现一些数据不一致的情况。

同样的,在集群需要缩容时,一些节点会被移除,哈希槽也会重新分配。这个过程可能会导致集群的性能和可用性下降,因为移除节点需要进行大量的数据迁移和同步,这个过程可能也会比较耗时。

为了最小化对集群的影响,可以采用一些措施来优化扩容或缩容过程,例如使用在线迁移或增量同步等技术来减少节点之间的数据传输量,或者在集群负载较轻的时候进行操作。此外,在进行扩容或缩容操作时,应该尽量避免同时进行多个操作,以免影响集群的稳定性和性能。

25.Redis Cluster 中的节点是怎么进行通信的?

通过 Gossip 协议进行通信;

新加入节点: Gossip 协议向老节点,发出一个“Meet 消息”。老节点会回复“Pong 消息”。后续新节点会定期给老节点发送“ping”,老节点回复"pong",来确保联系保持

Meet 消息,用于通知新节点加入。就好像上面例子中提到的新节点上线会给老节点发送 Meet 消息,表示有“新成员”加入。Ping 消息,这个消息使用得最为频繁,该消息中封装了自身节点和其他节点的状态数据,有规律地发给其他节点。Pong 消息,在接受到 Meet 和 Ping 消息以后,也将自己的数据状态发给对方。同时也可以对集群中所有的节点发起广播,告知大家的自身状态。Fail 消息,如果一个节点下线或者挂掉了,会向集群中广播这个消息。

通讯是为了保证每个节点都有其他节点的槽数据对应关系,每个节点都有ClusterState,它记录了所有槽和节点的对应关系。Redis 的客户端无论访问集群中的哪个节点都可以路由到对应的节点上

MOVED 重定向请求:请求到redis某个节点,发现slot不在该服务器,则返回moved命令,告诉redis客户端应该请求哪个节点重写向所在节点发送请求

ASK 重定向请求:Redis 客户端向“缓存节点 1”发出请求,此时“缓存节点 1”正向“缓存节点 2”迁移数据,如果没有命中对应的 Slot,它会返回客户端一个 ASK 重定向请求并且告诉“缓存节点 2”的地址。

客户端向“缓存节点 2”发送 Asking 命令,询问需要的数据是否在“缓存节点 2”上,“缓存节点 2”接到消息以后返回数据是否存在的结果。 

相关文章:

Redis高频面试题汇总(中)

目录 1.什么是redis事务? 2.如何使用 Redis 事务? 3.Redis 事务为什么不支持原子性 4.Redis 事务支持持久性吗 5.Redis事务基于lua脚本的实现 6.Redis集群的主从复制模型是怎样的? 7.Redis集群中,主从复制的数据同步的步骤 …...

【Flutter从入门到入坑之三】Flutter 是如何工作的

【Flutter从入门到入坑之一】Flutter 介绍及安装使用 【Flutter从入门到入坑之二】Dart语言基础概述 【Flutter从入门到入坑之三】Flutter 是如何工作的 本文章主要以界面渲染过程为例,介绍一下 Flutter 是如何工作的。 页面中的各界面元素(Widget&…...

Web Components学习(2)-语法

一、Web Components 对 Vue 的影响 尤雨溪在创建 Vue 的时候大量参考了 Web Components 的语法&#xff0c;下面写个简单示例。 首先写个 Vue 组件 my-span.vue&#xff1a; <!-- my-span.vue --> <template><span>my-span</span> </template>…...

Lesson 9.2 随机森林回归器的参数

文章目录一、弱分类器的结构1. 分枝标准与特征重要性2. 调节树结构来控制过拟合二、弱分类器的数量三、弱分类器训练的数据1. 样本的随机抽样2. 特征的随机抽样3. 随机抽样的模式四、弱分类器的其他参数在开始学习之前&#xff0c;先导入我们需要的库。 import numpy as np im…...

Kubernetes Secret简介

Secret概述 前面文章中学习ConfigMap的时候&#xff0c;我们说ConfigMap这个资源对象是Kubernetes当中非常重要的一个对象&#xff0c;一般情况下ConfigMap是用来存储一些非安全的配置信息&#xff0c;如果涉及到一些安全相关的数据的话用ConfigMap就非常不妥了&#xff0c;因…...

Redis 哨兵(Sentinel)

文章目录1.概述2. 没有哨兵下主从效果3.搭建多哨兵3.1 新建目录3.2 复制redis3.3 复制配置文件3.4 修改配置文件3.5 启动主从3.6 启动三个哨兵3.7 查看日志3.8 测试宕机1.概述 在redis主从默认是只有主具备写的能力&#xff0c;而从只能读。如果主宕机&#xff0c;整个节点不具…...

精读笔记 - How to backdoor Federated Learning

文章目录 精读笔记 - How to backdoor Federated Learning1. 基本信息2. 系统概要3. 攻击模型3.1 问题形式化定义3.1.1 前提假设3.1.2 攻击目标3.2 创新点3.2.1 Semantic Backdoor3.2.2 攻击方法4. 实验验证4.1 图像分类4.2 实验操作4.2.1 超参数设置4.2.2 衡量标准4.3 结果分析…...

即时通讯系列-N-客户端如何在推拉结合的模式下保证消息的可靠性展示

结论先行 原则&#xff1a; server拉取的消息一定是连续的原则&#xff1a; 端侧记录的消息的连续段有两个作用&#xff1a; 1. 记录消息的连续性&#xff0c; 即起始中间没有断层&#xff0c; 2. 消息连续&#xff0c; 同时意味着消息是最新的&#xff0c;消息不是过期的。同…...

关于js数据类型的理解

目录标题一、js数据类型分为 基本数据类型和引用数据类型二、区别&#xff1a;传值和传址三、深浅拷贝传值四、数据类型的判断一、js数据类型分为 基本数据类型和引用数据类型 1、基本数据类型 Number、String、Boolean、Null、undefined、BigInt、Symbol 2、引用数据类型 像对…...

大一上计算机期末考试考点

RGB颜色模型也称为相加混色模型 采样频率大于或等于原始声音信号最高频率的两倍即可还原出原始信号. 声音数字化过程中&#xff0c;采样是把时间上连续的模拟信号在时间轴上离散化的过程。 量化的主要工作就是将幅度上连续取值的每一个样本转换为离散值表示。 图像数字化过…...

微搭问搭001-如何清空表单的数据

韩老师&#xff0c;我点关闭按钮后&#xff0c;弹窗从新打开&#xff0c;里面的数据还在&#xff0c;这个可以从新打开清除不&#xff1f; 点关闭的时候清掉 就是清楚不掉也&#xff1f;咋清掉 清掉表单内容有属性可以做到&#xff1f; $page.widgets.id**.value “” 就可以实…...

Windows7,10使用:Vagrant+VirtualBox 安装 centos7

一、Vagrant&#xff0c;VirtualBox 是什么二、版本说明1、win7下建议安装版本2、win10下建议安装版本三、Windows7下安装1、安装Vagrant2、安装VirtualBox3、打开VirtualBox&#xff0c;配置虚拟机默认安装地址四、windows7下载.box文件&#xff0c;安装centos 71、下载一个.b…...

基于JavaEE开发博客系统项目开发与设计(附源码)

文章目录1.项目介绍2.项目模块3.项目效果1.项目介绍 这是一个基于JavaEE开发的一个博客系统。实现了博客的基本功能&#xff0c;前台页面可以进行文章浏览&#xff0c;关键词搜索&#xff0c;登录注册&#xff1b;登陆后支持对文章进行感谢、评论&#xff1b;然后还可以对评论…...

Android Framework——zygote 启动 SystemServer

概述 在Android系统中&#xff0c;所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育&#xff08;fork&#xff09;出来的&#xff0c;这也许就是为什么要把它称为Zygote&#xff08;受精卵&#xff09;的原因吧。由于Zygote进程在Android系统中有着如此重…...

在ubuntu上搭建SSH和FTP和NFS和TFTP

一、SSH服务搭建使用如下命令安装 SSH 服务&#xff1b;ssh 的配置文件为/etc/ssh/sshd_config&#xff0c;使用默认配置即可。sudo apt-get install openssh-server开启 SSH 服务以后我们就可以在 Windwos 下使用终端软件登陆到 Ubuntu&#xff0c;比如使用 Mobaxterm。二、FT…...

ThinkPHP 6.1 模板篇之文件加载

本文主要讲述模板中如何使用包含文件、引入css/js文件及路径优化。 包含文件 使用{include}标签来加载公用重复的文件&#xff0c;比如头部、尾部和导航部分 包含用法 1.创建公用文件 在模版 view 目录创建一个 common公共目录&#xff0c;分别创建 header、footer 和 nav …...

操作系统内核与安全分析课程笔记【1】链表、汇编与makefile

文章目录链表循环双向链表哈希链表其他链表汇编内联汇编扩展内联汇编makefile链表 链表是linux内核中关键的数据结构。在第二次课中&#xff0c;重点介绍了循环双向链表和哈希链表。这两种链表都在传统的双向链表的基础之上进行了针对效率的优化。(ps&#xff1a;这部分可以通…...

华为OD机试题 - 九宫格按键输入(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:九宫格按键输入题目输入输出示例一输入输出说明示例二输入输出说…...

PMSM控制_foc 控制环路

整个系统的控制过程有以下部分&#xff0c;以无感FOC&#xff0c;双电阻电流采样&#xff0c;控制周期为 10KHz 为例&#xff1a; 1、在每隔一个 PWM 周期采样一次两相电流 2、进行 FOC 的计算 &#xff08;1&#xff09;clarke 变换&#xff0c;将电流变换至静止坐标系下的 Ia…...

Linux 练习七 (IPC 共享内存)

文章目录System V 共享内存机制&#xff1a;shmget shmat shmdt shmctl案例一&#xff1a;有亲缘关系的进程通信案例二&#xff1a;非亲缘关系的进程通信内存写端write1.c内存读端read1.c案例三&#xff1a;不同程序之间的进程通信程序一&#xff0c;写者shmwr.c程序二&#xf…...

【数据库原理复习】ch4 完整性约束 SQL定义

这里写目录标题基本概念实体完整性参照完整性违规处理用户自定义完整性约束条件定义完整性约束命名字句基本概念 完整性约束主要包括 实体完整性参照完整性用户自定义完整性 实体完整性 关系模型中实体完整性通常在建表时候添加primary key完成 # primary key定义 create …...

【2023年的就业形势依旧严峻】

2023年口罩放开的第一年&#xff0c;也是第一个招聘会&#xff0c;挤满了求职者和用人单位&#xff0c;大多数都是想着重新开始&#xff0c;抓住金三银四的好时机&#xff0c;找到心仪的工作和符合岗位要求的人才&#xff0c;一起整装出发。我们理想的状态是&#xff0c;经济已…...

Linux下LED灯驱动模板详解

一、地址映射我们先了解MMU&#xff0c;全称是Memory Manage Unit。在老版本的Linux中要求处理器必须有MMU&#xff0c;但是现在Linux内核已经支持五MMU。MMU主要完成的功能如下&#xff1a;1、完成虚拟空间到物理空间的映射2、内存保护&#xff0c;设置存储器的访问权限&#…...

【C++】你不得不爱的——继承

凡是面向对象的语言&#xff0c;都有三大特性&#xff0c;继承&#xff0c;封装和多态&#xff0c;但并不是只有这三个特性&#xff0c;是因为者三个特性是最重要的特性&#xff0c;那今天我们一起来看继承&#xff01; 目录 1.继承的概念及定义 1.概念 2.继承的定义 2.基类…...

数据库系统概论

文章目录前言基础篇&#xff1a;1-5章第 1 章 绪论1.1 数据库系统概述1.2 数据模型1.3 数据库系统的结构1.4 数据库系统的组成1.5 小结第 2 章 关系数据库1.关系模型1.1 关系数据结构1.2 关系完整性约束实体完整性、参照完整性、用户定义完整性2.关系代数8种关系代数运算符并 ∪…...

32位处理器AM6528BACDXEA、AM6548BACDXEAF基于Arm Cortex-A53内核【工业4.0嵌入式产品应用】

AM6528BACDXEA、AM6548BACDXEAF 处理器是专为满足工业4.0嵌入式产品对处理性能的复杂需求而设计的Arm应用处理器。AM654x和AM652x器件将四个或两个Arm Cortex-A53内核与一个双Arm Cortex-R5F MCU子系统结合在一起。这些包含的功能旨在帮助客户实现终端产品的功能安全目标。它还…...

多图片怎么转换成PDF?这招教你轻松转换

多图片怎么转换成PDF&#xff1f;我们经常会传输图片文件给同事或者朋友&#xff0c;但是多张图片的传输比较麻烦&#xff0c;有的时候传输比较慢&#xff0c;而且也不便于查看&#xff0c;所以我们就可以将需要传输的多张图片转换成一个PDF文件&#xff0c;这样查看文件时就可…...

kali双网卡

先单独开启一个网卡&#xff0c;配置/etc/network/interfaces 修改为如下配置 This file describes the network interfaces available on your system and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* The loopb…...

【wed前端初级课程】第一章 什么是HTML

什么是WEB前端&#xff1f; 简单来说就是网页&#xff0c;只是这个网页它是由多种技术参与制作的&#xff0c;用来向用户展示的页面。 HTML(超文本标签语言)&#xff1a;它决定了网页的结构。 CSS&#xff1a;网页的装饰器。 JavaScript&#xff1a;JavaScrip最初是因为校验…...

sd卡格式化后数据恢复怎么操作

有时候我们需要清空SD卡数据文件&#xff0c;有时候则是因为需要修复SD卡所以需要格式化&#xff0c;但是却被提示无法格式化SD卡。这种情况往往是由于平时SD卡使用时的一些不良习惯或是SD卡中病毒&#xff0c;病毒在运行SD卡中的软件所造成的。那么sd卡格式化后数据恢复怎么操…...

大连sem网站建设/搜索优化指的是什么

大家好&#xff0c;这里是小虾虾科技屋——————————————————————有时候&#xff0c;某个软件随着更新&#xff0c;会带走许多历史的痕迹&#xff0c;于是有的人就想尝试复原那些软件&#xff0c;所以产生了今天为大家分享的工具。iTunes旧版软件抓包神器&a…...

深圳服饰网站建设/如何把网站推广出去

1.list中添加&#xff0c;获取&#xff0c;删除元素&#xff1b; 添加方法是&#xff1a;.add(e)&#xff1b;  获取方法是&#xff1a;.get(index)&#xff1b;  删除方法是&#xff1a;.remove(index)&#xff1b; 按照索引删除&#xff1b;  .remove(Object o)&#x…...

简述电子政务网站设计的技术/如何去除痘痘效果好

上图中&#xff0c;一边的接口的网络类型是点到点&#xff0c;一边的网络类型是广播型的&#xff0c;他们的hello时间和dead时间一致&#xff0c; 实验证明他们可以建立邻居&#xff0c;但是R1学不到R2的环回口的地址&#xff0c;同样R2也学不到R1的环回口地址&#xff0c;但是…...

坪地网站建设如何/网站批量收录

公众号关注 「奇妙的 Linux 世界」设为「星标」&#xff0c;每天带你提升技术视野&#xff01;私有云裸金属架构&#xff08;这是相对云上环境来说&#xff0c;不是说无操作系统&#xff09;上部署的 Kubernetes 集群&#xff0c;通常是无法使用 LoadBalancer 类型的 Service 的…...

广告制作行业发展前景/郑州seo排名优化

今天在写网站的时候同一个条件需要对比多个值&#xff0c;框架是thinkphp的查了下资料发现是可以判断的&#xff0c;接下来吾爱编程就为大家介绍一下thinkphp中if标签的condition用法&#xff0c;有需要的小伙伴可以参考一下&#xff1a;1、condition语法介绍&#xff1a;{if c…...

做网站建设需要做哪些工作/销售网站有哪些

Delphi 2010安装及使用UniDAC 4.0 . 分类&#xff1a; unidac 2012-04-08 11:30 77人阅读 评论(0) 收藏 举报UniDAC是一个功能强大的非可视化跨数据库的数据访问组件&#xff0c;可用于Delphi&#xff0c;Delphi for .NET&#xff0c;CBuilder&#xff0c;and Lazarus (Free …...