本文仅用于记录redis集群的搭建过程
一.关于redis集群的一些介绍
1.集群是如何判断是否有某个节点挂掉
每一个节点都存有这个集群所有主节点以及从节点的信息。它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点,所以一个redis集群最少有3个master节点,而每个master节点都应该配置一个slave节点,所以一个redis集群最少应该有6个节点,3主3从。
2.集群进入fail状态的必要条件
A、某个主节点和所有从节点全部挂掉,我们集群就进入faill状态。
B、如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态.
C、如果集群任意master挂掉,且当前master没有slave.集群进入fail状态
3.redis的投票机制
投票过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉。
选举的依据依次是:网络连接正常->5秒内回复过INFO命令->10*down-after-milliseconds内与主连接过的->从服务器优先级->复制偏移量->运行id较小的。选出之后通过slaveif no ont将该从服务器升为新主服务器。
通过slaveof ip port命令让其他从服务器复制该信主服务器。
最后当旧主重新连接后将其变为新主的从服务器。注意如果客户端与旧主服务器分隔在一起,写入的数据在恢复后由于旧主会复制新主的数据会造成数据丢失。
4.集群中的主从复制
集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点继续工作,这样集群就不会因为一个主节点的下线而无法正常工作。
注意:
1、如果某一个主节点和他所有的从节点都下线的话,redis集群就会停止工作了。redis集群不保证数据的强一致性,在特定的情况下,redis集群会丢失已经被执行过的写命令。
2、使用异步复制(asynchronous replication)是redis 集群可能会丢失写命令的其中一个原因,有时候由于网络原因,如果网络断开时间太长,redis集群就会启用新的主节点,之前发给主节点的数据就会丢失。
每个Redis集群中的节点都需要打开两个TCP连接。一个连接用于正常的给Client提供服务,比如6379,还有一个额外的端口(通过在这个端口号上加10000)作为数据端口,比如16379。第二个端口(本例中就是16379)用于集群总线,这是一个用二进制协议的点对点通信信道。这个集群总线(Cluster bus)用于节点的失败侦测、配置更新、故障转移授权,等等。客户端从来都不应该尝试和这些集群总线端口通信,它们只应该和正常的Redis命令端口进行通信。命令端口和集群总线端口的偏移量总是10000。
二.CentOS 7 Docker+redis集群
注:在部署集群之前先开放对应的端口,否则创建容器时会出错(阿里云还要添加防火墙规则)
1.安装docker
自己百度docker的安装
2.拉取redis镜像
docker pull redis
3.拉取ruby
docker pull ruby
4.创建基础redis容器
#在/usr/local/src目录下创建redis-cluster文件夹,并创建配置文件redis-cluster.conf
cd /usr/local/src && mkdir redis-cluster && cd ./redis-cluster && touch redis-cluster.conf
注意修改:cluster-announce-ip [ip]
添加如下内容:
port ${PORT}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
#对外ip
cluster-announce-ip [ip]
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes
5.创建自定义network(redis-net),用于集群节点间通信
docker network create redis-net
6.在/usr/local/src/redis-cluster下生成conf和data目录,并生成配置信息
cd /usr/local/src/redis-cluster
for port in `seq 6000 6005`; do
mkdir -p ./${port}/conf && PORT=${port} envsubst < ./redis-cluster.conf > ./${port}/conf/redis.conf && mkdir -p ./${port}/data;
done
ps:共生成6个文件夹,从6000到6005,每个文件夹下包含data和conf文件夹,同时conf里面有redis.conf配置文件
7.通过基础redis镜像创建6个redis容器
for port in `seq 6000 6005`; do
docker run -d -ti -p ${port}:${port} -p 1${port}:1${port} -v /usr/local/src/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/src/redis-cluster/${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
8.构建redis集群
#1.任意进入一个创建的Redis容器
docker exec -it ca13b3af8f7a /bin/bash
#2.直接执行
redis-cli --cluster create ip:6000 ip:6001 ip:6002 ip:6003 ip:6004 ip:6005 --cluster-replicas 1
9.配置每个redis的密码
修改从6000到6005文件夹下conf/redis.conf ,添加:
masterauth [密码]
requirepass [密码]
10.重启所有容器
for port in `seq 6000 6005`;do
docker restart redis-${port};
done
11. 完成
参考1:https://www.cnblogs.com/dadonggg/p/8628735.html
参考2:https://blog.csdn.net/dumarkee/article/details/86497492