引言
搭建集群首先须要装置 Docker,Linux 中装置比较简单,具体能够参考[[【Docker】Linux 装置 Docker(极简版)]](https://segmentfault.com/a/11…)。
[[【RocketMq】RocketMq 4.9.4 Windows-docker 部署]](https://segmentfault.com/a/11…) 中提到了 Windows 装置 Docker 的一部分些细节,这里不再过多探讨,装置实现之后的 Redis 集群搭建同样能够参考本篇进行构建。
过来集体在 Mac 上搭建过一次集群,和本文的搭建思路类似。如果是 Mac 用户能够参考:[[M1-Mac 中 docker 的 redis 集群配置]](https://segmentfault.com/a/11…)
Docker 拉取 Redis
查找和拉取 Redis 的命令为 docker search redis
和 docker pull reids:latest(或指定其余版本)
,查找之后拉取指定版本的 Redis 到本地 Docker 即可。
具体的操作流程如下,这里省略了 docker search redis
的过程。上面是在 windows 的 Docker 操作,Linux 指定成果统一:
单节点启动
单节点非常简单,适宜立马上手应用学习的开发者,依照上面的命令执行:
# 默认拉取一个最新的 redis 镜像
docker pull redis
#在默认的 6379 端口上启动一个 redis 服务
docker run --name test-redis -p 6379:6379 -d redis
#进入容器外部
docker exec -it test-redis /bin/bash
# 连贯 redis
redis-cli
#进入之后装置常规 ping 一下即可
ping
自定义配置单节点
Linux 中能够应用上面的形式:
docker run -d -p 6380:6379 -v /usr/docker/redis/myRedis/redis.conf:/etc/redis/redis.conf -v /usr/docker/redis/myRedis/data:/data --name myRedis redis redis-server /etc/redis/redis.conf
在 Windows 版本的 docker 仅仅是门路配置不太一样,须要替换为指定盘符的地址。
集群搭建
集群构建的步骤其实并不算特地简单,关键在于配置以及一些模版命令上须要读者自行批改。
自定义 redis-net
创立docker newwork
虚构网段用于 redis 集群节点通信应用。
此命令须要提前执行,否则后续的步骤会报错,倡议一开始立刻执行。
docker network create redis-net
创立 redis.conf 配置模版
咱们须要创立一个 docker/redis/ 目录
,在新建目录内创立 6 个redis.conf 文件。比拟笨的传统方法是一个个构建,当然这样一个个复制切实是太麻烦了,咱们寻找更快的形式,下文会进行介绍。
为了更高效的构建 redis 的配置,咱们通过 创立模板 的形式构建 redis.conf
模板,留神这一份配置文件格式既不能有误也不能乱写,否则整个 redis 构建过程是必定会出问题的,配置文件如下:
先来个 简略版本 的模板:
port ${PORT}
cluster-enabled yes
protected-mode no
cluster-config-file nodes.conf
cluster-node-timeout 5000
#对外 ip,这里的 ip 要改为你的服务器 Ip。【留神不能应用 127.0.0.1】cluster-announce-ip 192.168.58.128
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes
如果对于模板构建纯熟,能够应用简单点的版本,具体内容如下:
# 启动端口
port ${PORT}
# 绑定 IP, 0.0.0.0 为本地
#bind 0.0.0.0
# 日志等级
#loglevel notice
# 日志文件地位
#logfile /opt/docker/${PORT}/redis${PORT}_log.txt
# 是否开启 AOF 长久化模式,默认 no
appendonly yes
# aof 长久化文件格式
appendfilename appendonly.${PORT}.aof
# 集群文件
cluster-enabled yes
# 集群配置文件的名称, 每个节点都有一个集群相干的配置文件,长久化保留集群的信息。# 不配置,默认配置为 nodes-6379.conf
#cluster-config-file nodes.${PORT}.conf
cluster-config-file nodes.conf
# 节点互连超时的阀值,集群节点超时毫秒数
cluster-node-timeout 5000
# 集群节点 IP,填写宿主机的 IP
cluster-announce-ip 192.168.58.128
# 集群节点映射端口
cluster-announce-port ${PORT}
# 集群节点总线端口
# 此参数倡议 +10000
cluster-announce-bus-port 1${PORT}
# 断线工夫过长的从节点不容许设置为 master,该参数就是用来判断 slave 节点与 master 断线的工夫是否过长,作为计算参数之一
# 公式:(node-timeout * slave-validity-factor) + repl-ping-slave-perio,假如 node-timeout = 30,默认的 repl-ping-slave-period 是 10 秒,则如果超过 310 秒此 slave 将不会尝试进行故障转移 cluster-slave-validity-factor 10
# 能够配置值为 1,示意 master 的 slave 数量大于这个数值,slave 能力迁徙到孤立的 master 下面
# 如果这个数值被设置为 2,则只有一个主节点领有 2 个可工作节点才会从一个从节点迁徙。cluster-migration-barrier 1
# 默认状况下,集群全副的 slot 有节点负责,集群状态才为 ok,能力提供服务。设置为 no,能够在 slot 没有全副调配的时候提供服务。# 不倡议设置为 no,因为容易造成分区并且可能导致小分区的 Master 节点始终在被写入造成数据不均衡的问题。#cluster-require-full-coverage no
# redis 连贯明码 拜访认证
#requirepass 123456
# 主节点拜访认证
#masterauth 123456
# 是否启动保护模式
protected-mode no
以上两个版本其实就是配置多和少的区别,集体以 简略版本 的文件进行记录和演示。老手如果不相熟 Docker 集群搭建,倡议把下面的配置独自配置保留,以便须要的时候立即翻阅回顾构建流程。
模板配置
领有 redis.conf
模板之后,咱们开始根据这个模板构建集群目录和对应的数据存储。
集群配置
首先咱们能够执行上面的命令构建对应的目录和配置,留神在构建之前跳转到本人部署 redis 集群的根目录,比方集体先 cd /opt/docker/redis
当中:
for port in `seq 6000 6000`; do
mkdir -p ./${port}/conf && PORT=${port} envsubst < ./redis_template_version2.conf > ./${port}/conf/redis.conf && mkdir -p ./${port}/data;
done
下面的命令是几个子命令拼凑在一起的,比拟好了解:
- 在当前目录下构建“端口”对应的文件夹
- 定义把文件外部的 ${port}替换为对应的端口,重定向到页面替换。
- 输入到端口文件夹上面的 conf/redis.conf,这样每个端口文件夹相当于一个独立的 redis 服务
- 最初构建 data 存储数据目录
这里稍微解释一下
${xx}
这样的写法含意:
用 shell 格局字符串中的值替换环境变量。要替换的变量须要是${var}
或$var
格局。
比方:echo '{{$HOME}}' | envsubst
,替换环境变量stdin
输入到stdout
:envsubst < {{path/to/input_file}}
,将输出文件中的环境变量替换为stdout
:
redis_template_version2.conf
就是后面的.conf
模板文件的目录里。
简略版本 的内容如下,这个文件的配置内容较为简化:
port ${PORT}
cluster-enabled yes
protected-mode no
cluster-config-file nodes.conf
cluster-node-timeout 5000
#对外 ip,这里的 ip 要改为你的服务器 Ip。【留神不能应用 127.0.0.1】,因为 Docker 本身运行有一层外部网络,这个网络是为了反对节点外部通信的。cluster-announce-ip 192.168.58.128
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes
构建实现之后,咱们能够看到对应的文件夹内容如下(局部文件为集体试验命令):
为了不便展现,这里应用 tree 命令,留神 tree 通常须要手动装置,具体的装置过程如下:
sudo yum install tree
最初整个树形目录构建如下:
[zxd@localhost docker]$ tree
.
├── 6000
│?? ├── conf
│?? │?? └── redis.conf
│?? └── data
│?? ├── appendonlydir [error opening dir]
│?? └── nodes.conf
├── 6001
│?? ├── conf
│?? │?? └── redis.conf
│?? └── data
│?? ├── appendonlydir [error opening dir]
│?? └── nodes.conf
├── 6002
│?? ├── conf
│?? │?? └── redis.conf
│?? └── data
│?? ├── appendonlydir [error opening dir]
│?? └── nodes.conf
├── 6003
│?? ├── conf
│?? │?? └── redis.conf
│?? └── data
│?? ├── appendonlydir [error opening dir]
│?? └── nodes.conf
├── 6004
│?? ├── conf
│?? │?? └── redis.conf
│?? └── data
│?? ├── appendonlydir [error opening dir]
│?? └── nodes.conf
├── 6005
│?? ├── conf
│?? │?? └── redis.conf
│?? └── data
│?? ├── appendonlydir [error opening dir]
│?? └── nodes.conf
├── redis-back1.conf
├── redis_init_config.txt
├── redis_init.txt
├── redis_template.conf
└── redis_templat_version2.conf
运行 redis 节点
构建集群须要确保每一个节点都可能独自执行:
for port in `seq 6000 6000`; do
docker run -d -ti -p ${port}:${port} -p 1${port}:1${port} -v /opt/docker/redis/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /opt/docker/redis/${port}/data:/data --restart always --name redis-${port} --net redis-net --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf;
done
之后 docker ps
查看所有节点是否失常启动,同时对于每个节点进行连贯测试,因为篇幅无限,这里就不过多介绍了。
如果是线上部署,倡议每个节点进入试一遍看看是否能失常单节点运行,保障都能够失常启动的状况下,开始尝试构建集群。
构建 redis 集群
咱们启动 6 个节点之后,只须要进入到某一个节点的容器外部执行构建集群的命令即可,以集体的启动过程为例,执行上面的步骤:
- 执行
docker ps
命令。查看所有集群均失常搭建。
- 获取其中一个节点的容器 id,当然也能够间接通过最初一列的 NAMES 进入,咱们执行上面的命令:
docker exec -it d0073d25a732 /bin/bash
或者执行命令
`
docker exec -it redis-6000 /bin/bash
顺利进入到容器当中,此时还须要执行 redis-cli
真正进入到 redis 外部。留神启动端口是从 6000-6005,间接用默认的 redis-cli 会进入到 6379 的端口,这样连贯是会失败的,所以咱们最好指定端口和 ip 运行redis-cli
。
docker exec -it redis-6000 /bin/bash
root@d0073d25a732:/data# redis-cli -h 192.168.58.128 -p 6000
192.168.58.128:6000> ping
PONG
192.168.58.128:6000>
留神:进入节点容器外部之后,能够间接执行
redis-cli
,也能够进入到/usr/local/bin
下运行相干命令。
到了要害的步骤,咱们开始构建 redis 节点集群。留神这一步倡议进入容器之后跳转到/usr/local/bin
redis-cli --cluster create 192.168.58.128:6000 192.168.58.128:6001 192.168.58.128:6002 192.168.58.128:6003 192.168.58.128:6004 192.168.58.128:6005 --cluster-replicas 1
本人构建集群须要把 Ip 和端口进行绝对应的批改操作
root@d0073d25a732:/usr/local/bin# ./redis-cli --cluster create 192.168.58.128:6000 192.168.58.128:6001 192.168.58.128:6002 192.168.58.128:6003 192.168.58.128:6004 192.168.58.128:6005 --cluster-replicas 1
最终的打印内容如下:
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.58.128:6004 to 192.168.58.128:6000
Adding replica 192.168.58.128:6005 to 192.168.58.128:6001
Adding replica 192.168.58.128:6003 to 192.168.58.128:6002
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: a3d907505eb8575c95fb91f13d8580e144ae2ebd 192.168.58.128:6000
slots:[0-5460] (5461 slots) master
M: d429ebb22ff24dcc4a01f77776e3b8ba367c0365 192.168.58.128:6001
slots:[5461-10922] (5462 slots) master
M: 868b2e39ebf455e086c5e418537a04f1fc24f23b 192.168.58.128:6002
slots:[10923-16383] (5461 slots) master
S: c2e9e28bf4dec5f9603e176eea4e19857a548c27 192.168.58.128:6003
replicates 868b2e39ebf455e086c5e418537a04f1fc24f23b
S: 9dc71ed4313eb7db87bee287954c38d26a9ef950 192.168.58.128:6004
replicates a3d907505eb8575c95fb91f13d8580e144ae2ebd
S: cbbc3c7a21a16581ddd3136d7169eecb6c2faf83 192.168.58.128:6005
replicates d429ebb22ff24dcc4a01f77776e3b8ba367c0365
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.58.128:6000)
M: a3d907505eb8575c95fb91f13d8580e144ae2ebd 192.168.58.128:6000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 868b2e39ebf455e086c5e418537a04f1fc24f23b 192.168.58.128:6002
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 9dc71ed4313eb7db87bee287954c38d26a9ef950 192.168.58.128:6004
slots: (0 slots) slave
replicates a3d907505eb8575c95fb91f13d8580e144ae2ebd
M: d429ebb22ff24dcc4a01f77776e3b8ba367c0365 192.168.58.128:6001
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: c2e9e28bf4dec5f9603e176eea4e19857a548c27 192.168.58.128:6003
slots: (0 slots) slave
replicates 868b2e39ebf455e086c5e418537a04f1fc24f23b
S: cbbc3c7a21a16581ddd3136d7169eecb6c2faf83 192.168.58.128:6005
slots: (0 slots) slave
replicates d429ebb22ff24dcc4a01f77776e3b8ba367c0365
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
如果呈现相似的提醒,阐明集群创立胜利,如果报错则确定节点是否正确,构建集群的命令是否正确,比方 IP 和端口是否写对,是否存在对应的节点等等。
连贯测试
要连贯 Docker 的 Redis,首先要进入到某个容器的外部,而后再容器外部的 Shell 连贯上 Redis 集群,上面是集体的试验步骤:
docker ps -a
查看以后的集群状况,这里的容器 ID 为d0073d25a732
。
[zxd@localhost ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27ea2f9dced7 mysql:5.7 "docker-entrypoint.s…" 3 weeks ago Up About an hour 33060/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp mysql57
8aad8f4d75af apache/rocketmq:4.9.4 "sh mqbroker -c ../c…" 3 weeks ago Up About an hour 0.0.0.0:10909->10909/tcp, :::10909->10909/tcp, 9876/tcp, 10912/tcp, 0.0.0.0:10911->10911/tcp, :::10911->10911/tcp rmqbroker
dc2aefc4db1f apache/rocketmq:4.9.4 "sh mqnamesrv" 3 weeks ago Up About an hour 10909/tcp, 0.0.0.0:9876->9876/tcp, :::9876->9876/tcp, 10911-10912/tcp rmqnamesrv
195d102724b5 apacherocketmq/rocketmq-dashboard:latest "sh -c'java $JAVA_O…" 3 weeks ago Up About an hour 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp rocketmq-dashboard
cb04e4c79e39 redis "docker-entrypoint.s…" 3 weeks ago Exited (255) 3 weeks ago 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp test-redis
d0073d25a732 3e12e2ceb68f "docker-entrypoint.s…" 6 weeks ago Up About an hour 0.0.0.0:6000->6000/tcp, :::6000->6000/tcp, 0.0.0.0:16000->16000/tcp, :::16000->16000/tcp, 6379/tcp redis-6000
559261cf34e6 3e12e2ceb68f "docker-entrypoint.s…" 6 weeks ago Up About an hour 0.0.0.0:6005->6005/tcp, :::6005->6005/tcp, 0.0.0.0:16005->16005/tcp, :::16005->16005/tcp, 6379/tcp redis-6005
bd0fd81d54e7 3e12e2ceb68f "docker-entrypoint.s…" 6 weeks ago Up About an hour 0.0.0.0:6004->6004/tcp, :::6004->6004/tcp, 0.0.0.0:16004->16004/tcp, :::16004->16004/tcp, 6379/tcp redis-6004
7a5545e038e8 3e12e2ceb68f "docker-entrypoint.s…" 6 weeks ago Up About an hour 0.0.0.0:6003->6003/tcp, :::6003->6003/tcp, 0.0.0.0:16003->16003/tcp, :::16003->16003/tcp, 6379/tcp redis-6003
599b070b4afd 3e12e2ceb68f "docker-entrypoint.s…" 6 weeks ago Up About an hour 0.0.0.0:6002->6002/tcp, :::6002->6002/tcp, 0.0.0.0:16002->16002/tcp, :::16002->16002/tcp, 6379/tcp redis-6002
d551114d11de 3e12e2ceb68f "docker-entrypoint.s…" 6 weeks ago Up About an hour 0.0.0.0:6001->6001/tcp, :::6001->6001/tcp, 0.0.0.0:16001->16001/tcp, :::16001->16001/tcp, 6379/tcp redis-6001
- 咱们进入到容器外部,应用命令
docker exec -it d0073d25a732 /bin/bash
。
[zxd@localhost ~]$ docker exec -it d0073d25a732 /bin/bash
root@d0073d25a732:/data#
- 进入到容器之后,应用命令
redis-cli -c -h 192.168.58.128 -p 6000
连贯,而后经典的ping
和pong
测试即可,留神这里的-c
代表集群模式连贯:
root@d0073d25a732:/data# redis-cli -c -h 192.168.58.128 -p 6000
192.168.58.128:6000> ping
PONG
以上整个 docker 集群搭建结束。
常见问题
Could not connect to Redis at 127.0.0.1:6379: Connection refused
“
[root@rongle bin]# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
[root@rongle /]# redis-server /etc/redis.conf
[root@rongle /]# redis-cli
redis 127.0.0.1:6379>
这是 redis 初学者比拟常见的问题,能够从上面几个方面排查问题:
- redis.conf 是否敞开“保护模式”以及正文掉 bind 配置(默认 127.0.0.1)
- 是否启动端口和 IP 和连贯的端口和 IP 不统一。
- docker 的 redis 节点是否失常启动,如果在 status 外面发现一直重启,多半还是 redis.conf 存在问题。
- 命令的格局和标准是否正确。
收尾
以上就是疾速构建 docker redis 集群的形式,整个过程不算很难,然而对于配置这一块须要小心不要写错了,否则很容易浪费时间调试,因为在 Docker 中会对于 redis 容器进行有限重启。
参考资料
Docker 搭建 Redis Cluster 集群及扩容和收留 – Dvomu – 博客园 (cnblogs.com)
Redis 集群原理及搭建(Twemproxy、Predixy 代理搭建、Redis Cluster 集群)– Dvomu – 博客园 (cnblogs.com)