why cluster redis replication实现一主多从架构可以实现读写分离 redis sentinel实现一主多从下得高可用 但是却不能突破redis单机瓶颈
redis3以后增加了redis cluster成为海量数据得解决方案:
自动在多节点间进行数据分片
当一部分节点出现故障或无法与其余群集通信时,可以继续操作。
redis cluster端口 每个redis cluster node 需要两个端口:一个正常得redis端口,比如6379;一个正常redis端口+10000获得得端口,比如16379 这个大端口主要用来给cluster bus使用;cluster bus用来通过一个二进制协议实现节点间得通信,用于故障检测,配置更新,故障转移授权等。
redis cluster 数据分片 redis cluster没有使用一致性hash算法,而是使用了hash slot方式。 redis cluster中有16384个hash slot,要计算给定key的hash slot,只需对key的CRC16取模16384就可以获得对应得hash slot redist cluster中每个node代表一个hash slot得子集,比如三节点情况下:Node A contains hash slots from 0 to 5500. Node B contains hash slots from 5501 to 11000. Node C contains hash slots from 11001 to 16383. 这样得好处是在cluster中增加或删除节点会非常简单,只需要移动一些hash slot就可以了。并且这个过程不需要任何停机。 当一个redis命令脚本执行得时候,redis cluster支持所涉及得key都属于一个hash slot得情况。可以通过使用hash tag来保证所有key属于同一个hash slothash tag:如果key的{}中的括号之间有一个子字符串,则仅对字符串中的内容进行哈希处理,例如,此{foo}键和另一个{foo} key保证在同一hash slot中,并且可以在具有多个key作为参数的命令中一起使用。
redis cluster master-slave模型 可以在创建cluster得时候给master添加slave节点; 比如A、B、C为master node,A1、B1、C1为slave node,这样当B故障得时候B1可以提升为master继续提供服务;但是如果B和B1都发生故障得话,集群将不能继续运行。
redis cluster 一致性保证 Redis Cluster无法保证强一致性。实际上,这意味着在某些情况下,Redis Cluster可能会丢失客户端的写入操作。 造成丢失得原因有两个:
异步复制
在网络分区期间,在该分区中,客户端与少数实例(至少包括主实例)隔离。
官方文档
配置集群 4台机器模拟8节点 4主4从 在192.168.0.201 192.168.0.202 192.168.0.203 192.168.0.204每一台执行如下操作:
1 2 3 4 mkdir /etc/redis-cluster touch /etc/redis-cluster/7000.conf touch /etc/redis-cluster/7001.conf mkdir /var/log/redis
vim /etc/redis-cluster/7000.conf
1 2 3 4 5 6 7 8 9 port 7000 cluster-enabled yes cluster-config-file /etc/redis-cluster/node-7000.conf cluster-node-timeout 5000 appendonly yes daemonize yes pidfile /var/run/redis_7000.pid logfile /var/log/redis/7000.log bind 192.168.0.20X 127.0.0.1
vim /etc/redis-cluster/7001.conf
1 2 3 4 5 6 7 8 9 port 7001 cluster-enabled yes cluster-config-file /etc/redis-cluster/node-7001.conf cluster-node-timeout 5000 appendonly yes daemonize yes pidfile /var/run/redis_7001.pid logfile /var/log/redis/7001.log bind 192.168.0.20X 127.0.0.1
启动集群节点
1 2 redis-server /etc/redis-cluster/7000.conf redis-server /etc/redis-cluster/7001.conf
查看启动日志
创建集群 在任意机器执行创建:比如192.168.0.202上
1 redis-cli --cluster create 192.168.0.201:7000 192.168.0.201:7001 192.168.0.202:7000 192.168.0.202:7001 192.168.0.203:7000 192.168.0.203:7001 192.168.0.204:7000 192.168.0.204:7001 --cluster-replicas 1
将能看到输出日志:
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 >>> Performing hash slots allocation on 8 nodes... Master[0] -> Slots 0 - 4095 Master[1] -> Slots 4096 - 8191 Master[2] -> Slots 8192 - 12287 Master[3] -> Slots 12288 - 16383 Adding replica 192.168.0.202:7001 to 192.168.0.201:7000 Adding replica 192.168.0.203:7001 to 192.168.0.202:7000 Adding replica 192.168.0.204:7001 to 192.168.0.203:7000 Adding replica 192.168.0.201:7001 to 192.168.0.204:7000 M: 9c45c1ed0d1686ebb8f648dd1950388e980ff7fd 192.168.0.201:7000 slots:[0-4095] (4096 slots) master S: dc18063897d9ced631e409ae5129a98df717137b 192.168.0.201:7001 replicates c92a97df67f96b0f00562eac3f610785c203b393 M: 4ad71dc43b6014faf072b66de0b981360d71fe68 192.168.0.202:7000 slots:[4096-8191] (4096 slots) master S: 5c2237d20a4957e9b604ca6f5e354676049518b7 192.168.0.202:7001 replicates 9c45c1ed0d1686ebb8f648dd1950388e980ff7fd M: 23b72679000b8ab64b1116b556b6b06630586194 192.168.0.203:7000 slots:[8192-12287] (4096 slots) master S: 490ad398792978333e62f40abdae5b9461acc11e 192.168.0.203:7001 replicates 4ad71dc43b6014faf072b66de0b981360d71fe68 M: c92a97df67f96b0f00562eac3f610785c203b393 192.168.0.204:7000 slots:[12288-16383] (4096 slots) master S: 4bc59c58ebe3e0245226816a0b6443f535252294 192.168.0.204:7001 replicates 23b72679000b8ab64b1116b556b6b06630586194 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 192.168.0.201:7000) M: 9c45c1ed0d1686ebb8f648dd1950388e980ff7fd 192.168.0.201:7000 slots:[0-4095] (4096 slots) master 1 additional replica(s) S: 490ad398792978333e62f40abdae5b9461acc11e 192.168.0.203:7001 slots: (0 slots) slave replicates 4ad71dc43b6014faf072b66de0b981360d71fe68 S: 5c2237d20a4957e9b604ca6f5e354676049518b7 192.168.0.202:7001 slots: (0 slots) slave replicates 9c45c1ed0d1686ebb8f648dd1950388e980ff7fd M: c92a97df67f96b0f00562eac3f610785c203b393 192.168.0.204:7000 slots:[12288-16383] (4096 slots) master 1 additional replica(s) M: 4ad71dc43b6014faf072b66de0b981360d71fe68 192.168.0.202:7000 slots:[4096-8191] (4096 slots) master 1 additional replica(s) S: 4bc59c58ebe3e0245226816a0b6443f535252294 192.168.0.204:7001 slots: (0 slots) slave replicates 23b72679000b8ab64b1116b556b6b06630586194 M: 23b72679000b8ab64b1116b556b6b06630586194 192.168.0.203:7000 slots:[8192-12287] (4096 slots) master 1 additional replica(s) S: dc18063897d9ced631e409ae5129a98df717137b 192.168.0.201:7001 slots: (0 slots) slave replicates c92a97df67f96b0f00562eac3f610785c203b393 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
查看状态
1 2 redis-cli -p 7000 cluster nodes redis-cli --cluster check 127.0.0.1:7000
测试数据分片 1 2 3 4 5 6 7 8 9 10 11 12 13 $ redis-cli -c -p 7000 redis 127.0.0.1:7000> set foo bar -> Redirected to slot [12182] located at 127.0.0.1:7002 OK redis 127.0.0.1:7002> set hello world -> Redirected to slot [866] located at 127.0.0.1:7000 OK redis 127.0.0.1:7000> get foo -> Redirected to slot [12182] located at 127.0.0.1:7002 "bar" redis 127.0.0.1:7000> get hello -> Redirected to slot [866] located at 127.0.0.1:7000 "world"
-c参数,客户端会进行分片自动重定向。如果没有这个参数则需要到对应分片节点操作,slave节点还需要先输入readonly,然后才能进行get操作
测试故障转移 查看所有master
1 redis-cli -p 7000 cluster nodes | grep master
模拟故障
1 redis-cli -h 192.168.0.201 -p 7000 debug segfault
检查集群状态
1 redis-cli --cluster check 127.0.0.1:7000
可以发现192.168.0.201:7000得节点已经被摘除了 启动192.168.0.201:7000节点重新查看所有master,会发现master已经被其他节点接管,192.168.0.201:7000已经变成一个slave节点
添加新节点-master 添加一个空节点
1 2 3 4 cp /etc/redis-cluster/7000.conf /etc/redis-cluster/7002.conf sed -i 's/7000/7002/g' /etc/redis-cluster/7002.conf redis-server /etc/redis-cluster/7002.conf redis-cli --cluster add-node 127.0.0.1:7002 192.168.0.204:7000
检查集群状态,会发现已经加入成功 此时得master没有hash slot,不能保存数据,还需要reshard使其可以保存分片数据
1 2 3 4 #交互式迁移 redis-cli --cluster reshard 127.0.0.1:7000 或命令式迁移 redis-cli --cluster reshard <host>:<port> --cluster-from <node-id> --cluster-to <node-id> --cluster-slots <number of slots> --cluster-yes
添加新节点-slave
1 2 3 4 #这种方式会随机加入一个拥有最少slaves得master redis-cli --cluster add-node 127.0.0.1:7002 127.0.0.1:7000 --cluster-slave #这种方式指定master redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
1 2 redis-cli -p 7002 cluster replicate 23b72679000b8ab64b1116b556b6b06630586194
方式2更灵活,可以手动将slave从一个master移动到另一个master可以通过冗余slave得方式实现slave得自动迁移: 如果某个master的slave的挂了,其他节点冗余的slave会自动迁移到这个master
删除节点 1 redis-cli --cluster del-node 127.0.0.1:7000 `<node-id>`
您可以用这种方法删除master,但是要删除master,它必须为空 。如果master不为空,则需要先将数据从其重新分片到所有其他master。