redis cluster(3)- redis集群管理:伸缩,故障

2022-04-14 19:45:52 浏览数 (1)

redis集群数据分布及槽信息

Redis Cluster中有一个16384长度的槽的概念,他们的编号为0、1、2、3……16382、16383。这个槽是一个虚拟的槽,并不是真正存在的。正常工作的时候,Redis Cluster中的每个Master节点都会负责一部分的槽,当有某个key被映射到某个Master负责的槽,那么这个Master负责为这个key提供服务,至于哪个Master节点负责哪个槽,这是可以由用户指定的,也可以在初始化的时候自动生成(redis-trib.rb脚本)。这里值得一提的是,在Redis Cluster中,只有Master才拥有槽的所有权,如果是某个Master的slave,这个slave只负责槽的使用,但是没有所有权。

数据分片在Redis Cluster中,拥有16384个slot,这个数是固定的,存储在Redis Cluster中的所有的键都会被映射到这些slot中。数据库中的每个键都属于这16384个哈希槽的其中一个,集群使用公式CRC16(key) % 16384来计算键key属于哪个槽,其中CRC16(key)语句用于计算键key的CRC16校验和。集群中的每个节点负责处理一部分哈希槽。

所以我们在伸缩节点的时候,实质上也是对于哈希槽和槽对应数据的一个调整:槽slot和数据在节点之间的移动。

1、新增节点:

增加节点的顺序是先增加Master主节点,然后在增加Slave从节点。在新的机器上启动新的两个节点,并记录其ID

代码语言:javascript复制
redis-server /mnt/redis-cluster-7029/redis.conf
redis-server /mnt/redis-cluster-7030/redis.conf

redis-cli -c -p 7029 cluster nodes 
#7029输出以下内容:
4ce0a2cc06dbc435c90c45ff891a262ef58a1cfd :7029 myself,master - 0 0 0 connected

redis-cli -c -p 7030 cluster nodes
#7030输出以下内容:
923e869b3fda8add429fb200ea00ce94bdbc84e6 :7030 myself,master - 0 0 0 connected 

2. 新节点加入集群:

将新机器上的两个新实例加入到需要扩容的集群中

代码语言:javascript复制
#"10.25.157.78:7022"为需要扩容的集群中任意主节点
#"10.80.82.74:7029&7030"为新添加的服务器中的新实例
redis-trib.rb add-node 10.80.82.74:7029 10.25.157.78:7022
redis-trib.rb add-node 10.80.82.74:7030 10.25.157.78:7022

#查看一下是否加入成功
redis-cli -c -p 7029 cluster nodes

3. 设置新节点的主从模式

将10.80.82.74:7029设为master,10.80.82.74:7030设为slave

代码语言:javascript复制
#在10.80.82.74上执行:(其中4ce0a2cc06dbc435c90c45ff891a262ef58a1cfd为7029实例的ID)
redis-cli -c -p 7030
cluster replicate 4ce0a2cc06dbc435c90c45ff891a262ef58a1cfd

#查看一下,发现设置成功:
[root@tuling10-80-82-74 ~]# redis-cli -c -p 7029 cluster nodes
1f7f9825b2ed6253d50fdcbc8db6a10c43fd2ad4 10.45.144.56:7027 master - 0 1538969449311 9 connected 0-4095
6eadec56705c1e8a174e122145afde836cc412f5 10.25.157.78:7024 slave 1ae708c9458a8e97d199f461b21b1ac5c422dc18 0 1538969449310 6 connected
1ae708c9458a8e97d199f461b21b1ac5c422dc18 10.45.144.56:7026 master - 0 1538969449410 6 connected 12288-16383
35123eb1a9e564794eebd84de0b68993d76bce2a 10.45.144.56:7025 master - 0 1538969447809 5 connected 4096-8191
a9dddb597278bc0956f88c3b25ebad4edac975c9 10.25.157.78:7021 slave 1f7f9825b2ed6253d50fdcbc8db6a10c43fd2ad4 0 1538969448808 9 connected
102489d5d6e03731174876bd29b86c44cfc8190d 10.25.157.78:7023 slave 35123eb1a9e564794eebd84de0b68993d76bce2a 0 1538969449310 5 connected
408525165ed0cb15f3fea7a865879d0968d00b04 10.25.157.78:7022 master - 0 1538969448307 2 connected 8192-12287
d3d9c35ee4602b40276d5fc45865c1d736eaa757 10.45.144.56:7028 slave 408525165ed0cb15f3fea7a865879d0968d00b04 0 1538969448809 2 connected
4ce0a2cc06dbc435c90c45ff891a262ef58a1cfd 10.80.82.74:7029 myself,master - 0 0 10 connected
923e869b3fda8add429fb200ea00ce94bdbc84e6 10.80.82.74:7030 slave 4ce0a2cc06dbc435c90c45ff891a262ef58a1cfd 0 1538969447307 10 connected

4.数据分片,迁移槽位

新节点刚开始都是主节点状态,但是由于没有负责的槽,所以不能接受任何读写操作。对于新节点的后续操作一般有两种选择:

◆ 为它迁移槽和数据实现扩容

◆ 作为其他主节点的从节点负责故障转移

我们原集群中有4个master,总共16384个槽位,新增一台master后即需要从原4个实例上每个迁移819个槽位。

16384/5 约等于3277 迁移数:slot=4096-3276=819

通过redis-trib.rb reshard可以交互式地迁移Slot。也可以通过./redis-trib.rb reshard <host>:<port> --from <node-id> --to <node-id> --slots --yes在程序中自动完成迁移。

注意:当添加新节点成功以后,新的节点不会有任何数据,因为他没有分配任何的数据Slot(哈希slots),这一步需要手动操作。

为7029Master主节点分配数据Slots,分配方法是从集群中知道任何一个主节点(因为只有Master主节点才有数据slots),然后对其进行重新分片工作。

代码语言:javascript复制
#在集群中任意一台机器上执行:(这里我们在10.25.157.78上执行)
redis-trib.rb reshard 10.25.157.78:7022

How many slots do you want to move (from 1 to 16384)? 819
What is the receiving node ID? 4ce0a2cc06dbc435c90c45ff891a262ef58a1cfd  #新实例ID
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1:408525165ed0cb15f3fea7a865879d0968d00b04 #原实例ID
Source node #2:done

5.验证一下:

代码语言:javascript复制
redis-trib.rb info 10.25.157.78:7022

6.缩容:

删除节点:删除的顺序是先删除Slave从节点,然后在删除Master主节点

代码语言:javascript复制
# 例:删除从节点10.80.82.74:7030 (删除7030从节点,输入del-node命令,指定删除节点的IP地址和Port端口号,同时还要提供该从节点ID名称。)
redis-trib.rb del-node 10.80.82.74:7030 923e869b3fda8add429fb200ea00ce94bdbc84e6

7、故障转移

在高可用性方面,Redis可算是能够”Auto”一把了!Redis Cluster重用了Sentinel的代码逻辑,不需要单独启动一个Sentinel集群,Redis Cluster本身就能自动进行Master选举和Failover切换。

下面我们故意kill掉702结点,之后9可以看到结点状态变成了fail,而Slave 7011被选举为新的Master。

尝试查询之前保存在7010上的Key,可以看到7011顶替上来继续提供服务,整个集群没有受到影响。

# src/redis-cli -c -h 192.168.1.100 -p 7000 get foo6

# src/redis-cli -c -h 192.168.1.100 -p 7000 get foo2

# "bar"

故障情况:

  • 当某个从节点挂掉之后,对于redis集群来说几乎没有什么影响,相当于这个从节点对应的 主节点少了一个备份而已。
  • 当某一个主节点挂掉之后,redis 会从这个 主节点 的 多个从节点 中推选一个出来,担当master的工作,并且把之前依附在
  • 主节点的从节点调整依附到新的master上。如果新任的master也挂掉并且他没有从节点了,那么这个集群也真正的挂掉了。

https://www.cnblogs.com/PatrickLiu/p/8458788.html

注意:在此测试期间,应该运行一致性测试应用程序时打开选项卡。   为了触发故障转移,我们可以做的最简单的事情(这也是分布式系统中可能发生的语义上最简单的故障)是使单个进程崩溃,在我们的当前的情况下就是单个主进程。   我们可以识别一个集群并使用以下命令将其崩溃:

$ redis-cli -p 7000 cluster nodes | grep master 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385482984082 0 connected 5960-10921 2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 master - 0 1385482983582 0 connected 11423-16383 97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422   好吧,7000,7001和7002都是主服务器节点。 让我们用 DEBUG SEGFAULT 命令使节点7002崩溃:

代码语言:javascript复制
           $ redis-cli -p 7002 debug segfault
           Error: Server closed the connection

  现在我们可以看一致性测试的输出以查看它报告的内容。

代码语言:javascript复制
        18849 R (0 err) | 18849 W (0 err) |
        23151 R (0 err) | 23151 W (0 err) |
        27302 R (0 err) | 27302 W (0 err) |
        ... many error warnings here ...
   
        29659 R (578 err) | 29660 W (577 err) |
        33749 R (578 err) | 33750 W (577 err) |
        37918 R (578 err) | 37919 W (577 err) |
        42077 R (578 err) | 42078 W (577 err) |

    正如您在故障转移期间所看到的,系统无法接受578次读取和577次写入,但是在数据库中未创建任何不一致。 这听起来可能会出乎意料,因为在本教程的第一部分中,我们声明Redis群集在故障转移期间可能会丢失写入,因为它使用异步复制。 我们没有说的是,这种情况不太可能发生,因为Redis会将答复发送给客户端,并将命令复制到从服务器,同时,因此会有一个非常小的窗口来丢失数据。 但是很难触发这一事实并不意味着这是不可能的,所以这不会改变Redis集群提供的一致性保证。     现在我们可以检查故障转移后的群集设置(注意,在此期间,我重新启动了崩溃的实例,以便它重新加入作为从属群集):

代码语言:javascript复制
          $ redis-cli -p 7000 cluster nodes
          3fc783611028b1707fd65345e763befb36454d73 127.0.0.1:7004 slave 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 0 1385503418521 0 connected
          a211e242fc6b22a9427fed61285e85892fa04e08 127.0.0.1:7003 slave 97a3a64667477371c4479320d683e4c8db5858b1 0 1385503419023 0 connected
          97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422
          3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7005 master - 0 1385503419023 3 connected 11423-16383
          3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385503417005 0 connected 5960-10921
          2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 slave 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 0 1385503418016 3 connected

    现在,主服务器节点正在端口7000,7001和7002上运行。以前是主服务器节点,即运行在端口7005上的Redis实例,现在是7002的从服务器节点。

代码语言:javascript复制
            Node ID
          ip:port
          flags: master, slave, myself, fail, ...
          if it is a slave, the Node ID of the master
          Time of the last pending PING still waiting for a reply.
           Time of the last PONG received.
            Configuration epoch for this node (see the Cluster specification).
           Status of the link to this node.
            Slots served...

六、手动故障转移   有时,强制进行故障转移并不会在主服务器上导致任何问题。例如,为了升级其中一个主节点的Redis进程,最好将其故障转移,以便将其转变为一个对可用性影响最小的从服务器。   Redis Cluster使用CLUSTER FAILOVER命令支持手动故障转移,该命令必须在要故障转移的主服务器的一个从服务器上执行。   手动故障转移是比较特殊的,并且与实际主控故障导致的故障转移相比更安全,因为它们是以避免数据丢失的方式发生,只有在系统确定新主服务器节点处理完全部来自旧主服务器节点的复制流后才将客户从原始主服务器节点切换到新主服务器节点。   这是您在执行手动故障转移时在从服务器节点的日志中看到的内容:

代码语言:javascript复制
         #接受用户的手动故障转移请求。
         #已暂停的主服务器手动故障转移接收复制的偏移量:347540
         #处理所有主服务器节点的复制流,手动故障转移可以开始。
         #选举开始延迟0毫秒(等级#0,偏移量347540)。
         #为epoch 7545启动故障转移选举。
         #故障转移选举胜出:我是新主人。

          # Manual failover user request accepted.
         # Received replication offset for paused master manual failover: 347540
         # All master replication stream processed, manual failover can start.
         # Start of election delayed for 0 milliseconds (rank #0, offset 347540).
         # Starting a failover election for epoch 7545.
         # Failover election won: I'm the new master.

  基本上连接到我们正在故障转移的主服务器节点上的客户端都已停止工作。与此同时,主服务器节点将其复制偏移量发送给从服务器节点,该从服务器节点将等待达到其侧面的偏移量。当达到复制偏移量时,将启动故障转移,并向旧主服务器通知配置开关。 当旧主服务器节点上的客户端被解锁时,它们会被重定向到新主服务器。

0 人点赞