搭建Redis Cluster
本文使用多机搭建,一台虚机两个节点
IP | 环境 | docekr | redis |
---|---|---|---|
192.168.119.156 | CentOS Linux release 7.6.1810 | version 19.03.9 | redis:6.0 |
192.168.119.157 | CentOS Linux release 7.6.1810 | version 19.03.9 | redis:6.0 |
192.168.119.158 | CentOS Linux release 7.6.1810 | version 19.03.9 | redis:6.0 |
整体搭建步骤主要分为以下几步:
- 下载 Redis 镜像(其实这步可以省略,因为创建容器时,如果本地镜像不存在,就会去远程拉取)
- 编写 Redis 配置文件
- 创建 Redis 容器
- 创建 Redis Cluster 集群
- 查看集群状态
- 查看集群及节点信息
- 测试读写
1、拉取Redis镜像
# 需要什么版本就拉取什么版本,如果是内网,请提前准备好镜像包,找一台可连接外网的虚机即可
# docker pull redis:6.0
6.0: Pulling from library/redis
eff15d958d66: Pull complete
1aca8391092b: Pull complete
06e460b3ba1b: Pull complete
76b2112cc8b7: Pull complete
0f0e368cbbb6: Pull complete
686ee6025c94: Pull complete
Digest: sha256:27de068c6b366096ae12b6f43839d4be22b0681732c09ef47172cf0b21b4c50b
Status: Downloaded newer image for redis:6.0
docker.io/library/redis:6.0
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis 6.0 ffe7215bad7b 8 days ago 112MB
2、编写Redis配置文件
创建目录及文件
分别在 三台虚机上执行以下操作。
# 192.168.119.156
# 创建目录,目录可自己定义
mkdir -p /usr/local/docker-redis/redis-cluster
# 切换至指定目录
cd /usr/local/docker-redis/redis-cluster/
# 编写 redis-cluster.tmpl 文件
vi redis-cluster.tmpl
# 编写配置文件
port ${PORT}
requirepass 123456 # 密码可配置可不配置
masterauth 123456
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.119.156
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
# 192.168.119.157
# 创建目录
mkdir -p /usr/local/docker-redis/redis-cluster
# 切换至指定目录
cd /usr/local/docker-redis/redis-cluster/
# 编写 redis-cluster.tmpl 文件
vi redis-cluster.tmpl
# 编写配置文件
port ${PORT}
requirepass 123456
masterauth 123456
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.119.157
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
# 192.168.119.158
# 创建目录
mkdir -p /usr/local/docker-redis/redis-cluster
# 切换至指定目录
cd /usr/local/docker-redis/redis-cluster/
# 编写 redis-cluster.tmpl 文件
vi redis-cluster.tmpl
# 编写配置文件
port ${PORT}
requirepass 123456
masterauth 123456
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.119.158
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
port:节点端口;
requirepass:添加访问认证;
masterauth:如果主节点开启了访问认证,从节点访问主节点需要认证;
protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
daemonize:是否以守护线程的方式启动(后台启动),默认 no;
appendonly:是否开启 AOF 持久化模式,默认 no;
cluster-enabled:是否开启集群模式,默认 no;
cluster-config-file:集群节点信息文件;
cluster-node-timeout:集群节点连接超时时间;
cluster-announce-ip:集群节点 IP,填写宿主机的 IP;
cluster-announce-port:集群节点映射端口;
cluster-announce-bus-port:集群节点总线端口。
每个 Redis 集群节点都需要打开两个 TCP 连接。一个用于为客户端提供服务的正常 Redis TCP 端口,例如 6379。还有一个基于 6379 端口加 10000 的端口,比如 16379。
第二个端口用于集群总线,这是一个使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测、配置更新、故障转移授权等等。客户端永远不要尝试与集群总线端口通信,与正常的 Redis 命令端口通信即可,但是请确保防火墙中的这两个端口都已经打开,否则 Redis 集群节点将无法通信。
在 192.168.119.156
机器的 redis-cluster
目录下执行以下命令:
for port in `seq 6371 6372`; do \
mkdir -p ${port}/conf \
&& PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
&& mkdir -p ${port}/data;\
done
在 192.168.119.157
机器的 redis-cluster
目录下执行以下命令:
for port in `seq 6373 6374`; do \
mkdir -p ${port}/conf \
&& PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
&& mkdir -p ${port}/data;\
done
在 192.168.119.158
机器的 redis-cluster
目录下执行以下命令:
for port in `seq 6375 6376`; do \
mkdir -p ${port}/conf \
&& PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
&& mkdir -p ${port}/data;\
done
上面 shell for 语句,意思就是循环创建 6371 ~ 6376 相关的目录及文件。
执行完毕之后,可以看到目录结构
# 192.168.119.156
# 其余两台没有tree命令就不看了,结果一致,除了目录名称及配置内容
tree -L 3
.
├── 6371
│ ├── conf
│ │ └── redis.conf
│ └── data
├── 6372
│ ├── conf
│ │ └── redis.conf
│ └── data
└── redis-cluster.tmpl
6 directories, 3 files
# 配置文件输出结果
# cat 6371/conf/redis.conf
port 6371
requirepass 123456
masterauth 123456
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.119.156
cluster-announce-port 6371
cluster-announce-bus-port 16371
3、创建 Redis 容器
将宿主机的 6371 ~ 6376
之间的端口与 6 个 Redis 容器映射,并将宿主机的目录与容器内的目录进行映射(目录挂载)。记得指定网络模式,使用 host
网络模式。
在 192.168.119.156
机器执行以下命令:
for port in $(seq 6371 6372); do \
docker run -di --restart always --name redis-${port} --net host \
-v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /usr/local/docker-redis/redis-cluster/${port}/data:/data \
redis:6.0 redis-server /usr/local/etc/redis/redis.conf; \
done
在 192.168.119.157
机器执行以下命令:
for port in $(seq 6373 6374); do \
docker run -di --restart always --name redis-${port} --net host \
-v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /usr/local/docker-redis/redis-cluster/${port}/data:/data \
redis:6.0 redis-server /usr/local/etc/redis/redis.conf; \
done
在 192.168.119.158
机器执行以下命令:
for port in $(seq 6375 6376); do \
docker run -di --restart always --name redis-${port} --net host \
-v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /usr/local/docker-redis/redis-cluster/${port}/data:/data \
redis:6.0 redis-server /usr/local/etc/redis/redis.conf; \
done
备注:命令译为 循环6371 - 6376 运行redis 容器
docker run 运行-di 守护进程
–restart always 保持容器启动
–name redis-${port} 容器名称
–net host 使 用host网 卡
− v 挂载目录
redis:6.0 指定镜像版本
redis redis-server /usr/local/etc/redis/redis.conf 根据挂载配置启动redis服务端
查看是否创建成功
docker ps
4、创建 Redis Cluster 集群
随便进入一个容器
docker exec -it redis-6371 bash
cd cd /usr/local/bin/
# 创建Redis Cluster 集群
./redis-cli -a 123456 --cluster create 192.168.119.156:6371 192.168.119.156:6372 192.168.119.157:6373 192.168.119.157:6374 192.168.119.158:6375 192.168.119.158:6376 --cluster-replicas 1
至此一个高可用的 Redis Cluster 集群搭建完成,如下图所示,该集群中包含 6 个 Redis 节点,3 主 3 从。三个主节点会分配槽,处理客户端的命令请求,而从节点可用在主节点故障后,顶替主节点。
5、查看集群状态
我们先进入容器,然后通过一些集群常用的命令查看一下集群的状态。
# 进入容器
docker exec -it redis-6371 bash
# 切换至指定目录
cd /usr/local/bin/
# 检查集群状态
./redis-cli -a 123456 --cluster check 192.168.119.156:6371
6、查看集群信息和节点信息
# 在192.168.119.156机器连接
# 连接至集群某个节点
./redis-cli -c -a 1234 -h 192.168.119.158 -p 6376
# 查看集群信息
cluster info
# 查看集群结点信息
cluster nodes
7、测试读写
在 6376 节点中执行写入和读取,命令如下:
# 写
set name mrhelloworld
set a 123
set b 123456
# 读取数据
get name
get a
get b
来到192.168.119.157虚机上查看
docker exec -it redis-6374 bash
root@k8s-node01:/data# cd /usr/local/bin/
root@k8s-node01:/usr/local/bin# ./redis-cli -c -a 1234 -h 192.168.119.157 -p 6374
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Warning: AUTH failed
192.168.119.157:6374> get name
-> Redirected to slot [5798] located at 192.168.119.157:6373
Warning: AUTH failed
"mrhelloworld"
192.168.119.157:6373> get a
-> Redirected to slot [15495] located at 192.168.119.158:6375
Warning: AUTH failed
"123"
192.168.119.158:6375> get b
-> Redirected to slot [3300] located at 192.168.119.156:6371
Warning: AUTH failed
"123456"
192.168.119.156:6371>
通过以上操作我们得知 name
键的存储被分配到了 6373 节点,a分到了6375,b分到了6371节点
所以我们直接连接 任意节点并获取该值都不需要重定向节点,因为数据就在该节点,所以直接读取返回。
到此Redis Cluster搭建完毕
8、Haproxy负载
拉取镜像
docker pull haproxy
Using default tag: latest
latest: Pulling from library/haproxy
eff15d958d66: Already exists
2b24affa247e: Pull complete
8ab01220e071: Pull complete
5a8e56fc6768: Pull complete
Digest: sha256:bd15d84d1ff75a1259e7db6e4d8c68bc1a445da0107f39db9225746a00126c57
Status: Downloaded newer image for haproxy:latest
docker.io/library/haproxy:latest
# 创建容器
docker create --name haproxy --net host -v /opt/haproxy:/usr/local/etc/haproxy haproxy:latest
0b85906e3a89d1920e88beebbef1b1cbc78d5978340e728cdc71f0d741ccc517
# 修改haproxy.cfg
vim /opt/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
maxconn 4000
daemon
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#haproxy的客户页面
listen http_front
bind 0.0.0.0:25666
stats uri /haproxy #页面地址
#页面的用户名和密码,建议主备设为不同,方便确定抢占到VIP的服务器是主机还是备机
stats auth admin:admin
stats admin if TRUE #管理界面,成功登陆后可通过webui管理节点
listen proxy-redis
bind 0.0.0.0:16379 # 负载端口
mode tcp
balance roundrobin
option tcplog
server redis1 192.168.119.156:6371 check port 6371 maxconn 3000
server redis2 192.168.119.156:6372 check port 6372 maxconn 3000
server redis3 192.168.119.157:6373 check port 6373 maxconn 3000
server redis4 192.168.119.157:6374 check port 6374 maxconn 3000
server redis5 192.168.119.158:6375 check port 6375 maxconn 3000
server redis6 192.168.119.158:6376 check port 6376 maxconn 3000
# 重启容器
docker restart haproxy
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b85906e3a89 haproxy:latest "docker-entrypoint.s…" 11 minutes ago Up 8 minutes haproxy
4af3e220ba25 redis:6.0 "docker-entrypoint.s…" 2 hours ago Up About an hour redis-6372
db3a02890eb3 redis:6.0 "docker-entrypoint.s…" 2 hours ago Up About an hour redis-6371
# 测试负载
docker run -it redis:6.0 bash
cd /usr/local/bin/
./redis-cli -h 192.168.119.156 -p 16379
192.168.119.156:16379> get a
"123"
到此haproxy正常
可以访问:http://192.168.119.156:25666/haproxy