[TOC] > [参考](https://juejin.im/post/5c9ca08f5188252d5a14a31b) ## 概述 为甚么填入任何一个节点地址都可以操作redisCluster呢? 在集群模式下,Redis接收任何键相关命令时首先计算键对应的槽, 假如初始化的是从节点, 首先会向从节点发送redis命令, 从节点根据槽找出所对应的节点,如果节点是自身,则处理键命令; 如果不是自身, 则MOVED重定向错误,通知客户端请求正确的节点。这个过程称为MOVED重定向 重定向信息包含了键所对应的槽以及负责该槽的节点地址,根据这些信 息客户端就可以向正确的节点发起请求 ## 安装 ### docker [CentOS Docker 安装](https://www.runoob.com/docker/centos-docker-install.html "CentOS Docker 安装") ### redis:5.0 `docker pull redis:5.0` ## 集群搭建 ### 创建Redis 容器 /home/redis-cluster ``` mdkir -p /home/redis-cluster cd /home/redis-cluster ``` /home/redis-cluster/redis-cluster.tmpl ``` port ${PORT} protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 192.168.0.229 cluster-announce-port ${PORT} cluster-announce-bus-port 1${PORT} appendonly yes #daemonize no ``` > 备注:此模版文件为集群节点通用文件 其中${PORT} 将读取命令行变量 ip则根据**网卡分配ip**进行替换 以保证节点配置文件除端口以及ip外 全部一致 > ip 可为实际网卡ip > ### 自动生成配置 ``` for port in `seq 7000 7005`; do \ mkdir -p ./${port}/conf \ && PORT=${port} envsubst < ./redis-cluster.tmpl > ./${port}/conf/redis.conf \ && mkdir -p ./${port}/data; \ done ``` ### 创建自定义network ``` docker network create redis-net docker network ls ``` > 备注:创建redis-net虚拟网卡 目的是让docker容器能与宿主(centos7)桥接网络 并间接与外界连接 #### 查看redis-net虚拟网卡网关ip ``` docker network inspect redis-net | grep "Gateway" | grep --color=auto -P '(\d{1,3}.){3}\d{1,3}' "Gateway": "172.18.0.1" ``` ### 创建6个redis容器 ``` for port in `seq 7000 7005`; do \ docker run -d -ti -p ${port}:${port} -p 1${port}:1${port} \ -v /home/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \ -v /home/redis-cluster/${port}/data:/data \ --restart always --name redis-${port} --net redis-net \ --sysctl net.core.somaxconn=1024 redis:5.0 redis-server /usr/local/etc/redis/redis.conf; \ done ``` 备注:命令译为 循环7010 - 7005 运行redis 容器 ``` docker run 运行 -d 守护进程模式 --restart always 保持容器启动 --name redis-710* 容器起名 --net redis-net 容器使用虚拟网卡 -p 指定宿主机器与容器端口映射 701*:701* -P 指定宿主机与容器redis总线端口映射 170**:1700* --privileged=true -v /home/redis-cluster/701*/conf/redis.conf:/usr/local/etc/redis/redis.conf 付权将宿主701*节点文件挂载到容器/usr/local/etc/redis/redis.conf 文件中 --privileged=true -v /home/redis-cluster/${port}/data:/data \ 付权将宿主701*/data目录挂载到容器/data目录中 --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf; 容器根据挂载的配置文件启动 redis服务端 ``` ### 查看容器分配ip ``` docker network inspect redis-net ... "600aa2f84dfbe72a19caf5dc684cb7691e89a43753f70d74355468b7659caa23": { "Name": "redis-7000", "EndpointID": "75873081222c7a2eedc5f3ee639df5cc7645790012dd72e34c97fd97dcb5cf47", "MacAddress": "02:42:ac:15:00:02", "IPv4Address": "172.21.0.2/16", "IPv6Address": "" }, ... ``` > 备注:每个容器对应分配了ip 需要修改节点配置文件redis.conf与其对应并重启容器。 ``` vim /home/redis-cluster/700*/conf/redis.conf //编辑ip为查询分配的ip 并wq退出 port 7000 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.21.0.2 # 设置网卡ip 可为真实ip cluster-announce-port 7000 cluster-announce-bus-port 17000 appendonly yes ``` ### 启动集群 ``` docker exec -it redis-7000 bash redis-cli --cluster create 172.21.0.2:7000 172.21.0.3:7001 172.21.0.4:7002 172.21.0.5:7003 172.21.0.6:7004 172.21.0.7:7005 --cluster-replicas 1 ``` ### 连接集群 ``` docker exec -it redis-7000 bash redis-cli -c -p 7000 //注意连接集群 需要参数c 127.0.0.1:7000> info replication ... 127.0.0.1:7000> set name cpj -> Redirected to slot [360] located at 192.168.0.229:7000 ``` ### 停止进群 ``` for port in `seq 7000 7005`; do \ docker stop redis-${port}; docker rm redis-${port}; done ``` ## 注意事项 ### 开放端口 ``` for port in `seq 7000 7005`; do \ firewall-cmd --zone=public --add-port=${port}/tcp --permanent done #重新载入 firewall-cmd --reload = ```