Redis Cluster实践

    Redis Cluster提供了在多个redis实例间数据自动分片(sharded)的特性,同时在partitions之间提供了一定程度的可用性保障,比如一些nodes失效时集群仍可以继续读写操作;不过当集群中较大规模的节点失效会导致集群停止服务,比如多数master失效(majority of masters)。在实用性方面,Redis Cluster能够做到:

    1)在多个nodes间自动切分数据的能力(split)

    2)当部分nodes失效时(或者nodes无法与其他nodes通信时),集群仍然可以继续操作

 

     此外,我们已知Redis Sentinal模块已经支持在Master-Slave架构下自动Failover,当集群规模增大、数据需要sharding时,我们需要采用Cluster架构。

    Redis Cluster在3.0+版本才正式发布,宣称可以支持1000个节点;当然在通常情况下,我们的集群可能在10~20个节点左右,毕竟节点越多其复杂度越大,维护成本越高。Redis Cluster中涉及到节点自动发现、failover、slave自动迁移等机制,基于gossip协议和普通的选举算法,并没有使用额外的服务协调组件,不过Cluster中所有的节点都需要彼此建立连接(full mesh)。

 

    对于客户端应用而言,只需要声明集群的部分节点即可,客户端即可与其中一个节点建立连接,即可通过指令获取集群的所有状态信息,所以客户端实现也是非常轻量级的;此后客户端将会缓存集群的信息,这些信息包括nodes与slots的映射关系,那么当客户端需要提交请求时,它能够在客户端(单边)计算此操作应该转发给哪个节点,此后直接与相应的node建立连接并提交请求。所以Redis Cluster机制中,并不存在Proxy层。

  

一、集群TCP端口

    每个redis实例都需要2个TCP端口,其一为服务于客户端的port,通常为6379;另外一个为“Redis Cluster bus”端口,此值为客户端port + 10000,假如客户端port为6379,那么bus端口即为16379,此端口我们无法通过配置来设定。(因为server的最大端口号为65535,所以客户端port不要设置的太大)

    “Cluster bus”端口,用于nodes间通讯,比如“节点失效检测(failure detection)”、配置信息更新(备注:cluster内部的配置信息交换)、failover授权等等。bus端口上采用了封闭的二进制协议,通常客户端无法与bus口交互,同时为了安全起见,我们需要使用防火墙机制,让此端口只对nodes集群有效。

 

二、集群与Docker

    当前Cluster尚不支持NATted环境,在一般环境中IP地址或者port会重新映射(remapped)。Docker使用了一种称为“port mapping”技术:在Docker容器内运行的程序使用的端口,将以另一个端口的方式暴露出去(Docket的宿主环境)。这可以允许一个Server(物理环境)上允许多个Docker容器,而且每个容器内的程序可以使用相同的端口。为了让Redis Cluster与Docker机制兼容,Docker需要使用“host networking mode”,具体信息请参考Dorcker文档。

 

三、集群数据分片机制

    Redis Cluster并没有使用一致性hash机制,但是使用了一种不同的sharding方式:hash slot(哈希槽);Cluster将会分配16384个slot(此值不可修改),对于指定的key,将会对key使用CRC16算法计算出long数值,然后对16384取模,即可得出此key所属的slot。那么集群中每个node都负责一部分slots,比如集群由A、B、C三个节点构成(3个masters):

    1)A中的slots区间为:0~5500

    2)B中的slots区间为:5501~11000

    3)C中的slots区间为:11001~16383

 

    hash slot机制很像存储层面的block,所以在集群中新增、移除nodes将变得简单。比如,我想添加一个新的node D,我只需要将A、B、C中的部分slots迁移到D上即可(而不是对集群中所有的数据重新resharding);同理,如果想移除节点A,只需要将A上的slots迁移到其他节点,此后即可将A从集群中移除。(言外之意,不需要resharding,而且对客户端透明)

    由此可见,hash slots从一个node迁移到另一个node,或者增删节点,都不需要中断用户操作,集群仍可以正常服务。

 

    我们知道Redis支持“multiple key”操作(即多个key的数据在一次调用中返回),那么Cluster也支持此特性,但是要求所有的keys需要在一个hash slot上(即在同一个node上),为了确保多个keys所属与同一个slot,则要求使用“hash tags”。

 

    “hash tags”:Redis Cluster支持的特性,在key字符串中如果包含"{}",那么“{}”之间的字符串即为“hash tags”,客户端(包括Server端)将根据“hash tags”来计算此key所属的slots,而不是key完整的字符串,当然存储仍使用key。所以,有了“hash tags”,我们可以强制某些keys被保存在相同的slots:比如,“foo”和“{foo}.another”将会保存同一个slot上。这对“multiple key”操作非常有帮助。

 

四、集群节点的主备模式

    当部分masters节点失效或者无法与大多数节点通讯时,为了能够保持集群的有效性,Redis Cluster通常使用Master-Slave模式,即一个Master节点通常需要一个或者多个slaves,通过replicas方式来提高可用性。

    比如上例中的三个节点,如果B失效,那么集群将无法继续提供服务,因为“5501~11000”区间的slots完全“丢失”了。为了避免这种情况,我们通常需要为每个Master增加至少一个slave。比如A1、B1、C1分别为A、B、C的slave节点,那么当B失效时,B1可以被提升为master,接管B的服务,从而集群仍然可以继续操作。(不过,此后如果B1也失效,集群将不可用)

    从集群的整体架构拓扑可知,Cluster并没有统一的Primary节点,也不存在所谓的集群单点问题。

 

  

五、数据一致性

    Redis Cluster不能保证“强一致性”(strong consistency),即在实际使用中,某些情况下已经writes成功的数据(已经向客户端确认成功的)可能会丢失。

    第一个原因就是Master与slaves之间采用异步复制的方式,这意味着那些在master上写入成功但尚未replicas到slave时,如果master失效,也意味着这些writes数据丢失了。

    1)Client向A提交write操作

    2)A写入成功且向Client返回“OK”。(此时客户端逻辑则认为write操作成功)

    3)A将操作通过异步的方式replication到slave A1上。

    上述过程中可见,A不会等到slave A1复制成功后才向Client返回确认消息;所以在2)过程之后如果A失效了,A1将会被提升为Master,那么A1上尚未复制的writes操作意味着丢失了。。。

 

    Redis Cluster支持“同步复制”,即使用“WAIT”指令(即在write操作之后紧跟一个WAIT指令,表示此客户端等待,直到Master将write被同步给slave之后才返回确认消息),它可以降低数据丢失的可能性,但这仍然不是严格意义上的“强一致性”(通常是二阶段提交)。

 

    还有另一种情况会导致writes丢失:网络分区,network partition。比如有6个节点A、B、C,以及其对应的slaves A1、B1、C1,以及Client端为Z1;此时网络分区导致“A,C,A1,B1,C1”、“B、Z1”,其中Z1与“B”在一个分区,且与第一个分区完全隔离,即客户端被隔离在一个小分区中。因为Z1认为B是Master,所以它将继续writes;集群中故障检测、判定以及failover都需要一定的时间量,在此时间内,Z1仍将writes操作发送给B,但是failover结束后,B1被提升为Master(B也在隔离指定时间后,切换为read only状态),但是因为网络分区导致B无法将数据同步给B1,所以在failover期间发生的writes将丢失。

    这里引入一个“node timeout”配置参数,当node将链接中断超过timeout后,master将被认为失效,此后将有其中一个slave来替代。当然,如果在timeout超时后,没有master接管,那么整个集群将处于error状态,中断所有的write请求。

 

六、集群配置参数

    我们稍后会尝试搭建一个Cluster环境,在此之前先了解一下Cluster的几个配置参数,它们需要在redis.conf中声明:

    1)cluster-enabled <yes/no>:首要参数,表示此redis实例是否支持cluster,“yes”表示开启,此后此redis实例可以被添加到集群中,“no”表示此redis为单实例运行。

    2)cluster-config-file <filename>:cluster配置文件的名称,当集群信息发生变更时,node将会自动把这些信息持久化到此配置文件中,以便在启动时重新读取它。对于用户而言,通常不应该认为修改此文件内容。文件中会包含:集群中其他nodes信息、以及他们的状态,还有一些持久性的变量等。

    3)cluster-node-timeout <毫秒数>:node在被认为失效之前,允许不可用的最长时间。如果Master处于“不可达”的时间超过此值,将会被failover。当然,每个node在此时间内不能与“多数派”nodes通讯,它也将终止接收writes请求,切换到read only模式。这个参数很重要,选择合适的值,对集群的有效性、数据一致性有极大影响。

    4)cluster-slave-validity-factor <factor>:用于限定slave于master的失联时长的倍数;如果设置为0,slave总是尝试failover,不管master与slave之间的链接断开多久(即只要slave无法与master通讯,都会尝试进行failover;Cluster有选举机制,有可能会被否决);如果此值为正值,则失联的最大时长为:factor * node timeout,当失联时长超过此值后,slave触发failover。比如node timeout为5秒,factor为10,那么当slave与master失联超过50秒时,slave将会尽力尝试failover。此值需要合理设置,也会对集群有效性、数据一致性产生影响。

    5)cluster-migration-barrier <count>:适用于“migration”架构场景(稍后介绍);master需要保留的slaves的最少个数;如果一个master拥有比此值更多的slaves,那么Cluster将会使用“migration”机制,将多余的slaves迁移到其他master上,这些master持有的slaves的数量低于此值。最终Cluster希望做到,slaves能够按需迁移,在failover期间,确保每个master都有一定量的slaves,以提高集群整体的可用性。(比如A有三个slaves:A1、A2、A3,而B只有一个slave B1,当B失效后,B1提升为master,但是B1没有任何slave,所以存在风险,那么migration机制,可以将A下的某个slave迁移到B1下,成为B1的slave。)

    6)cluster-require-full-coverage <yes/no>:“集群是否需要全量覆盖”,如果设置为yes(默认值),当集群中有slots没有被任何node覆盖(通常是由于某个master失效,但是它也没有slave接管时),集群将会终止接收writes请求;如果设置为no,集群中那些服务正常的nodes(slots)仍然可以继续服务。

 

七、创建和使用集群

    创建集群之前,需要准备一些空的redis实例,且它们支持集群模式,接下来我们在单机模拟一个Cluster测试环境,6个节点分别为三个masters和三个slaves,客户端port依次为:7000、7001、7002、7003、7004、7005,每个节点使用单独的redis.conf文件,它们使用不同的datadir,以避免存储时冲突。

redis-7000.conf
redis-7001.conf
redis-7002.conf
redis-7003.conf
redis-7004.conf
redis-7005.conf
##在redis的根目录创建上述配置文件
##适当修改每个文件中的数据目录和端口即可
##redis需要首先执行make

 

    redis-7000.conf配置样例:

daemonize yes
pidfile /var/run/redis-7000.pid
port 7000
bind 127.0.0.1
dir /data/redis/7000
cluster-enabled yes
##默认保存在dir下
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

 

    nodes.conf这个文件,用于保存Cluster信息的,通常不要人为的去修改它,以免带来错误;支持集群模式的redis实例,在启动时会初始化nodes.conf信息,同时当它加入集群后,如果收到集群信息的变更时,将会修改此文件内容。因为masters需要“多数派”,所以最小Cluster的构建规模,至少包含3个master节点,本文为了展示Cluster的最小完整拓扑结构,还为每个master增加了一个slave。

 

    我们依次启动上述redis实例!在启动日志中,我们可以看到每个redis实例都会创建一个node ID的字符串,当然此信息也可以在各自的nodes.conf中查看。集群中,所有的node都会持有唯一的ID,Cluster并没有使用IP + Port方式来标记一个实例,因为IP +Port可能会随时改变,这会影响集群中节点的判断,所以它使用了node ID,任何节点的ID一旦生成将会写入到nodes.conf中,且此后不会被修改。

 

    此后我们需要将这些孤立的redis node构建成Cluster环境,我们可以使用Redis提供了帮助脚本redis-trib来完成,这个脚本使用ruby开发,所以我们需要安装ruby相关依赖:

 

#任意目录
> gem install redis
 

 

    因为国内网络问题可能导致无法安装,错误提示如下:

 

ERROR:  Could not find a valid gem 'redis' (>= 0), here is why:
          Unable to download data from https://rubygems.org/ - Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://rubygems.org/latest_specs.4.8.gz)
 

 

    建议先增加一个国内的ruby镜像地址,然后再执行gem指令:

 

> gem sources -a https://ruby.taobao.org/
 

 

    安装成后,我们即可以使用redis-trib构建集群了:

 

> cd src
> ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

 

  

    redis-trib脚本位于src下,“create”指令就是用来构建集群,“replicas 1”表示每个master只有一个slave,将会根据此规则解析此后的IP:Port地址列表,6个地址,前三个是master,后三个是slave:

 

Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
M: 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: 48abc812431cf7b1e20830bcb73fa2e15169a970 127.0.0.1:7003
   replicates 545d7cfe420163529962911fe244d356140e3756
S: a6c9e20808c34ffac40e3fb2d0938b52359ec54f 127.0.0.1:7004
   replicates e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8
S: a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005
   replicates db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3
 

 

 

Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
M: 48abc812431cf7b1e20830bcb73fa2e15169a970 127.0.0.1:7003
   slots: (0 slots) master
   replicates 545d7cfe420163529962911fe244d356140e3756
M: a6c9e20808c34ffac40e3fb2d0938b52359ec54f 127.0.0.1:7004
   slots: (0 slots) master
   replicates e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8
M: a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005
   slots: (0 slots) master
   replicates db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
 

 

    非常简单,到此为止简单的集群已经构建完成,16384个slots也全部分配。接下来我们使用jedis客户端对集群数据进行几次操作:

 

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>
 

 

 

Set<HostAndPort> hosts = new HashSet<>();
//添加任意多个redis实例的地址
//不需要将集群中所有的地址都穷举
hosts.add(new HostAndPort("127.0.0.1",7000));
hosts.add(new HostAndPort("127.0.0.1",7001));
hosts.add(new HostAndPort("127.0.0.1",7002));
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setBlockWhenExhausted(true);
poolConfig.setMaxTotal(32);
poolConfig.setMaxIdle(2);
JedisCluster jedisCluster = new JedisCluster(hosts,poolConfig);
jedisCluster.set("test001","test001");
System.out.println(jedisCluster.get("test001"));
jedisCluster.close();
 

 

    我们也可以通过redis-cli中断来操作集群数据,比如:

 

#任何一个节点均可
#必须需要使用-c参数,表示开启集群模式,
#可以提示“ASK”、“MOVED”等slots转移信息
> ./redis-cli -c -p 7000
127.0.0.1:7000> set test002 test002
-> Redirected to slot [13391] located at 127.0.0.1:7002
OK
-> set test002 test002
OK
 

 

    redis-cli和我们的Jedis客户端在功能上并没有太大区别,在集群模式下,向节点写入key时,当前node将会告知client将key转发到合适的node上,比如我们在7000这个实例上写入“test002”(首次写入,Client此时还没有nodes与slots的映射关系),此时返回“Redirected”信息,告知Client此key应该被写入在7002节点,那么Client将会在7002节点上重试,写入成功并返回“OK”。每当Client收到“Redirected”反馈信息时,它都会重新获取集群中nodes与slots的映射关系(任何node都可以交付映射信息),并在本地缓存,此后再次写入时,Client将直接与相应的node交互即可,比如第二次写入“test002”时,直接返回了“OK”。

 

    Resharding

    Resharding就是将数据重新分片,意味着我们可以将nodes上的部分slots迁移到其他nodes上,redis-trib辅助工具仍然可以帮助我们:

##注意,7000只是trib登陆的实例
> ./redis-trib.rb reshard 127.0.0.1:7000
....
How many slots do you want to move (from 1 to 16384)? 1000
What is the receiving node 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:545d7cfe420163529962911fe244d356140e3756
Source node #2:done

 

    在slots重新分配的过程中,

    1)需要输入允许迁移的slots数量,最终将有指定数量的slots被迁移到目标node上。

    2)需要输入“Receiving”端的node ID,表示集群中哪个node接收slots,通常是新的node或者负载较小的node。

    3)需要输入“Source”端的node ID,表示“指定数量的slots”将从哪些nodes上迁出;允许依次输入多个ID,输入“all”表示从所有nodes上(不包括Receiving端),“done”表示输入结束,开始执行reshard。

 

    之所以“reshard”,原因就是Redis Cluster目前还没有提供“rebalance”机制,它不能自动平衡集群中每个节点上的slots分布,不过此特性将来会添加进去。

 

    自动Failover

    我们可以通过“cluster nodes”指令来查看集群中节点的状态和拓扑关系:

#登陆到任意节点
> ./redis-cli -c -p 7000
127.0.0.1:7000> cluster nodes
db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002 master - 0 1458555571985 3 connected 10923-16383
a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005 slave db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 0 1458555572489 6 connected
545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 127.0.0.1:7001 master - 0 1458555571480 2 connected 5461-10922
48abc812431cf7b1e20830bcb73fa2e15169a970 127.0.0.1:7003 slave 545d7cfe420163529962911fe244d356140e3756 0 1458555571480 4 connected
a6c9e20808c34ffac40e3fb2d0938b52359ec54f 127.0.0.1:7004 slave e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 0 1458555570474 5 connected

 

    由此可见,7000、7001、7002是master,其中7005是7002的slave节点,我们尝试将7002关闭,看看7005是否能够正常failover并提升为master:

#关闭7002
>./redis-cli -p 7002 shutdown

##然后在其他任何节点使用“cluster nodes”指令查看即可
##发现7005已经被提升为master

 

    我们可以再次启动7002,会返现此时7002自动转换为7005的slave。从简单测试来看,Cluster的failover机制符合预期的。

 

    如果需要人为的Failover,比如希望将某个Slave提升为Master,我们可以在指定的slave上使用“CLUSTER FAILOVER”指令即可。

 

    新增节点

    这是一个非常普遍的运维操作,我们将一个新的node添加到集群中,如果它是一个master节点,还可以将其他nodes上的部分slots迁移到此node上;当然也可以为现有的master新增slave节点。

    假如我们新增一个节点7006,它将作为一个新的master加入集群,换个其他节点一下,我们为其准备配置文件和数据目录,并启动:

> ./redis-server ../redis-7006.conf 
> ./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
##等同于:CLUSTER MEET

 

    “add-node”指令第一个参数为新node的地址,第二个参数为任意现存的节点作为登陆节点。执行后,我们可以通过“cluster nodes”指令查看集群节点的状态,会发现7006加入集群正常,但是唯一的问题就是其上没有分布任何slots;像这种没有任何slots的节点,也不会参与集群选举,它的失效也不会影响集群可用性,所以,我们可以使用上述的“reshard”指令将其他节点的部分slots迁移到新节点。

 

    我们也可以通过如下命令为集群添加一个slave:

> ./redis-trib.rb add-node --slave 127.0.0.1:7006 127.0.0.1:7000

 

    通过“--slave”选项表示添加的新节点是一个slave,Cluster将这个新节点分配给某个没有slave或者slaves个数最少的master;如果希望为指定的master新增slave节点,则指令中应该指定master节点的ID:

> ./redis-trib.rb add-node --slave --master-id 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7006 127.0.0.1:7000
##等同于:CLUSTER REPLICATE

 

    移除节点

> ./redis-trib del-node 127.0.0.1:7000 26f047b573ed2bb37aa6dd46f6e444d3a8e26f50

 

    “del-node”指令可以将一个空的node移除集群,所谓空node就是此node上没有覆盖任何slots。如果你要移除一个master,那么首先需要将此节点上的所有slots迁移到其他nodes上(reshard指令),否则移除节点将会抛出错误。

 

    副本迁移(migration)

    我们也会经常遇到这样的需求,将某个master的其中一个slave迁移到其他master,即重新配置slave从属:

#登陆到相应的slave节点
CLUSTER REPLICATE <master-node-id>

 

    不过对于集群而言,有时候我们希望slave能够自动迁移到合适的master下,不需要人工干预,这种机制称为“副本迁移”(replicas migration)。

    1)集群总是将slaves数量最多的master下的某个slave,迁移到slave个数最小的master下。即平衡每个master持有的slaves数量。

    2)通常我们可以将多个slave随意加入集群,而不需要关注它们究竟归属哪个master;因为副本迁移机制,可以动态平衡它们。

    3)配置参数“cluster-migration-barrier”用于限定每个master下应该保留的最少slaves个数,那么在副本迁移时,集群应该首先保证当前master下的slaves个数不低于此值。

 

八、Cluster常用指令

    1、CLUSTER NODES

    在集群中的任何一个节点,均可以使用此指令查看集群节点的状态和拓扑结构,同时也能查看每个节点分配的slots等。

db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002 slave a91205008a4f0b5a1c0aff5d08f9d903f1d72182 0 1458565075747 7 connected
a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005 master - 0 1458565075245 7 connected 10923-16383

 

    每条记录的组成:

    1)node ID:40个字符的随机字符串,全局唯一。

    2)ip:port:节点的地址

    3)flags:一个有“,”分割的列表:myself,master,slave,fail?,fail等;master:表示当前node为master,通常其后跟一个“-”;myself表示此node为当前登陆节点;slave表示其节点为slave,此后紧跟master的node ID;fail?:表示节点处于PFAIL状态;fail:此节点处于FAIL状态,多数节点已不可达。

    4)ping-sent:此节点最近一次ping发送的时间戳。

    5)pong-recv:此节点最近一次pong的接收时间。

    6)config-epoch:此节点的epoch值,每次failover,都会导致epoch值的增加。同一个master的多个slaves,在failover时,epoch值最大者被提升为新的master。

    7)link-state:链接状态

    8)slot:此节点上持有的sltos的区间,如果只持有一个slot,此时将会是一个数字。

 

    2、CLUSTER SLAVES <node-id>:列出指定node的slaves列表。

    3、CLUSTER SLOTS:展示出slots与nodes的对应关系

1) 1) (integer) 10923    ----start slot range
   2) (integer) 16383    ----end slot range
   3) 1) "127.0.0.1"    ----master
      2) (integer) 7005
   4) 1) "127.0.0.1"    --slave
      2) (integer) 7002
2) 1) (integer) 0
   2) (integer) 5460
   3) 1) "127.0.0.1"
      2) (integer) 7000
   4) 1) "127.0.0.1"
      2) (integer) 7003

 

    4、CLUSTER KEYSLOT <key>:计算此key所属的slot。

    5、CLUSTER MEET <ip> <port>:将指定的redis实例加入集群,当前登陆节点会将此新node的信息通过gossip协议广播给集群中其他的节点。

    6、CLUSTER REPLICATE <node-id>:将当前节点转换为指定node的slave。

    7、CLUSTER FAILOVER [force | takeover]:将当前节点提升为master。

 

    其他更多指令请参见:CLUSTER

 

参考文档:

http://redis.io/topics/cluster-tutorial

http://redis.io/topics/cluster-spec

    

深入理解Redis Cluster:架构、原理与实践 Redis 是一个高性能的键值存储数据库,广泛应用于缓存、会话存储、消息队列等场景。随着数据量和并发量的增长,单机 Redis 可能面临性能瓶颈和单点故障问题。为了解决这些问题,Redis 提供了 Redis Cluster,一种分布式解决方案,支持数据自动分片、高可用性和水平扩展。 本文将深入探讨 Redis Cluster 的架构设计、核心原理、部署方式以及最佳实践,帮助你全面理解并高效使用 Redis Cluster。 阅读详情

相关推荐

(7)Redis-Cluster集群理论及实践【上】

前言 redis 是我们目前大规模使用的缓存中间件,由于它强大高效而又便捷的功能,得到了广泛的使用。 redis在年初发布了3.0.0,官方支持了redis cluster,也就是集群。至此结束了redis 没有官方集群的时代,之前我们用redis cluster用的最多的应该是twitter 发布的Twemproxy(https://github.com/twitter/twemproxy)...

应无所住而生其心 1503

java通过scan进行redis key遍历

遍历所有redis key,删除满足条件的field import xxx.utils.RedisClusterUtil; import org.checkerframework.checker.units.qual.A; import redis.clients.jedis.JedisCluster; import java.util.*; //add by xq import java.util.List; import redis.clients.jedis.Jedis; import red

山中有石为玉 8234

Redis Cluster集群的搭建与实践

Redis Cluster集群 一、redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其redis-cluster架构图如下: 其结构特点:      1、所有的redis节点彼此互联(PI

Andyの笔记 3万+

jedis 4.1.1版本集群模式 keys解决方案

jedis以集群方式连接redis会使用redis.clients.jedis.JedisCluster 集群下直接使用JedisCluster.keys()会报错 Cluster mode only supports KEYS command with pattern containing hash-tag ( curly-brackets enclosed string ) 错误解决: jedis 4.X以前 集群keys的解决方案是遍历 Map<String, JedisPool> clu

oZhanXiangSi的博客 5264

Redis Cluster集群模式原理与Java应用实践

Redis Cluster是Redis的分布式解决方案,在保证高可用性的同时也实现了数据的水平扩展。它通过自动分片机制将数据分布在多个Redis节点上,无需外部的缓存分区支持。本章将带您领略Redis Cluster的基本架构和设计理念。我们会从Redis Cluster如何解决大数据量存储问题开始,逐步深入到它的工作原理和使用场景。Redis Cluster的出现不仅解决了传统Redis的性能瓶颈,也降低了大规模应用的运维复杂度,是众多互联网公司后端架构不可或缺的一部分。

weixin_33628677的博客 346

Hcaptcha验证码的‘免浏览器’破解思路:协议分析与N值算法逆向

本文深入解析Hcaptcha验证码的‘免浏览器’破解思路,通过协议分析与N值算法逆向,实现高效自动识别。文章详细拆解Hcaptcha的API交互流程,揭示关键参数`req`和`n`的生成机制,并提供轻量级实现方案,显著降低资源消耗,适用于大规模数据采集等场景。

weixin_30838873的博客 535

Redis_Jedis, JedisCluster 扩展 keys 方法实现

  最近,我们使用 Java 操作 Redis 比较多,用的组件是 Jedis ,下面是一个 maven 坐标。 &lt;dependency&gt; &lt;groupId&gt;redis.clients&lt;/groupId&gt; &lt;artifactId&gt;jedis&lt;/artifactId&gt; &lt;version&gt;2.9.0&...

迎难而上 4626

Keil C51开发必看:详解data/xdata/bdata内存分配陷阱与避坑指南

本文深入解析Keil C51开发中的data/xdata/bdata内存分配陷阱,提供针对51芯片的高效避坑指南。通过真实案例揭示Keil编译器的隐藏规则,分享内存优化策略和调试技巧,帮助开发者解决data溢出、xdata访问异常等典型问题,提升嵌入式开发效率。

v6b7n8m9q0的博客 1072

(十一)Redis集群JedisCluster实现keys命令方法

由于JedisCluster集群类不支持像单机模式下的keys方法,下面的类我们就模拟keys命令方法: 一、获取集群类   package redis.v1.client.server; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.Iterat...

OceanSky的专栏 4318

中微8S6990实战:5分钟搞定GPIO配置与按键中断(附避坑指南)

本文以中微8S6990单片机为例,详细讲解了GPIO按键中断的快速配置方法与实战避坑指南。内容涵盖GPIO初始化、中断配置、软件消抖优化及低功耗唤醒等关键步骤,并提供了利用逻辑分析仪进行调试验证的有效方法,帮助开发者快速构建稳定可靠的嵌入式按键交互系统。

weixin_29194817的博客 280

用Keil5给CH552G编程:手把手配置8051开发环境+LED闪烁实战

本文详细介绍了如何使用Keil5为CH552G单片机配置8051开发环境,并完成LED闪烁实战。从获取必要软件、安装WCH器件库到创建工程、编写程序及烧录,手把手指导开发者避开常见陷阱,特别适合从STC转向CH552G的开发者。

weixin_30733003的博客 538

008.Redis Cluster集群架构实践

Redis Cluster模式部署实战 本文详细介绍了Redis Cluster集群模式的部署流程,主要内容包括: 环境准备(关闭防火墙、配置主机名解析、时钟同步) 6节点规划(3主3从)及槽位分配 自动化部署脚本编写(变量定义、互信配置) 系统优化(内存参数、透明大页配置) 编译安装Redis 8.0.3到所有节点 通过systemd服务单元管理Redis进程 部署过程采用脚本自动化方式,实现了从单节点到多节点的批量配置和安装,确保集群环境的一致性。最后提供了Redis服务管理单元文件,便于通过syste

木二 987

ROBOGUIDE教程:FANUC机器人X型焊枪气动点焊焊接

FANUC机器人X型焊枪气动点焊焊接虚拟仿真实现方法。

IndRobSim 4386

redis cluster集群搭建与实践

1.实现原理 redis3.0以后支持redis-cluster集群 采用无中心化结构 每个节点保存数据和集群的状态 每个节点都和其他所有节点连接。其redis-cluster架构图如下: 其结构特点: 1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。 2、节点的fail是通过集群中超过半数的节点检测失效时才生效。 3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一...

u011187168的博客 239

Vue2项目实战:vue2-org-tree实现动态组织架构图

本文详细介绍了如何在Vue2项目中使用vue2-org-tree组件实现动态、可交互的组织架构图。内容涵盖从快速安装、基础渲染到核心功能实战,包括水平布局、节点展开折叠、响应式数据绑定、深度自定义节点内容以及事件处理。同时提供了性能优化、样式覆盖等避坑指南,并通过一个完整的企业级Demo展示了如何打造功能丰富的架构图,助力高效开发后台管理系统。

weixin_28040125的博客 522

【电动汽车再生制动控制技术(万字长文,图文并茂)】

电动汽车再生制动的基本原理是:通过具有可逆作用的电动机/发电机来实现电动汽车动能和电能的转化。在汽车减速或制动时,可逆电机以发电机形式工作,汽车行驶的动能带动发电机将汽车动能转化为电能并储存在储能器(蓄电池或超级电容器)中;在汽车起动或加速时,可逆电机以电动机形式工作,将储存在储能器中的电能转化为机械能给汽车。这对于改善汽车的能量利用效率,延长电动汽车的行驶距离是至关重要的。

优快云-新能源汽车研发测试专业博主 1577

唯品会大规模 Redis Cluster 的生产实践

分享大纲 本次分享内容如下: 1、生产应用场景 2、存储架构演变 3、应用最佳实践 4、运维经验总结 关于这4部分的内容介绍: 第1、2部分:介绍redis cluster在唯品会的生产应用场景,以及存储架构的演变。第3部分:redis cluster的稳定性,应用成熟度,踩到过那些坑,如何解决这些问题?这部分是大家比较关系的内容。第4部分:简单介绍大规模运营的一些经验,包括部署

yubinpll9110的专栏 3019

手把手入门YOLO到改进优化教程 | 【P1基础篇】YOLOv8网络架构原理

本节先来学习基础知识,以YOLOv8进行讲解入门, 拿YOLOv8入手掌握YOLO的底层逻辑 ,也可以基于此来轻松学习后面更新的YOLO系列 (大部分YOLO版本的核心思想一致,更新是基于旧版本做结构升级、优化策略,学习成本会越来越低)。

嵌入式阿齐Archie 2万+

唯品會大規模 Redis Cluster 的生産實踐

1、生産應用場景 1.1 業務範圍 redis cluster在唯品會主要應用于後端業務,用作內存存儲服務。主要大數據實時推薦/ETL、風控、營銷三大業使用。 cluster用于取代當前twemproxy三層架構,作爲通用的存儲架構。redis...

chuzhuo9521的博客 212

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

《Redis高并发架构设计:从单机到Cluster的最佳实践》

文章围绕Redis高并发架构设计,介绍从单机到Cluster的演进。摘要将提炼核心要点,助你快速了解Redis架构知识。 ### Redis高并发架构设计:从单机到Cluster的最佳实践摘要 本文聚焦Redis高并发架构设计,阐述基础部署模型差异,单机模式适用于测试等场景,主从+Sentinel满足中小规模业务,Redis Cluster支撑核心生产环境。深入解析Cluster架构槽位分片与高可用原理,针对热点key和跨槽事务痛点,提出多副本、本地缓存及Lua脚本等解决方案。结合去哪儿网实战,分享混合

lcl_032015的博客 734

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

redis分布式方案redis cluster的介绍和实践

简要介绍 redis cluster是redis官方提供的分布式解决方案。主要作用有两点: 将数据根据分区规则分布到不同的redis节点上,降低单个redis节点的读写压力。 内置提供高可用支持,集群中的每个主节点可以设置多个从节点,主节点故障后,从节点可以自动替换继续保证redis的使用。 分布式的方案要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负...

markfengfeng的博客 1018

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Redis Cluster 分布式缓存架构设计与实践

Redis Cluster是一种分布式缓存架构,通过分片技术(16384个哈希槽)和高可用设计解决单机Redis的性能瓶颈与单点故障问题。其核心包括去中心化节点结构、主从复制机制和自动故障转移能力,采用Gossip协议维护集群状态。在实际应用中,它适用于高并发Web、实时数据分析和微服务场景,能有效缓存热点数据并支持水平扩展。搭建过程需配置多个主从节点实例,通过CRC16算法实现键值路由。该架构显著提升了系统的并发处理能力和可用性。

ALex_zry的博客 1263

Redis Cluster 故障转移与高可用实践

Redis Cluster通过主从复制和自动故障转移机制实现高可用性,采用Gossip协议进行故障检测与确认。其故障转移流程包括资格检查、投票选举、主节点晋升和槽位重分配等步骤,确保在节点故障时快速恢复服务。网络分区情况下采用majority机制,只有包含多数主节点的分区才能继续服务。该架构适用于金融、电商等高可用要求场景,通过合理配置参数、多可用区部署和读写分离等策略保障系统稳定性。

ALex_zry的博客 1069

Redis Cluster 实践

一:关于redis cluster 1:redis cluster的现状 reids-cluster计划在redis3.0中推出,可以看作者antirez的声明:http://antirez.com/news/49(ps:跳票了好久,今年貌似加快速度了),目前的最新版本见:https://raw.githubusercontent.com/antir...

weixin_33973609的博客 72

Redis Cluster 部署、在线扩容、缩容、迁移、集群管理实践

概述 Redis 分片集群是为了应对业务增长带来的数据增长, 实现在线动态横向扩缩容,集群中的每个分片主节点处理 16384 个哈希槽的一个子集; 为了稳定也可以进行高可用部署, 即将各分片节点启用一个或多个副本节点; 当分片主节点挂掉,其对应的副本节点自动提升为新主节点,当原主节点重新上线后,自动成为新主节点的副本节点; 当一对分片主从节点都故障时,整个集群不能正常工作,需要人工介入恢复启动故障节点 分片集群 1、创建一个有 3 个分片节点的集群 # 创建具有 3 个分片节点的集群、每个分片有

star8521的专栏 959

redis:redis cluster集群实践

本文是集群的基础介绍(安装、测试、操作),没有介绍复杂难懂的概念。如果你想深入了解集群原理请参考 Redis 集群规范 。 Redis的版本>=3.0 redis集群介绍 redis cluster提供一种redis安装方式:数据自动在多个redis节点间分片 redis cluster提供一定程度的高可用,在实际的环境中当某些节点失败或者不能通讯的情况下能够继续提供服务。大量节点失败的情况下集群也会停止服务(比如大多数主节点不可用) redis集群提供的能力: 自动切分数据集到多个节点上 当

OceanStar的博客 1889
上一篇: 算法编程(五)
下一篇: Redis Cluster实现原理
iteye_19607
博客等级 码龄8年 34粉丝 198原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值