单机的redis不能适应互联网时代下平台对可用性、吞吐量的高要求,需要redis cluster提高可用性、扩展吞吐量
关于redis的称呼Leader/Follower 主从节点,实际上在redis中目前的称呼是master,但业界领域的标准名称是leader(因master与leader的机制不同),已造成国外领域权威人士的不满甚至弃用,redis迫于压力可能会换成leader
redis版本3.0以上
每个redis节点需要2个tcp端口,并确保防火墙打开端口,如6379与6379+10000=16379,第二个端口是集群自动使用,客户端不要去使用
最小集群要求至少包含3个主节点
Redis Cluster使用hash槽分片,hash槽数量16384个,映射方式是CRC16(key)%16384
例如3个节点的集群
节点A包含从0到5500的哈希槽。
节点B包含从5501到11000的哈希槽。
节点C包含从11001到16383的哈希槽。
Redis Cluster使用Leader-Follower模型,每个hash槽可以有1个Leader节点,N个Follower节点
例如为B节点添加1个B1 Follower节点,B1会复制B;B失败,群集将把节点B1提升为新的Leader节点,继续正常运行
Redis Cluster在某些情况下会丢失写操作
1、redis的Leader-Follower复制是异步的,集群是弱一致性的,在某些情况下会丢失写操作
2、在网络分区期间,客户端与少数实例(至少包括主实例)隔离,例如A,B,C,A1,B1,C1的集群,发生网络分区后,一侧可能有A,C,A1,B1,C1,另一侧是B和客户端,如果分区持续的时间足以使B1升级为该分区的多数端的Leader,则客户端向B发送的写操作将丢失
以3个Leader和Follower一共6个节点为例,每个节点配置
cluster-enabled yes
cluster-config-file nodes.conf
运行实例,创建集群执行
redis-cli --cluster create 127.0.0.1:7000127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004127.0.0.1:7005 \
--cluster-replicas 1
完成集群部署
使用redis的utils/create-cluster脚本可完成自动部署
执行命令
create-cluster start
create-cluster create
按交互操作完成部署
当集群部署后或有一定数据后,如果需要对节点进行重新分片,可以使用命令执行
redis-cli reshard <host>:<port> --cluster-from<node-id> --cluster-to <node-id> --cluster-slots <number ofslots> --cluster-yes
<host>:<port> 在哪个节点上执行命令
--cluster-from <node-id> 转出节点
--cluster-to <node-id> 转入节点
--cluster-slots <numberof slots> hash槽数量
有时候需要停机维护(例如升级)主节点,为了使停机时不产生一致性影响,redis提供了强制故障转移,而不会在主服务器上引起任何问题
使用CLUSTER FAILOVER 命令进行手动故障转移后,新的Leader会将客户端从原始Leader切换到新的Leader,然后可以对节点进行停机维护
集群扩容时添加新节点,可以作为新的Leader承担分片,也可以作为已有Leader的Follower
无论是哪种,首先需要把已运行的新节点加入集群
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
add-node后第一个节点是要加入的新节点,第二个节点是集群中任意节点
新加入后,它的状态是没有分配hash槽的Leader
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000--cluster-slave
还是相同的命令,只是多了个指定为使其成为从节点,但这个命令没有指定作为哪个leader的follower,因此默认是分配给follower数量最少的leader
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000--cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
这个命令指定了作为哪个leader的follower
还可以在新节点上执行命令,使其成为指定leader的follower
redis 127.0.0.1:7006> cluster replicate3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e是某个leader的id
执行redis-cli--cluster del-node 127.0.0.1:7000 `<node-id>` 即可删除节点,前提是数据必须为空,不为空需要重新分片到其他leader
副本迁移可以使follower从一个主服务器移动到另一个主服务器
redis 127.0.0.1:7006> cluster replicate3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
以上命令就是把节点手动分配给指定的leader
自动迁移的意义在于提高集群的可用性,因为故障、网络等问题某些分片的副本数不能保证足够,自动迁移使得副本数多的分片能够自动向副本数不足的分片迁移一些follower
由于redis cluster不同的key会落到不同的分片上,对mset、mget、SINTERSTORE,SUNIONSTORE,ZINTERSTORE,ZUNIONSTORE等批量操作就要求所操作的批量key位于相同的分片
Redis的hash tag能够使不同key落到相同的分片,key需要符合{foo}.student1、{foo}.student2的形式,此时redis是对{foo}进行CRC16计算
在集群中权衡key的分布是很重要的