哨兵的不足
1)配置复杂
----ansible利用模块和板块
2)中断时间长
----调整参数
3)资源利用率低,只有一台主库对外提供对外服务
4)3台只能挂1台
----调整数
5)依赖于redis数据节点
6)主库压力比较大,性能有瓶颈
1、集群redis-cluster
1)槽位分配slot
2)总共有16384个槽位
3)每一个槽都得分配到位,有一个槽没分配,整个集群都不能用
4)序号不一定要连续,最重要的是每个节点的槽位数量要大致相同,允许有2%的误差
5)集群端口为配置文件里的port加10000,比如6380,通讯端口就是16380
6)故障转移切换全自动,不需要人工手动
7)集群配置文件动态更新,不能手动更改
8)代码连接redis集群需要插件驱动支持
9)集群内消息传递是同步的
10)集群内的所有已经发现的节点配置文件是自动更新的
11)hash分配算法是足够随机和足够平均的足够稳定的
1.0、集群介绍
Redis Cluster 是redis 的分布式解决方案
1.1、数据分布
redis-cluster采用的是哈希分片规则
把数据集规划到多个节点上
每个节点负责整体数据的一个子集
1.2、目录规划
# redis 安装目录
/opt/redis_cluster/redis_{PORT}/{conf,logs,pid}
# redis 数据目录
/data/redis_cluster/redis_{PORT}/redis_{PORT}.rdb
# redis 运维脚本
/root/redis_shell.sh
1.3、集群拓扑
1.4、手动搭建部署集群
========================
db01操作
========================
mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}
mkdir –p /data/redis_cluster/redis_{6380,6381}
cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF
bind 10.0.0.51
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_cluster/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
cat >/opt/redis_cluster/redis_6381/conf/redis_6381.conf<<EOF
bind 10.0.0.51
port 6381
daemonize yes
pidfile "/opt/redis_cluster/redis_6381/pid/redis_6381.pid"
logfile "/opt/redis_cluster/redis_6381/logs/redis_6381.log"
dbfilename "redis_6381.rdb"
dir "/data/redis_cluster/redis_6381/"
cluster-enabled yes
cluster-config-file nodes_6381.conf
cluster-node-timeout 15000
EOF
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
========================
db02操作:
========================
mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}
mkdir –p /data/redis_cluster/redis_{6380,6381}
cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF
bind 10.0.0.52
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_cluster/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
cat >/opt/redis_cluster/redis_6381/conf/redis_6381.conf<<EOF
bind 10.0.0.52
port 6381
daemonize yes
pidfile "/opt/redis_cluster/redis_6381/pid/redis_6381.pid"
logfile "/opt/redis_cluster/redis_6381/logs/redis_6381.log"
dbfilename "redis_6381.rdb"
dir "/data/redis_cluster/redis_6381/"
cluster-enabled yes
cluster-config-file nodes_6381.conf
cluster-node-timeout 15000
EOF
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
========================
db03操作
========================
mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}
mkdir –p /data/redis_cluster/redis_{6380,6381}
cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF
bind 10.0.0.53
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_cluster/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
cat >/opt/redis_cluster/redis_6381/conf/redis_6381.conf<<EOF
bind 10.0.0.53
port 6381
daemonize yes
pidfile "/opt/redis_cluster/redis_6381/pid/redis_6381.pid"
logfile "/opt/redis_cluster/redis_6381/logs/redis_6381.log"
dbfilename "redis_6381.rdb"
dir "/data/redis_cluster/redis_6381/"
cluster-enabled yes
cluster-config-file nodes_6381.conf
cluster-node-timeout 15000
EOF
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
1.5、手动配置节点发现
1.5.1、所有节点启动后检查进程
1.5.2、检查节点ID
但是登陆后发现每个节点只有自己ID,目前集群内的节点还没有相互发现,我们要做的就是让集群内的节点互相发现
1.5.3、查看集群的数据目录会发现有生成的配置文件
查看后发现只有自己的节点内容,等节点全部发现后会把所有的节点ID写入到这个文件
1.5.4、添加redis控制脚本
redis_shell.sh
USAG(){
echo "sh $0 {start|stop|restart|login|ps|tail} PORT"
}
if [ "$#" = 1 ]
then
REDIS_PORT='6379'
elif
[ "$#" = 2 -a -z "$(echo "$2"|sed 's#[0-9]##g')" ]
then
REDIS_PORT="$2"
else
USAG
exit 0
fi
REDIS_IP=$(hostname -I|awk '{print $1}')
PATH_DIR=/opt/redis_cluster/redis_${REDIS_PORT}/
PATH_CONF=/opt/redis_cluster/redis_${REDIS_PORT}/conf/redis_${REDIS_PORT}.conf
PATH_LOG=/opt/redis_cluster/redis_${REDIS_PORT}/logs/redis_${REDIS_PORT}.log
CMD_START(){
redis-server ${PATH_CONF}
}
CMD_SHUTDOWN(){
redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT} shutdown
}
CMD_LOGIN(){
redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT}
}
CMD_PS(){
ps -ef|grep redis
}
CMD_TAIL(){
tail -f ${PATH_LOG}
}
case $1 in
start)
CMD_START
CMD_PS
;;
stop)
CMD_SHUTDOWN
CMD_PS
;;
restart)
CMD_SHUTDOWN
CMD_START
CMD_PS
;;
login)
CMD_LOGIN
;;
ps)
CMD_PS
;;
tail)
CMD_TAIL
;;
*)
USAG
esac
集群模式的 Redis 除了原有的配置文件之外又加了一份集群配置文件.当集群内节点 信息发生变化,如添加节点,节点下线,故障转移等.节点会自动保存集群状态到配置文件. 需要注意的是,Redis 自动维护集群配置文件,不需要手动修改,防止节点重启时产生错乱.
1.5.5、节点发现后建立集群内节点连接
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.51 6381
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.52 6380
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.52 6381
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.53 6380
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.53 6381
2、Redis Cluster通讯流程
通信过程:
1)集群中的每一个节点都会单独开辟一个Tcp通道,用于节点之间彼此通信,通信端口在基础端口上加10000
2)每个节点在固定周期内通过特定规则选择结构节点发送 ping 消息
3)接收到ping 消息的节点发送 pong消息作为回应。
集群中每个节点通过一定规则挑选要通信的节点,每个节点可能知道全部节点,也可能知道部分节点,只要这些节点彼此可以正常通信,最终会大成一致的状态,
当节点出现故障,新节点加入,主从角色变化等,它能够不断的ping/pong消息,从而达到同步到目的
2.1、通讯消息类型
Gossip协议职责就是信息交换,信息交换的载体就是节点间彼此发送Gossip 消息
常见的Gssip 消息分为:ping 、pong、 meet、fail 等
2.1.1、meet
meet消息:用于通知新节点加入,消息发送者通知接受者加入到当前集群,meet消息通信消息正常完成后,接收节点会加入到当前集群中并进行ping 、pong 消息交换
2.1.2、ping
ping消息:集群内交换最频繁的消息,集群内每个节点每秒向多个其他节点发送ping消息吗,用于检测节点是否在线和交换彼此信息
2.1.3、pong
pong消息:当接收到ping、meet消息时,作为相应消息回复给发送方确认消息正常通信
节点也可以向集群内广播自身的 pong 消息来通知整个集群对自身状态进行更新
2.1.4、fail
fail消息:当节点判定集群内另一个节点下线时,回向集群内广播 一个fail消息,其他节点收到fail 消息后把相应借钱更新为下线状态
3、Redis Cluster手动分配槽位
redis-cli -h 10.0.0.51 -p 6380 cluster addslots {0..5461}
redis-cli -h 10.0.0.52 -p 6380 cluster addslots {5462..10922}
redis-cli -h 10.0.0.53 -p 6380 cluster addslots {10923..16383}
3.1、检查集群的节点状态和节点状态
4、手动配置集群高可用
1.用三剑客过滤
[root@db01 ~]# redis-cli -c -h db01 -p 6381 cluster nodes|grep -v "6381"|awk '{print $1,$2}'
8f4d4a6fcd6950d0d69231d53c3eba893d324191 10.0.0.51:6380
0095449b63ac2d0e145b3c57e96940bca25ad401 10.0.0.52:6380
bd65d98ad91fc5c918c5a9a50be50bd8a139f5b3 10.0.0.53:6380
2.先在txt文本里敲,先别在shell里
redis-cli -c -h db01 -p 6381 cluster REPLICATE 0095449b63ac2d0e145b3c57e96940bca25ad401
redis-cli -c -h db02 -p 6381 cluster REPLICATE bd65d98ad91fc5c918c5a9a50be50bd8a139f5b3
redis-cli -c -h db03 -p 6381 cluster REPLICATE 8f4d4a6fcd6950d0d69231d53c3eba893d324191
3.检查集群搭建
[root@db01 ~]# redis-cli -h 10.0.0.51 -p 6380
10.0.0.51:6380> CLUSTER NODES
4.测试集群
for i in {1..1000};do redis-cli -c -h 10.0.0.53 -p 6380 del t_${i};done
-c 支持远程操作集群其他节点
10.0.0.51:6380>DBSIZE
10.0.0.52:6380>DBSIZE
10.0.0.53:6380>DBSIZE
5、模拟故障转移
6、使用工具搭建部署Redis Cluster
1.所有机器执行,下载工具
yum makecache fast
yum install rubygems
gem sources --remove https://rubygems.org/
gem sources -a http://mirrors.aliyun.com/rubygems/
gem update –system
gem install redis -v 3.3.5
2.所有机器执行,清理环境,并启动
pkill redis
rm -rf /data/redis_cluster/redis_6380/*
rm -rf /data/redis_cluster/redis_6381/*
sh redis_shell.sh start 6380
sh redis_shell.sh start 6381
3.db01执行创建集群命令
cd /opt/redis_cluster/redis/src/
./redis-trib.rb create --replicas 1 10.0.0.51:6380 10.0.0.52:6380 10.0.0.53:6380 10.0.0.51:6381 10.0.0.52:6381 10.0.0.53:6381
./redis-trib.rb check 10.0.0.51:6380
./redis-trib.rb rebalance 10.0.0.51:6380