Redis——cluster集群

Redis——cluster集群redis集群配置

大家好,欢迎来到IT知识分享网。

redis集群模式用来解决单redis数据量瓶颈,并且不再需要配置单独的哨兵,可故障转移和水平扩展;

集群将key通过crc16运算后与16384取模,将key分布到固定16384个槽位(slot)中的一个(0-16383),每个redis分别保管不同的槽位,并且集群模式默认使用db0不支持select别的db;(每个redis分配的slot可自动平衡,也可手动分配或按比重分配;计算slot的key还有个hash tags的注意点,如果key中包含{后面也有}对应并且第一个{和第一个}中间包含一个或多个字符,这样计算slot的时候只会计算第一个{和第一个}中间的值,可以将一批key分到同一个slot中,利于批量操作命令和故障问题查找)

官方文档:Redis cluster tutorial – Redis、Redis Cluster Specification – Redis

有关cluster的redis.conf配置:(更新至v7.0.2版本)

  • cluster-enabled yes

开启集群模式,普通模式启动的redis无法加入集群,必须以集群的方式启动redis;(启动redis后,日志打印redis标志的右侧会显示当前redis版本、32或64位、启动模式、端口、pid等信息)

  • cluster-config-file nodes-6379.conf

设置集群配置的名字,每个集群节点都有一个集群配置,该配置是redis自动创建修改的,每个节点集群配置的名字应该唯一;

  • cluster-node-timeout 15000

设置节点故障超时(毫秒),其他的时间限制基本为该设置的倍数;

  • cluster-port 0

设置集群总线监听的入站端口,设置为0时,总线端口为命令端口+10000;

  • cluster-replica-validity-factor 10

设置副本有效(可进行故障转移)因子,副本数据太老旧就不会被选为故障转移副本,如果副本与主服务器最后交互时间超过(node-timeout * replica-validity-factor) + repl-ping-replica-period的值,则不会进行故障转移;(因子过大可能更容易使用太旧的数据进行故障转移,因子过小可能无法选择副本进行故障转移,0是唯一可以保证所有分区恢复时集群能够继续运行的值,0值可以保证集群最大可用性)

  • cluster-migration-barrier 1

设置一个master故障转移所需最少的副本个数,由于没有正常工作副本的master无法进行故障转移,当一个master拥有超过该值个副本,就会将多余副本转移给孤立的master,以提高抗故障能力;(默认值是1,因为至少有一个正常工作的副本时才能故障转移,如果要禁用只需设置一个很大的数即可或者设置cluster-allow-replica-migration为no,设置为0只用在调试中,在生产环境中设置0是危险的)

  • cluster-allow-replica-migration yes

关闭此项允许较低要求的自动集群配置;该项可以阻止孤立master进行迁移,也阻止变为空的master进行迁移;(默认“yes”,即允许自动迁移)

  • cluster-require-full-coverage yes

设置集群是否覆盖全槽位,默认集群检测到16384个槽位没有全部覆盖(存在槽位没有正在运行的节点处理),整个集群停止查询服务,也就是整个集群不可用,当槽位再次全部覆盖后,集群自动变为可用,如果需要在槽位没有全覆盖情况下让已覆盖槽位支持查询,只需设置为no即可;

  • cluster-replica-no-failover no

设置是否进行故障转移,如果设置为yes,则将阻止master故障时进行故障转移,但扔可以手动强制进行故障转移;(在一些特定场景下可能用得到)

  • cluster-allow-reads-when-down no

设置允许集群down状态可读(只要节点认为自己拥有槽位);可用于两种情况:一是适用于在应用程序在节点故障或者网络分区时不需要数据一致性的情况(例如缓存),二是适用于不满足三个分片集群但又需要开启集群后面进行扩展的情况;(不启用该配置时1或2个分片配置的集群里一个master停止服务会导致整个集群读写停止,开启该配置只会停止写服务;达不到master的quorum数,槽位所有权不会自动改变)

  • cluster-allow-pubsubshard-when-down yes

设置允许集群down状态可以发布分片信息(只要节点认为自己拥有槽位);当应用程序想要在集群状态不是ok时使用订阅发布特性,设置yes是很有用的;如果应用程序确保只有一个分片服务特定通道,这个设置应保持yes;

  • cluster-link-sendbuf-limit 0

设置单个集群总线连接的发送字节缓冲区的内存使用限制,超过限制缓冲区将被清空(主要为了防止发送缓冲区发送给慢速连接时无限延长时间的问题);默认禁用,当“CLUSTER LINKS”命令输出中“mem_cluster_links”信息或者“send-buffer-allocated”元素不断增加时应启用该设置;建议最小设置1gb,这样默认情况下集群连接缓冲区可以容纳至少一个subpub消息(client-query-buffer-limit默认是1gb);

  • cluster-announce-hostname “”

配置集群宣布的主机名;主要用于需要TLS服务名称信息(SNI)的应用或者依靠DNS路由的应用;该值通过集群总线与全部节点交互,设置为空字符串将移除主机名;

  • cluster-preferred-endpoint-type ip

设置告诉客户端使用何种方式连接集群(IP地址、用户自定义主机名、声明没有端点);可以设置为“ip”、“hostname”、“unknown-endpoint”,用于控制MOVED/ASKING请求的返回和CLUSTER SLOTS的第一个字段(如果指定了hostname但没有公布主机名,则会返回“?”);

当一个集群宣布了自己拥有unknown-endpoint时,表示集群不知道客户端如何连接到集群,这种情况发生在某些网络环境下,发生在有多条路由到节点,但不知道客户端使用了哪条时,这种情况下,服务器希望客户端使用跟最后一次请求用过的相同的端点,但是使用响应中提供的端口;

  • cluster-announce-ip 10.1.1.5
  • cluster-announce-tls-port 6379
  • cluster-announce-port 0
  • cluster-announce-bus-port 6380

以上三项设置对NAT网络或者Docker的支持,以便自动发现机制有效;(如果cluster-tls设置yes并且不设置cluster-announce-tls-port或者设置为0,则cluster-announce-port被当作TLS端口,如果cluster-tls设置no则cluster-announce-tls-port设置无效)(不设置bus-port默认使用客户端端口+10000的固定偏移,所以防火墙那块集群端口需要关注两个:一个普通端口供客户端访问,一个总线端口供集群节点访问)

在redis5.0之后取消了redis-trib.rb脚本的支持,也就是说不再需要自己安装ruby了(非常好),将功能直接搬到了redis-cli里了,直接使用redis-cli –cluster就可以搭建和管理集群;

redis-cli –cluster的help:(v7.0.2版本)

[centos@localhost bin]$ ./redis-cli --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN		创建集群
                 --cluster-replicas <arg>		指定每个主节点的副本节点个数
  check          host:port				检查集群
                 --cluster-search-multiple-owners	检查集群同一个槽位是否被分给多个节点
  info           host:port				显示集群信息
  fix            host:port				修复集群
                 --cluster-search-multiple-owners	修复同一个槽位分给多个节点的问题
                 --cluster-fix-with-unreachable-masters
  reshard        host:port				迁移槽位
                 --cluster-from <arg>			指定源节点,多个用逗号隔开,参数为nodeid,参数可指定all,不设置该项会交互式询问
                 --cluster-to <arg>			指定一个目标节点,参数为nodeid,不设置该项会交互式询问
                 --cluster-slots <arg>			指定迁移槽位数量,不设置该项会交互式询问
                 --cluster-yes				设定交互式的时候自动回复yes
                 --cluster-timeout <arg>		迁移超时时间
                 --cluster-pipeline <arg>		指定cluster getkeysinslot一次返回的数量(默认10个)
                 --cluster-replace			直接复制到目标节点(没发现有啥明显作用)
  rebalance      host:port				重新平衡节点槽位
                 --cluster-weight <node1=w1...nodeN=wN>	指定节点槽位权重
                 --cluster-use-empty-masters		指定可以使用未分配槽位的主节点(默认忽略0槽位主节点)
                 --cluster-timeout <arg>		指定超时时间
                 --cluster-simulate			仅模拟平衡槽位操作,实际数据无影响
                 --cluster-pipeline <arg>		指定cluster getkeysinslot一次返回的数量(默认10个)
                 --cluster-threshold <arg>		设定进行重新平衡槽位的阈值
                 --cluster-replace
  add-node       new_host:new_port existing_host:existing_port	添加新节点(默认是主节点)
                 --cluster-slave				指定添加的是副本节点,自动分配主节点
                 --cluster-master-id <arg>		为添加的副本节点指定主节点
  del-node       host:port node_id			删除节点,并关闭该redis
  call           host:port command arg arg .. arg	在集群所有节点执行相同命令
                 --cluster-only-masters
                 --cluster-only-replicas
  set-timeout    host:port milliseconds		同配置文件的cluster-node-timeout
  import         host:port				将非集群redis数据导入集群
                 --cluster-from <arg>			指定外部redis
                 --cluster-from-user <arg>
                 --cluster-from-pass <arg>
                 --cluster-from-askpass
                 --cluster-copy
                 --cluster-replace
  backup         host:port backup_directory
  help           

For check, fix, reshard, del-node, set-timeout, info, rebalance, call, import, backup you can specify the host and port of any working node in the cluster.

Cluster Manager Options:
  --cluster-yes  Automatic yes to cluster commands prompts

 (注意最后的说明:check, fix, reshard, del-node, set-timeout, info, rebalance, call, import, backup的host:port参数可以使用集群里的任何一个节点)

测试实验:

虚拟机ip:192.168.1.31,6个redis的端口8001-8006(3主3从)(3主或4主允许宕机1主,5主或6主允许宕机2。。。);

配置8001的redis.conf:

        bind 192.168.1.31        配置ip

        port 8001        配置端口

        pidfile “/var/run/redis_8001.pid”        配置pidfile(虽然没开启daemonize)

        masterauth 654321        配置master的密码

        requirepass 654321        配置自己的密码

        appendonly yes        开启aop(我关闭了rdb)

        cluster-enabled yes        配置开启cluster模式(必须以该模式启动)

        cluster-config-file nodes-8001.conf        配置cluster-node

其他8002-8006配置按照8001相关配置即可;

以cluster模式启动6个redis服务:

Redis——cluster集群

 然后使用redis-cli –cluster create将这6个redis创建成为集群:(-a指定密码,并使用–cluster-replicas指定每个主节点有一个副本节点(由redis自动分配的),不指定则全为主节点,集群主最少要3个,每个主节点带一个副本节点所以最少需要6个redis实例)

./redis-cli -a 654321 –cluster create 192.168.1.31:8001 192.168.1.31:8002 192.168.1.31:8003 192.168.1.31:8004 192.168.1.31:8005 192.168.1.31:8006 –cluster-replicas 1

Redis——cluster集群

 然后输入yes确认redis给分配的主从关系:

Redis——cluster集群

 这样redis集群就建立完毕了;

使用./redis-cli –cluster check可以检查集群:(8001,8002,8003为主节点,各带一个副本节点)

./redis-cli -a 654321 –cluster check 192.168.1.31:8001

Redis——cluster集群

 使用./redis-cli连接集群里任何一个redis存取数据:(-a指定密码,-c指定集群模式)

./bin/redis-cli -a 654321 -c -h 192.168.1.31 -p 8001

Redis——cluster集群

 集群里使用批量操作的key不在同一个slot会抛异常,使用hashtag则比较方便:(使用hashtag会造成数据倾斜,导致数据集中在某个redis里)

Redis——cluster集群

 可以使用测试的keys命令查看本redis的所有key:(只会展示本redis的所有key)

Redis——cluster集群

 可以看到相同hashtag的key都在一个redis里;

通过–cluster info也可以看到8002里有4个key:

Redis——cluster集群

 关掉8001,默认超时15s后,8001的副本redis8005接替了8001的位置成为了master并管理0-5460的槽位:

Redis——cluster集群

 继续关掉8002集群就会马上停止:

Redis——cluster集群

 然后等8006替换了8002集群就又可以正常运行了:

Redis——cluster集群

 当停掉没有正常slave的master后集群就彻底停掉了(slot没有全覆盖,默认需要全覆盖),需要重新启动宕机的主redis才能使集群自动恢复,例如关掉8005(此时8005没有slave了),不管等待多久集群都无法自动恢复:

Redis——cluster集群

 将副本8001启动是无效的:(8001只会去同步不存在的8005):

Redis——cluster集群

 只有启动主8005才可以时集群恢复:(为了减少影响我关了刚起的8001)

Redis——cluster集群

 将8001和8002都启动,8001成为8005的副本,8002成为8006的副本:

Redis——cluster集群

 再以cluster模式启动另外两个redis实例8007,8008,使用add-node加入到集群里:

./redis-cli -a 654321 –cluster add-node 192.168.1.31:8007 192.168.1.31:8001

Redis——cluster集群

 默认添加的是主节点,并且是没有分配slot的主节点:

Redis——cluster集群

 将8008作为指定8007的副本节点加入集群:(使用–cluster-slave指定作为副本节点加入集群,使用–cluster-master-id指定作为主节点的id,不指定主节点则由集群自动分配主节点)

./redis-cli -a 654321 –cluster add-node 192.168.1.31:8008 192.168.1.31:8001 –cluster-slave –cluster-master-id ce2e7d2b05fb0edc2347bbcbcdd0b778e95f4f10

Redis——cluster集群

 变成了4主4从,但是8007是没有分配slot的:

Redis——cluster集群

 多添加点测试数据:

Redis——cluster集群

Redis——cluster集群

 可以使用rebalance自动平衡slot的分配,并使用–cluster-use-empty-masters将0lost的主节点也加入分配,还可以用–cluster-weight指定slot分配的权重(使用的是node的id,默认权重都是1):

./redis-cli -a 654321 –cluster rebalance 192.168.1.31:8001 –cluster-use-empty-masters –cluster-replace

Redis——cluster集群

 每个主节点都分配了4096个slot:(8007从8003,8005,8006中各分配一部分slot)

Redis——cluster集群

Redis——cluster集群

 也可以使用reshard手动迁移slot,例如使用交互式命令将8007的2000个slot迁移到8003中:

./redis-cli -a 654321 –cluster reshard 192.168.1.31:8001

Redis——cluster集群

输入各种必须参数,最后输入yes,过一会就迁移完了:

Redis——cluster集群

Redis——cluster集群

Redis——cluster集群

 迁移后的slot分配:

Redis——cluster集群

 也可以使用参数直接指定,就可以不通过交互式迁移数据:

./redis-cli -a 654321 –cluster reshard 192.168.1.31:8001 –cluster-from ce2e7d2b05fb0edc2347bbcbcdd0b778e95f4f10 –cluster-to 997203098886bcd76c5ae53f41cf027408b67819 –cluster-slots 2096 –cluster-yes –cluster-replace

这样就把8007的全部slot迁移到8003中了(0slot的8007的副本8008也自动挂到了8003下面)

Redis——cluster集群

 可以删除0slot的8007了:(8007会自动关掉,非0slot主节点无法移除)

./redis-cli -a 654321 –cluster del-node 192.168.1.31:8001 ce2e7d2b05fb0edc2347bbcbcdd0b778e95f4f10

Redis——cluster集群

 副本节点8008可以随便删掉:(8008也会自动关掉)

./redis-cli -a 654321 –cluster del-node 192.168.1.31:8001 5b2ad9bd6dd0b88a64e1dab57522fc8a0ac1668f

Redis——cluster集群

 此时集群状态:

Redis——cluster集群

 启动删掉的主节点8007,直接手动添加到集群是失败的:

Redis——cluster集群

 (但此时通过8007可以查看到集群信息,通过正常的集群查不到8007)

需要登录8007后将8007清空(如果有数据要flushall)重置才可以重新添加到集群:

Redis——cluster集群

Redis——cluster集群

Redis——cluster集群

 重启关掉的副本节点8008,可以继续同步之前主节点的数据,但状态跟8007一样,通过正常的集群查不到,通过自己可以查看到自己在集群里;

同样也需要清空重置8008才能正常加入到集群里:

(应谨慎使用cluster reset。。。刚在8008里试了一下–cluster call cluster reset,导致所有节点都变主节点了。。。原以为集群不会受集群不识别的redis实例影响)

Redis——cluster集群

Redis——cluster集群

 然后删掉8001,8002,8004,8008节点:

Redis——cluster集群

Redis——cluster集群

 然后把其他作为副本节点重新加入集群:(分别flushall和cluster reset)

./redis-cli -a 654321 –cluster add-node 192.168.1.31:8001 192.168.1.31:8003 –cluster-slave

./redis-cli -a 654321 –cluster add-node 192.168.1.31:8002 192.168.1.31:8003 –cluster-slave

./redis-cli -a 654321 –cluster add-node 192.168.1.31:8004 192.168.1.31:8003 –cluster-slave

./redis-cli -a 654321 –cluster add-node 192.168.1.31:8008 192.168.1.31:8003 –cluster-slave

最后集群状态:

Redis——cluster集群

关于客户端登录集群后,跟CLUSTER相关的命令:(部分命令需谨慎使用)(更新至v7.0.2版本)

  • ASKING

收到ask重定向时,由集群客户端自动发送的ask命令;返回OK;

  • CLUSTER ADDSLOTS slot [slot …]

给节点分配新的槽位;(槽位必须是未分配的,重复分配slot返回错误,被成功分配的slot如果之前被指定为importing状态则会清除导入状态)

通常用来为新的集群分配slot或者用来修复未分配的slot;通常用在redis-cli中,在正确的上下文中使用该命令可能导致集群状态异常或数据丢失;

成功返回“OK”字符串,失败返回错误;

  • CLUSTER ADDSLOTSRANGE start-slot end-slot [ start-slot end-slot …]

(v7.0.0)给节点分配新的槽位,类似ADDSLOTS,不过该命令分配的是槽位区间;

  • CLUSTER BUMPEPOCH

推进配置纪元;如果节点的epoch为0或者比集群最大的epoch小则会增加epoch;

(配置epoch是集群自动管理的,依靠节点一致意见,该命令会直接跳过一致意见影响epoch,违反“last failover wins”原则,应谨慎使用)

epoch增加了返回BUMPED,已经拥有集群最大epoch则返回STILL;

  • CLUSTER COUNT-FAILURE-REPORTS node-id

查询节点失败报告的数量(未过期的失败报告,并且是来自其他节点的错误报告);

(节点超时时间超过配置的超时时间后,会给超时节点标记PFAIL状态,并在心跳包中发布该信息;节点收到其他节点公布的PFAIL信息也会创建错误报告记录一个节点标记了另一个节点PFAIL状态;错误报告超时时间是节点超时时间的两倍;如果给定时间内大部分节点都认为超时节点为PFAIL状态,则会将该节点的PFAIL状态改为FAIL状态并发布给其他节点,让其他节点的标记也改为FAIL)

该命令通常用于调试,当集群的失败检测异常时;

  • CLUSTER COUNTKEYSINSLOT slot

返回指定slot的key数量(只限于本节点里的);

  • CLUSTER DELSLOTS slot [slot …]

在当前节点上将指定slot设定为未绑定状态;该命令让节点忘记哪个master拥有这个slot,拥有未绑定slot的节点如果收到别的声称拥有这些slot的节点的心跳包,就会立即建立slot的联系,如果收到更高epoch节点的心跳或更新消息联系会重新建立;

(该命令只能用于跟某些节点有联系的slot,多次调用相同的slot命令将失败,该命令导致的slot未全覆盖可能会使集群停止)

成功返回“OK”字符串,失败返回错误;

  • CLUSTER FAILOVER [FORCE|TAKEOVER]

强制副本进行手动故障转移;该命令只能发给副本,通常使用在没有发生故障但又希望主从安全交换(不丢数据)的时候;

FORCE选项:主服务关闭的时候进行手动故障转移;(副本不与主服务握手,直接开始故障转移,但仍需要大多数节点同意授权故障转移)

TAKEOVER选项:不需要集群一致的手动故障转移;一般用于当全部master关机或分区时,为了在不同数据中心间进行数据中心切换,将集群副本提升为master(包含FORCE选项所包含的所有内容,并且不需要集群授权;TAKEOVER违反last-failover-wins协议,epoch不是正常增加的,应谨慎使用)

命令被接受并企图进行故障转移返回OK字符串(不能保证故障转移成功),否则返回错误;

  • CLUSTER FLUSHSLOTS

删除当前节点上的所有slot,只有数据库为空的时候才能调用;

返回OK字符串;

  • CLUSTER FORGET node-id

从当前节点的节点表中删除指定node-id,并通知给其他msater和slave,并将该id加入禁止列表禁止一段时间内(60秒)

(60s的禁止列表是为了:防止刚删除就收到其他节点心跳包关于node-id节点已知的消息,使得该节点又重新添加该删除的id节点到节点表中,这样就有60s的时间告知集群内所有节点我们要删除该节点)

命令执行失败的情况:1.id不在节点表里。2.id正是当前节点的master。3.id正是当前节点。

成功返回OK,否则返回失败;

  • CLUSTER GETKEYSINSLOT slot count

返回指定slot的count个key的列表;

  • CLUSTER INFO

提供集群节点的信息;

  • CLUSTER HELP

(v5.0.0)返回全部命令的帮助信息列表;

  • CLUSTER KEYSLOT key

返回指定key被散列的槽位的值;

  • CLUSTER LINKS

(v7.0.0)返回本节点与集群节点间的连接和属性信息;(集群中每个节点都与其他节点使用一对tcp长连接,一条收一条发)

  • CLUSTER MEET ip port

强制当前节点去指定ip、port的节点进行握手,用于将开启集群支持的不同redis节点加入到一个工作的集群中;(由于节点间的自动发现机制,不需要全部节点都发送CLUSTER MEET命令)

成功返回OK,ip或者port无效返回错误;

  • CLUSTER MYID

返回当前节点的id;

  • CLUSTER NODES

返回节点信息;

每行的格式:<id> <ip:port@cport> <flags> <master> <ping-sent> <pong-recv> <config-epoch> <link-state> <slot> <slot> … <slot>

  1. <id>:节点id,创建节点时生成40个字符的随机字符串;
  2. <ip:port@cport>:节点地址和总线端口;
  3. <flags>:用逗号分割的标记列表(myself, master, slave, fail?, fail, handshake, noaddr, nofailover, noflags)
  4. <master>:如果是子节点并且有已知的master,则为master的id,否则为“-”;
  5. <ping-sent>:被发送的正在进行的ping的unix毫秒值,没有待处理的ping则为0;
  6. <pong-recv>:收到最后一个pong时的unix毫秒值;
  7. <config-epoch>:当前节点(如果当前是子节点,则为主节点的)的epoch;
  8. <link-state>:连接状态(连接或断开);
  9. <slot>:服务的槽位,单个槽位或者槽位区间;(最多能有16384个值)

另外还有两个特殊槽位状态:导入槽位和迁移槽位(只能添加到标记为myself的节点)

导入槽位:[slot_number-<-importing_from_node_id]

迁移槽位:[slot_number->-migrating_to_node_id]

节点flag标记:

  1. myself:当前正在连接的节点
  2. master:主节点
  3. slave:副本节点
  4. fail?:PFAIL状态的节点,当前节点不可达,逻辑上可达(非FAIL状态);
  5. fail:FAIL状态的节点,对多个将PFAIL提升为FAIL的节点不可达;
  6. handshake:不可信节点,正在进行握手;
  7. noaddr:该节点没有已知的地址;
  8. nofailover:副本将不会尝试故障转移;
  9. noflags:没有任何标记;
  • CLUSTER REPLICAS node-id

返回指定主节点node-id的副本信息(返回格式跟CLUSTER NODES一致);

如果id未知,或者根据当前节点的节点表不认为该id是主节点,将返回错误;

(如果主节点正在添加、删除或移动副本,则向还没来得及更新的节点发送该命令可能会获得旧数据(正常情况下几秒钟就会更新节点信息))

  • CLUSTER REPLICATE node-id

将节点重新配置为主节点的副本;(如果当前节点是空的主节点,则会变为副本节点)

副本节点将总会接受该命令,在以下情况:1.id存在于节点表里。2.指定的id没有识别我们所发送命令的这个节点。3.这个id是一个master。

如果接收命令的节点是主节点,只有满足以下情况才会执行命令成功并变为副本节点(然后立即联系主节点进行复制工作):1.节点没有服务于任何slot。2.节点是空的,没有任何key。

成功返回OK,否则返回错误;

  • CLUSTER RESET [HARD|SOFT]

重置一个集群节点,主要用来重新配置集群节点;(不能重置有key的主节点,要重置主节点必须先删除key,例如先使用flushall命令再使用该命令)(默认SOFT)

对节点造成的效果:

  1. 所有其他节点被忘记。
  2. 所有已分配、开放的槽位都被重置,槽位到节点映射全部清空。
  3. 如果节点是一个副本,则会转换为空的主节点,数据集被清空。
  4. 仅HARD模式,生成新的节点id。
  5. 仅HARD模式,变量currentEpoch和configEpoch被重置为0。
  6. 新的配置被记录到硬盘中节点的集群配置文件中。

成功返回OK,否则返回错误;

  • CLUSTER SAVECONFIG

强制节点保存nodes.conf文件;

该命令主要用于由于某些原因nodes.conf文件丢失或被删除,我们又想重新生成配置文件;也可用于将一些CLUSTER命令对集群的改动保存到磁盘的配置文件上;

成功返回OK,否则返回操作失败;

  • CLUSTER SET-CONFIG-EPOCH config-epoch

在新节点中指定一个epoch;(只有节点的节点表为空,节点的epoch为0时该命令才有效)

可以在创建集群前使用该命令对每个节点设置不同的epoch;(新集群创建时,集群配置epoch冲突解决算法可以处理节点具有相同配置的情况,确保最终所有相同配置的节点都会趋于不同)

成功返回OK,否则返回错误;

  • CLUSTER SETSLOT slot IMPORTING|MIGRATING|STABLE|NODE [node-id]

以不同的方式改变节点中槽位的状态;

  1. IMPORTING:将slot设置为迁移状态;
  2. MIGRATING:将slot设置为导入状态;
  3. STABLE:从slot中清除任何IMPORTING、MIGRATING状态;
  4. NODE:将slot绑定到不同节点;

四个模式详解:(slot从源节点source-node迁移到目标节点destination-node)

  1. CLUSTER SETSLOT <slot> MIGRATING <destination-node-id>
    该命令将source-node槽位设置为迁移状态;(接受命令的节点必须拥有该槽位)
  2. CLUSTER SETSLOT <slot> IMPORTING <source-node-id>
    该命令将destination-node槽位设置为导入状态;(接受命令的节点必须不能拥有该槽位)
  3. CLUSTER SETSLOT <slot> STABLE
    清除槽位的迁移或导入状态;(修复由于redis-cli –cluster fix导致的错误状态,正常情况下会在迁移或导入结束时自动调用SETSLOT…NODE…清除状态)
  4. CLUSTER SETSLOT <slot> NODE <node-id>
    将slot跟节点关联起来;是最复杂的命令(仅在特定情况下有用,并且不同的slot状态有不同的作用);
    a.如果接受命令的节点拥有该slot,则会将该slot分配给其他节点,但是如果接受命令的节点中仍有该slot的键命令则会返回错误;
    b.如果slot是迁移状态,分配给其他节点后将清除该状态;
    c.如果slot是导入状态也在接受命令的节点上,并且该命令将这个slot又分配到该节点上,会造成下列效果:首先导入状态会被清除,如果节点的epoch不是集群中最大的则会生成一个新的epoch给自己,这样它的新的slot所有权将超过之前的故障转移或迁移的任何旧配置;
    (只有上面的c情况,才会使集群在不经过其他节点同意的情况下创建新的epoch,只能通过手动配置触发,由于集群的配置纪元冲突算法,不可能给两个节点创建相同配置epoch的非瞬态设置)

(要注意设置导入和迁移的顺序,先在目标节点上做好准备再用源节点迁移)

以上四种命令,成功返回OK,否则返回错误;

  • CLUSTER SHARDS

(v7.0.0)获得槽位到节点的映射关系;

  • CLUSTER SLAVES node-id

列出指定主节点的副本节点;(该命令是为了兼容,请使用新的CLUSTER REPLICAS命令)

(返回格式跟CLUSTER NODES一致)

  • CLUSTER SLOTS

获得槽位到节点的映射列表;

列表每一项数据的格式:

  1. 第一行,slot的开始位置;
  2. 第二行,slot的结束位置;
  3. 第三行,由ip、port、nodeid三小行组成的master信息;
  4. 第四行开始,由ip、port、nodeid三小行组成的上面第三行master的副本信息;
  5. 后面可能有多个副本信息,每行一个副本信息;
  • READONLY

启用集群副本节点的读请求;(通常副本会将请求重定向到自己的主节点,使用READONLY可使副本接受读请求(但可能是旧的数据)并忽略写请求)(开启READONLY时只有当key不在副本主节点服务范围内时才会重定向)

  • READWRITE

禁用集群副本节点的读请求;(默认副本节点是关闭读请求的,该命令可以将READONLY的副本节点恢复为原本的readwrite禁读状态)

也可以查看cluster help的信息:

Redis——cluster集群

 以下是一些小测试的截图:

Redis——cluster集群

Redis——cluster集群

Redis——cluster集群

Redis——cluster集群

 8003拥有slot0,在8005上CLUSTER DELSLOTS 0,8005过会又会知道slot0的联系:(可能是收到了8003拥有slot0的心跳包)

Redis——cluster集群

Redis——cluster集群

 如果在8003上CLUSTER DELSLOTS 0,则集群就停止了:

Redis——cluster集群

Redis——cluster集群

 此时用CLUSTER ADDSLOTS给8003再添加slot0就可以了(给其他节点添加会失败),集群恢复正常:

Redis——cluster集群

Redis——cluster集群

 Redis——cluster集群

 Redis——cluster集群

 Redis——cluster集群

Redis——cluster集群

Redis——cluster集群

 将8008reset,8008变为了master并忘记了集群的信息:Redis——cluster集群

Redis——cluster集群

 将8007由主节点变为8008的副本:

Redis——cluster集群

Redis——cluster集群

 让8008重新去跟集群中的节点握手:

Redis——cluster集群

Redis——cluster集群

 刚注意到8004之前是8007的副本(可能是之前电脑休眠造成的),之前的8008是8006的副本,现在8007变为8008的副本,8004又是8007的副本,8006没有副本了,所以再将8004变为8006的副本:

Redis——cluster集群

Redis——cluster集群

 0slot是在8003上,将0slot迁移到8005上:

先在8005上:

CLUSTER SETSLOT 0 IMPORTING 997203098886bcd76c5ae53f41cf027408b67819

Redis——cluster集群

 在8003上:

CLUSTER SETSLOT 0 MIGRATING b433cdd481538161aa00f2679163c35765f63256

CLUSTER SETSLOT 0 NODE b433cdd481538161aa00f2679163c35765f63256

Redis——cluster集群

Redis——cluster集群

在8005上:

CLUSTER SETSLOT 0 NODE b433cdd481538161aa00f2679163c35765f63256

Redis——cluster集群

Redis——cluster集群

 Redis——cluster集群

 在8003的副本节点8001测试READONLY和READWRITE:(默认是READWRITE并重定向到master)

Redis——cluster集群

Redis——cluster集群

参考:Redis cluster tutorial – Redis

ASKING – Redis

Redis 的主从同步,及两种高可用方式_cute-CSDN博客_redis主从

Redis 5.0 redis-cli –cluster help说明 – jyzhou – 博客园

redis 哨兵+cluster_十点半睡的博客-CSDN博客

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11745.html

(0)
上一篇 2024-03-16 12:33
下一篇 2024-03-21 18:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信