• Redis—听说你速度跟甲斗一样快?——cluster


    我们紧接上文,现在你使用了哨兵机制架构,业务的性能又上升了一个新的高度
    在这里插入图片描述
    你的Redis从最简单的只有一台实例,经过数据持久化机制、主从复制架构,再到哨兵架构,其性能和稳定性都越来越高,就算节点发生故障,也不用担心了。

    基于哨兵架构,你的Redis基本上可以稳定运行很长一段时间了,随着时间的发展,你的业务流量迎来了爆炸式的增长,此时你的架构还能够承担这么大的流量吗?

    我们思考一下:

    • Redis节点故障宕机,我们有哨兵+slave,可以实现主从自动切换
    • 大量读请求,我们有多个slave节点来分担压力,就算不够我们还可以增加多台slave
    • 大量写请求,由于只有一台msater,而且只有master才能够提供写服务,所以master容易出现写性能瓶颈

    问题出现了,当有大量的写请求时,你的架构只有一个msater能够提供服务,很有可能无法承担那么大的写流量

    要想完美的解决这个问题,Redis第三个架构随之而来——分片集群(cluster)

    cluster

    • redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容
    • 优点:将Redis的写操作分摊到了多个节点上,提高写的并发能力,扩容简单
    • 缺点:每个Node承担着互相监听、高并发数据写入、高并发数据读出,工作任务繁重

    特点:

    • 高性能可拓展:可支持拓展到1000个节点,多个节点之间数据分片,采用异步复制模式完成主从同步,无代理方式完成重定向
    • 可用性:具有自我故障检测、故障转移的特点
    • redis cluster集群是为了降低主节点的压力,主主节点之间是不存在同步关系的,各主从之间的数据存在同步关系。有多少主节点,就会把16384个哈希槽(hash slot)平均分配到这些主节点上,当往redis里写入数据时,会根据哈希算法(CRC16(KEY)%16384)算出这个数的哈希槽来决定它放到哪一个主节点上,然后这个主节点的从节点去自动同步。在客户端随便连接一个主节点即可,主节点之间会进行内部跳转。当取对应数据时,各节点之间会自动跳转到所取数据所在的主节点上
    • 多主多从,去中心化:从节点作为备用,复制主节点数据,不提供服务

    1.cluster节点之间如何通信?

    在这里插入图片描述
    Redis集群中,节点之间通过建立TCP连接,使用gossip协议来传播集群的信息(节点通信端口=服务端口+10000)

    所谓gossip协议,指的是一种消息传播的机制,类似人们传递八卦消息似的,一传十,十传百,直至所有人都知道这条八卦内容。Redis集群中各节点之间传递消息就是基于gossip协议,最终达到所有节点都会知道整个集群完整的信息。

    gossip协议有4种常用的消息类型:PING、PONG、MEET、FAIL

    • MEET:当需要向集群中加入新节点时,需要集群中的某个节点发送MEET消息到新节点,通知新节点加入集群。新节点收到MEET消息后,会回复PONG命令给发送者(redis5.0后 用add-node命令来添加节点)。
    • PING:集群内每个节点每秒会向其他节点发送PING消息,用来检测其他节点是否正常工作,并交换彼此的状态信息。PING消息中会包括自身节点的状态数据和其他部分节点的状态数据。
    • PONG:当接收到PING消息和MEET消息时,会向发送发回复PONG消息,PONG消息中包括自身节点的状态数据。节点也可以通过广播的方式发送自身的PONG消息来通知整个集群对自身状态的更新。
    • FAIL:当一个节点判定另一个节点下线时,会向集群内广播一个FAIL消息,其他节点接收到FAIL消息之后,把对应节点更新为下线状态。

    2.cluster如何实现数据分片

    在cluster中,规定了数据和实例的对应规则——采用哈希槽(hash slot),来处理数据和实例之间的映射关系

    在cluster中,一个切片集群共有16384个哈希槽(2^14),这些哈希槽类似于数据分区,每个键值对都会根据它的key,被映射到一个hash槽中

    • 每当我们通过Redis Cluster对某个key执行操作时,接收请求的节点会首先对key执行计算,得到该key对应的哈希槽,然后再从哈希槽与节点的映射关系中找到负责该哈希槽的节点。如果是节点自身,则直接进行处理;如果是其他节点,则通过重定向告知客户端连接至正确的节点进行处理
    • 每个Node被平均分配了一个Slot段,对应着0-16384,Slot不能重复也不能缺失,否则会导致对象重复存储或无法 存储。
    • Node之间也互相监听,一旦有Node退出或者加入,会按照Slot为单位做数据的迁移。例如Node1如果掉线了,0- 3276这些Slot将会平均分摊到Node2和Node3上,由于Node2和Node3本身维护的Slot还会在自己身上不会被重新分配,所以迁移过程中不会影响到3277-16384 Slot段的使用
      在这里插入图片描述
      为集群分配哈希槽
    #将槽 0 ~ 槽5000 指派给 给 7001 :
    127.0.0.1:7001> CLUSTER ADDSLOTS 0 1 2 3 4 ... 5000
    
    #将槽 5001 ~ 槽10000 指派给 给 7002 :
    127.0.0.1:7002> CLUSTER ADDSLOTS 5001 5002 5003 5004 ... 10000
    
    #将槽 10001~ 槽 16383 指派给 给 7003 :
    127.0.0.1:7003> CLUSTER ADDSLOTS 10001 10002 10003 10004 ... 16383
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    通过哈希槽,就实现了数据到哈希槽,哈希槽再到实例的分配

    但客户端如何知道要访问的数据在哪个实例上呢?

    3.如何定位数据在哪个节点?

    一般来说,客户端和集群实例建立连接后,实例就会把哈希槽的分配信息发给客户端。但是,在集群刚刚创建的时候,每个实例只知道自己被分配了哪些哈希槽,是不知道其他实例拥有的哈希槽信息的

    Redis 实例会把自己的哈希槽信息发给和它相连接的其它实例,来完成哈希槽分配信息的扩散。当实例之间相互连接后,每个实例就有所有哈希槽的映射关系了
    
    • 1

    客户端收到哈希槽信息之后,会把哈希槽信息缓存到本地,当客户端请求键值对时,会先计算键所对应的哈希槽,然后就可以给相应的实例发送请求了

    当客户端向节点请求键值对时,接收命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己

    如果键所在的槽刚好指派给了当前节点,那么节点会直接执行这个命令;
    如果没有指派给当前节点,那么节点会向客户端返回一个 MOVED 错误,然后重定向(redirect)到正确的节点,并再次发送之前待执行的命令
    
    • 1
    • 2

    在这里插入图片描述
    节点通过以下算法来定义 key 属于哪个槽:

    crc16(key,keylen) & 0x3FFF;
    crc16:用于计算 key 的 CRC-16 校验和
    0x3FFF:换算成 10 进制是 16383
    & 0x3FFF:用于计算出一个介于 0~16383 之间的整数作为 key 的槽号。
    
    • 1
    • 2
    • 3
    • 4

    查看key属于哪个槽

    127.0.0.1:7001> CLUSTER KEYSLOT <KEY>
    
    • 1
    比如:MOVED 10086 127.0.0.1:7002 表示,客户端请求的键值对所在的哈希槽 10086,实际是在 127.0.0.1:7002 这个实例上。
    
    通过返回的 MOVED 命令,就相当于把哈希槽所在的新实例的信息告诉给客户端了。
    
    这样一来,客户端就可以直接和 7002 连接,并发送操作请求了。
    
    同时,客户端还会更新本地缓存,将该槽与 Redis 实例对应关系更新正确
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    当集群中的实例有新增或删除,redis需要重新分配哈希槽;为了负载均衡,redis需要把哈希槽在所有实例上重新分布一遍,而且分片过程中不需要下线

    但这样会造成:当客户端有操作键值对的有关的命令,同时该键值对正好属于被迁移槽。并且被迁移槽的部分键值对还驻留在source节点中,另外部分键已经保存在target节点中;则会进行下列动作:

    - 如果能在source节点找到对应的key,那么直接执行client的命令;
    - 如果找不到该key,那很有可能就在target中,此时source节点会向client发送一个ASK错误,引导client转向正在导入槽的target节点,并再次发送之前想要执行的命令。
    
    • 1
    • 2

    ASK 和 MOVED 的区别

    ASK 错误和 MOVED 错误都会导致客户端重定向,它们的区别在于:
    1.MOVED 错误代表槽的负责权已经从一个节点转移到了另一个节点:在客户端收到关于槽 n 的 MOVED 错误之后,客户端每次遇到关于槽 n 的命令请求时,都可以直接将命令请求发送至 MOVED 错误指向的节点,因为该节点就是目前负责槽 n 的节点
    
    2.而 ASK 只是两个节点迁移槽的过程中的一种临时措施:在客户端收到关于槽 n的 ASK 错误之后,客户端只会在接下来的一次命令请求中将关于槽 n 的命令请求发送到 ASK 错误指向的节点,但是 ,如果客户端再次请求槽 n 中的数据,它还是会给原来负责槽 n 的节点发送请求
    
    3.ASK 命令的作用只是让客户端能给新实例发送一次请求,而且也不会更新客户端缓存的哈希槽分配信息。而不像 MOVED 命令那样,会更改本地缓存,让后续所有命令都发往新实例
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.如何实现高可用

    • 故障检测
      集群中每个节点都会定期向集群中的其他节点发送ping消息,以此检测对方是否在线
      如果接受ping消息的节点没有在规定时间内返回pong消息,那么发送PING消息的节点就会将PING消息节点标记为疑似下线(possible fail,PFAIL)

    如果集群中超过半数以上的主节点都将某个节点X标记为PFAIL,则某个主节点就会将这个主节点X标记为下线(FAIL),并广播这条消息

    • 故障转移
      一个节点成为从节点后,就会告诉集群中其他节点自己正在开始复制所主节点

    当一个从节点发现自己所主节点下线时,就会开始进行故障转移
    1.在该下线主节点的所有从节点中,选择一个做主节点
    2.被选中的从节点会执行SLAVEOF no one命令,成为新的主节点
    3.新的主节点会撤销对所有对下线主节点的槽指派,并将这些槽全部派给自己
    4.新的主节点向集群广播一条pong消息,告诉其他节点自己变成了主节点
    5.新主节点开始提供服务,故障转移完成

    5.命令相关

    • 客户端命令
    #集群相关
    redis-cli -c -p 7001 cluster info :打印所有集群的信息
    redis-cli -c -p 7001 cluster nodes :列出集群当前已知的所有节点( node),以及这些节点的相关信息
    
    #节点相关
    redis-cli -c -p 7001 cluster meet <ip> <port> :将节点添加到集群当中,让它成为集群的一份子(随机分配角色。)
    
    redis-cli -c -p 7001 cluster forget <node_id> :从集群中移除 node_id 指定的节点
    
    redis-cli -c -p 7001 cluster replicate <master_node_id> :可以让接受命令的节点成为node_id所指定的从节点,并开始对主节点进行复制
    
    redis-cli -c -p 7001 cluster saveconfig :将节点的配置文件保存到硬盘里面
    
    #哈希槽相关
    redis-cli -c -p 7001 cluster addslots <slot> [slot ...] :将一个或多个槽(slot)指派( assign)给当前节点
    
    redis-cli -c -p 7001 cluster delslots <slot> [slot ...] :移除一个或多个槽对当前节点的指派。
    
    redis-cli -c -p 7001 cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
    
    redis-cli -c -p 7001 cluster setslot <slot> node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派
    
    redis-cli -c -p 7001 cluster setslot <slot> migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中
    
    redis-cli -c -p 7001 cluster setslot <slot> importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点
    
    redis-cli -c -p 7001 cluster setslot <slot> stable :取消对槽 slot 的导入( import)或者迁移( migrate)
    
    #key相关
    redis-cli -c -p 7001 cluster keyslot <key> :计算键 key 应该被放置在哪个槽上
    
    redis-cli -c -p 7001 cluster countkeysinslot <slot> :返回槽 slot 目前包含的键值对数量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 集群命令
    #帮助文档
    redis-cli --cluster help
    
    #集群相关
    redis-cli --cluster create --cluster-replicas 1 <host:port>创建集群
    
    #添加主节点
    redis-cli  --cluster add-node <新主节点host:port>  <集群任意节点host:port>
    
    #添加从节点
    redis-cli  --cluster add-node --slave <从节点host:port>  <主节点host:port> --cluster-slave
    
    #重新分配slot
    redis-cli --cluster reshard <节点host:port>
    
    #平衡新增节点的slot
    redis-cli --cluster rebalance --cluster-use-empty-masters 
    
    #查看集群情况
    redis-cli  --cluster check <节点host:port>
    
    #移除节点(在删除的时候,需要保证节点的hash槽是空的,如果不是空的,需要把hash槽移走)
    redis-cli  --cluster del-node <节点host:port> <节点id>
    
    #查看某一node信息
    redis-cli --cluster info <host:port> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    cluster部署

    master1:192.168.149.128:7001
    master2:192.168.149.129:7001
    master3:192.168.149.130:7001
    slave可以通过cluster命令随机分配给主,slave端口为8001

    在这里插入图片描述

    • 前期准备
      分别在三台服务器上部署
    cp /etc/redis/redis.conf /etc/redis_7001.conf
    cp /etc/redis/redis.conf /etc/redis_8001.conf
    mkdir /var/lib/redis/cluster
    systemctl stop redis-server
    
    • 1
    • 2
    • 3
    • 4
    • 配置文件
      master1和slave1
    #vim /etc/redis_7001.conf
    bind 0.0.0.0
    port 7001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_7001.log
    pidfile /var/redis/redis_7001.pid
    tcp-backlog 511
    tcp-keepalive 300
    timeout 0
    supervised no
    loglevel notice
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb_7001
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    cluster-enabled yes
    cluster-config-file nodes_7001.conf
    cluster-node-timeout 15000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    #vim /etc/redis_8001.conf
    bind 0.0.0.0
    port 8001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_8001.log
    pidfile /var/redis/redis_8001.pid
    tcp-backlog 511
    tcp-keepalive 300
    timeout 0
    supervised no
    loglevel notice
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb_8001
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    cluster-enabled yes
    cluster-config-file nodes_8001.conf
    cluster-node-timeout 15000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    启动redis

    redis-server /etc/redis_7001.conf && redis-server /etc/redis_8001.conf
    
    • 1

    master2和slave2

    #vim /etc/redis_7001.conf
    bind 0.0.0.0
    port 7001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_7001.log
    pidfile /var/redis/redis_7001.pid
    tcp-backlog 511
    tcp-keepalive 300
    timeout 0
    supervised no
    loglevel notice
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb_7001
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    cluster-enabled yes
    cluster-config-file nodes_7001.conf
    cluster-node-timeout 15000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    #vim /etc/redis_8001.conf
    bind 0.0.0.0
    port 8001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_8001.log
    pidfile /var/redis/redis_8001.pid
    tcp-backlog 511
    tcp-keepalive 300
    timeout 0
    supervised no
    loglevel notice
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb_8001
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    cluster-enabled yes
    cluster-config-file nodes_8001.conf
    cluster-node-timeout 15000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    启动redis

    redis-server /etc/redis_7001.conf && redis-server /etc/redis_8001.conf
    
    • 1

    master3和slave3

    #vim /etc/redis_7001.conf
    bind 0.0.0.0
    port 7001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_7001.log
    pidfile /var/redis/redis_7001.pid
    tcp-backlog 511
    tcp-keepalive 300
    timeout 0
    supervised no
    loglevel notice
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb_7001
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    cluster-enabled yes
    cluster-config-file nodes_7001.conf
    cluster-node-timeout 15000vim /etc/redis_7001.conf
    bind 0.0.0.0
    port 7001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_7001.log
    pidfile /var/redis/redis_7001.pid
    cluster-enabled yes
    cluster-config-file nodes_7001.conf
    cluster-node-timeout 15000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    #vim /etc/redis_8001.conf
    bind 0.0.0.0
    port 8001
    daemonize yes
    protected-mode no
    dir /var/lib/redis/cluster
    logfile /var/log/redis/redis_8001.log
    pidfile /var/redis/redis_8001.pid
    tcp-backlog 511
    tcp-keepalive 300
    timeout 0
    supervised no
    loglevel notice
    databases 16
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb_8001
    slave-serve-stale-data yes
    slave-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    slave-priority 100
    cluster-enabled yes
    cluster-config-file nodes_8001.conf
    cluster-node-timeout 15000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    启动redis

    redis-server /etc/redis_7001.conf && redis-server /etc/redis_8001.conf
    
    • 1
    • 自动创建集群
    redis-cli --cluster create  --cluster-replicas 1 192.168.149.128:7001 192.168.149.128:8001 192.168.149.129:7001 192.168.149.129:8001 192.168.149.130:7001 192.168.149.130:8001 
    
    --cluster-replicas 1 #master和slave的比例为1:1
    
    • 1
    • 2
    • 3

    cluster会自动为master分配slave,分配后信息如图
    在这里插入图片描述
    也可以进行手动指定

    • 手动配置主节点(系统会自动分配slot,master必须大于等于三个)
    redis-cli --cluster create  --cluster-replicas 0 192.168.149.128:7001 192.168.149.129:7001 192.168.149.130:7001
    
    • 1
    • 手动指定从节点
    redis-cli --cluster add-node 192.168.149.129:8001 192.168.149.128:7001 --cluster-slave 
    
    redis-cli --cluster add-node 192.168.149.130:8001 192.168.149.129:7001 --cluster-slave 
    
    redis-cli --cluster add-node 192.168.149.128:8001 192.168.149.130:7001 --cluster-slave 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 验证
    redis-cli  -c -p 7001
    127.0.0.1:7001> CLUSTER NODES
    db93ccf1d9ec043032b2a5c8a559f0aa0b77377b 192.168.149.129:7001@17001 master - 0 1660126817807 3 connected 5461-10922
    6ebbefdc950de1b003ce49fdf5a6e8e853f4099a 192.168.149.129:8001@18001 slave e88d4393194f8990dfb9f6a958953e8a7a174a55 0 1660126819000 1 connected
    9355eadf652557747690155b8acb2bd5a1fb7a8d 192.168.149.128:8001@18001 slave 8a36ec13af914d629df215bdf97e690167e3b67f 0 1660126818824 5 connected
    8a36ec13af914d629df215bdf97e690167e3b67f 192.168.149.130:7001@17001 master - 0 1660126820857 5 connected 10923-16383
    e88d4393194f8990dfb9f6a958953e8a7a174a55 192.168.149.128:7001@17001 myself,master - 0 1660126820000 1 connected 0-5460
    eef9afb0222d6fc66bceddd1e95eaee64f2c4eb7 192.168.149.130:8001@18001 slave db93ccf1d9ec043032b2a5c8a559f0aa0b77377b 0 1660126820000 3 connected
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可以看到192.168.149.128:7001是主,192.168.149.129:8001是其从

    #在192.168.149.128:7001 写入数据
    [root@master ~]# redis-cli -c -p 7001
    127.0.0.1:7001> set name python
    -> Redirected to slot [5798] located at 192.168.149.129:7001
    OK
    
    #在192.168.149.129:8001查看
    [root@slave1 ~]# redis-cli -c -p 8001
    127.0.0.1:8001> get name
    -> Redirected to slot [5798] located at 192.168.149.129:7001
    "python"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.缩容案例

    创建了四台master两台slave,打算将其中一台master(192.168.149.128:8001)转换成slave,变成三主三从架构

    #master:
    192.168.149.128:7001
    192.168.149.128:8001
    192.168.149.129:7001
    192.168.149.130:7001
    
    
    #slave:
    192.168.149.129:8001
    192.168.149.130:8001
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    将192.168.149.128:8001上的哈希槽(12288-16383)全部分配给192.168.149.128:7001

    redis-cli --cluster reshard 192.168.149.128:7001
    
    • 1

    在这里插入图片描述
    分配结束后把192.168.149.128:8001删除

    redis-cli --cluster del-node 192.168.149.128:8001 caf9fbac8c701d6030f91fc2273a16e065808de7
    
    • 1

    现在只有三台主,我们添加从节点,每台主分配一台从

    redis-cli --cluster add-node 192.168.149.129:8001 192.168.149.128:7001 --cluster-slave 
    
    redis-cli --cluster add-node 192.168.149.130:8001 192.168.149.129:7001 --cluster-slave 
    
    redis-cli --cluster add-node 192.168.149.128:8001 192.168.149.130:7001 --cluster-slave 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    再将哈希槽重新平均分配一下

    redis-cli --cluster rebalance 192.168.149.128:7001
    
    • 1

    验证

    #在192.168.149.129:7001写数据
    [root@minion1 ~]# redis-cli -c -p 7001
    127.0.0.1:7001> set age 18
    -> Redirected to slot [741] located at 192.168.149.128:7001
    OK
    
    #重定向到192.168.149.128:7001了。而192.168.149.128:7001的从是192.168.149.129:8001
    192.168.149.129:8001> get age
    -> Redirected to slot [741] located at 192.168.149.128:7001
    "18"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.扩容案例

    将192.168.149.128:8001转换成master,然后分配slot

    #master:
    192.168.149.128:7001
    192.168.149.129:7001
    192.168.149.130:7001
    
    
    #slave:
    192.168.149.129:8001
    192.168.149.130:8001
    192.168.149.128:8001
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    删除192.168.149.128:8001

    redis-cli --cluster del-node 192.168.149.128:8001 caf9fbac8c701d6030f91fc2273a16e065808de7
    
    • 1

    增加192.168.149.128:8001为主节点

    redis-cli --cluster ass-node 192.168.149.128:8001 192.168.149.128:7001
    
    • 1

    这时候128:8001还没有被分配slot,重新分配一下

    #重新平均分配slot
    redis-cli --cluster rebalance --cluster-use-empty-masters  192.168.149.128:8001
    
    • 1
    • 2
  • 相关阅读:
    【JVM篇】什么是运行时数据区
    智能时代的“发动机升级”:数据中心十年之变
    【原创】MybatisPlus调用原生SQL的三种方法
    什么是畏缩型性格?如何改变畏缩型性格?
    Java代码规范
    【SimpleFunction系列二】渐进式理解Redis分布式锁
    单片机——软件部分开发过程介绍
    Nacos——Distro一致性协议
    【vue】axios封装拦截
    java 企业工程管理系统软件源码 自主研发 工程行业适用
  • 原文地址:https://blog.csdn.net/s_alted/article/details/126465806