redis通常须要6个节点才能组成完整的高可用集群,这里咱们使用docker-compose
来快速搭建集群。 集群搭建通常分为三个步骤:node
项目GitHub地址:github.com/willcat/red…git
因为代码更新,在配置文件中手动设置了容器名称,因此文章和代码中的容器名有区别,好比文章中的redis-cluster_redis-cluster-6380_1
,在代码和实际运行中是node-80
,文章中的redis-cluster_redis-cluster-6381_1
,在代码和实际运行中是node-81
github
进入redis-cluster-docker目录,执行docker-compose up -d
redis
随便进入一个容器好比redis-cluster_redis-cluster-6380_1
[1],docker exec -it redis-cluster_redis-cluster-6380_1 redis-cli -p 6380
,而后运行cluster nodes
命令,整个过程以下:docker
$ docker exec -it redis-cluster_redis-cluster-6380_1 redis-cli -p 6380
127.0.0.1:6380> cluster nodes
3914fe7597f9ad9e9c485cf473bcaa461973baaa :6380@16380 myself,master - 0 0 0 connected
复制代码
能够看到目前各个节点还只能返回本身的信息,每一个节点还不能感知到彼此。ruby
[1] 这是docker-compose
根据咱们在docker-compose.yml
配置的服务名称自动生成的,若是不想使用默认名称,能够在配置文件中使用container_name
指定容器名称 docker exec
bash
节点握手是指一批运行在集群模式下的节点经过Gossip
协议彼此通讯,达到感知对方的过程。网络
cluster meet {ip} {port}
命令,达到两个节点间的握手,这两个节点就组成了一个真正的彼此感知的集群,以后两个节点间会按期经过ping/pong
消息进行正常的节点通讯cluster meet {ip} {port}
命令,添加还没有加入集群的新节点127.0.0.1:6380> cluster nodes
c6db83c252a072407707917474001c70da649407 172.26.0.6:6385@16385 master - 0 1565199856348 3 connected
e356c336482f7a8a3f786674b96ac06030b0dcb4 172.26.0.3:6381@16381 master - 0 1565199855000 0 connected
dae83c485b9fb1357947944b36007c3371a750f2 172.26.0.7:6383@16383 master - 0 1565199857362 5 connected
c87aba899473356f25a919dc2d477340f5222ba4 172.26.0.2:6382@16382 master - 0 1565199855000 4 connected
5ebbd85dfbe1e4e01bae5f4954418a436453876c 172.26.0.5:6384@16384 master - 0 1565199855339 2 connected
3914fe7597f9ad9e9c485cf473bcaa461973baaa 172.26.0.4:6380@16380 myself,master - 0 1565199855000 1 connected
复制代码
{app_name}_default
网络中docker network ls
能够查看网络列表,docker network inspect <network_name>
能够查看对应网络的配置以及各个容器的ip。docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-cluster_redis-cluster-6385_1
命令直接查看某个容器的ip。节点创建握手以后,集群还处于下线状态,没法执行写操做。app
127.0.0.1:6380> set hello world
(error) CLUSTERDOWN Hash slot not served
复制代码
查看集群信息能够看到集群是fail
状态工具
127.0.0.1:6380> cluster info
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_ping_sent:718
cluster_stats_messages_pong_sent:283
cluster_stats_messages_meet_sent:8
cluster_stats_messages_sent:1009
cluster_stats_messages_ping_received:283
cluster_stats_messages_pong_received:285
cluster_stats_messages_received:568
复制代码
在各个节点上执行相似cluster addslots {0...5461}
的命令,将0~16383个slot平均分配到全部节点上。这里咱们只分配三个节点,另外三个节点分别看成前面三个节点的从节点,从而在主节点出现故障时可以自动完成故障转移。
//分配三个节点,注意,如下三个命令在登陆redis-cli以后是不成功的,只能使用redis-cli -p 6380 cluster addslots {0..5461}这种模式
$ docker exec -it redis-cluster_redis-cluster-6380_1 redis-cli -p 6380 cluster addslots {0..5461}
$ docker exec -it redis-cluster_redis-cluster-6381_1 redis-cli -p 6381 cluster addslots {5462..10922}
$ docker exec -it redis-cluster_redis-cluster-6382_1 redis-cli -p 6382 cluster addslots {10923..16282}
// 将三个未分配槽的节点设置为从节点
127.0.0.1:6383> CLUSTER REPLICATE 3914fe7597f9ad9e9c485cf473bcaa461973baaa
OK
127.0.0.1:6384> CLUSTER REPLICATE e356c336482f7a8a3f786674b96ac06030b0dcb4
OK
127.0.0.1:6385> CLUSTER REPLICATE c87aba899473356f25a919dc2d477340f5222ba4
OK
复制代码
这样3主3从的集群就搭建完成了,能够感受到仍是比较麻烦的,因此redis官方在redis3.x
和redis4.x
提供了redis-trib.rb
工具方便咱们快速搭建集群,在redis5.x
中更是能够直接使用redis-cli
命令来直接完成集群的一键搭建,省去了redis-trib.rb
依赖ruby环境的问题。在代码中,readme.md里提供了快速搭建的命令。
//官方指出: 能够使用redis5.x 的redis-cli命令模式来搭建由redis-4.x组成的集群。
redis-cli --cluster create 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 \
--cluster-replicas 1
复制代码
在集群中某个节点读写不属于此节点的数据会返回错误(error) MOVED 5798 172.20.0.6:6381
,为了减小手动切换的环节,在开启客户端时能够添加-c
参数,开启请求重定向,详细命令redis-cli -p 6380 -c
,这样之后操做跨节点时会自动跳转到相应的节点
大多数开发语言的Redis客户端都采用Smart客户端支持集群协议,客户端选择能够参考clients。
Moved
重定向负责协助Smart客户端更新slot->node的映射关系。当集群伸缩时,slot会发生迁移,这时去原来节点读写会返回(error) ASK {slot} {targetIP}:{targetPort}
错误,客户端从ASK重定向异常提取出目标节点信息,发送asking
命令到目标节点打开客户端链接标识,再执行键命令。若是存在则执行,不存在则返回不存在信息。
TODO