已经有了Redis主从+Sentinal(哨兵)为什么还需要Redis Cluster?
解释这个问题之前,先看一个简单的Redis主从+Sentinel的架构图。
从这个架构图不难看出,哨兵主要解决的问题是在主从架构下,主节点宕机的情况下,选择一个从节点提升为主节点继续对外提供服务。同时对Redis主从集群中的主节点、从节点进行监控。这个架构有如下缺点:
- 主节点的容量大小决定了整个Redis集群的容量大小,即主节点的内存能够存储多少数据,整个集群就只能提供这么多数据的缓存服务;
- 主节点宕机,在Sentinel哨兵从从节点选举出主节点的这段时间内,整个集群不可用;
- 一个集群必须至少要有3个Sentinel哨兵节点,且Sentinel哨兵节点只做主从节点及自身节点的监控及故障恢复,资源有些浪费;
Redis Cluster就是为解决上述几大问题而产生。
什么是Redis Cluster?
Redis Cluster本质上也是由主从结构拓展而来,只是说整个Cluster集群由若干个主从架构的小集群组成。Redis规定了16384个Hash Slot,默认情况下,每个小集群均分这16384个Hash Slot,但是可以根据具体情况,手动对每个小集群的Hash Slot进行定制分配。数据写入时,根据key值使用crc16算法进行hash得到一个小于16384的具体的Hash Slot(槽位),然后将数据写入到分配到该槽位的机器。
Redis Cluster优点:
- 提供海量数据的缓存:集群中可部署多个主从集群,数据根据Hash Slot的分配规则分布到不同的主从集群中。
- 缓存服务高可用:任意主节点宕机,Redis Cluster会从从节点中自动选出一个节点提升为主节点,继续提供服务。
- 主节点宕机,影响范围小:某个小集群主节点宕机,Redis Cluster将对应从节点选举提升为主节点的这段时间,整个集群中的其他主节点不会受影响,仅宕机的节点在故障恢复的这段时间不可用。影响的范围仅为所分配到的槽位的数据。
- 从节点自动分配:当Redis Cluster集群中,某一主节点的从节点宕机或断开连接,导致主从结构崩塌(即某一主节点下没有从节点),集群会自动将其他主节点下冗余的从节点自动分配到没有从节点的主节点下,增强集群的高可用性。
- 灵活扩容/缩容:当缓存数据量很大时,可以根据数据要求,灵活对集群进行拓展。数据量变小时,支持快速对集群进行缩容,节约资源。
基于Redis 6.0.9的Redis Cluster部署实践
- 更换gcc版本
安装scl源:yum install centos-release-scl scl-utils-build
安装9版本的gcc、gcc-c++、gdb工具链:yum install -y devtoolset-9-toolchain
设置版本生效:scl enable devtoolset-9 bash
设置版本长期生效: echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
- 下载安装
cd /data/redis
wget https://download.redis.io/releases/redis-6.0.9.tar.gz
tar -zxvf redis-6.0.9.tar.gz
cd redis-6.0.9
make
- 集群配置
#创建集群配置需要的目录
mkdir -p /data/redis/cluster
#创建数据存放目录
mkdir -p /data/redis/data
#创建pid文件和启动脚本存放的目录
mkdir -p /data/redis/run
cd /data/redis/cluster
#根据端口号,床架6个目录,代表集群中不同的服务
mkdir -p /data/redis/cluster/7000
mkdir -p /data/redis/cluster/7001
mkdir -p /data/redis/cluster/7002
mkdir -p /data/redis/cluster/7003
mkdir -p /data/redis/cluster/7004
mkdir -p /data/redis/cluster/7005
- 配置文件:将redis.conf拷贝一份到 /data/redis/cluster/7000目录下
cp /data/redis/redis-6.0.9/redis.conf /data/redis/cluster/7000
cd /data/redis/cluster/7000
修改7000目录下的redis.conf配置文件中的如下属性值
#改成自己的IP地址
bind 192.168.1.19
port 7000
dir /data/redis/cluster/7000
pidfile /data/redis/run/redis_7000.pid
logfile "/data/redis/cluster/7000/redis.log"
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 15000
cluster-replica-validity-factor 10
cluster-migration-barrier 1
cluster-require-full-coverage yes
cluster-replica-no-failover no
- 端口7000的配置文件配置完成,基于端口7000的配置文件,配置其他端口的配置文件。使用sed命令直接替换修改。
sed 's/7000/7001/g' /data/redis/cluster/7000/redis.conf > /data/redis/cluster/7001/redis.conf
sed 's/7000/7002/g' /data/redis/cluster/7000/redis.conf > /data/redis/cluster/7002/redis.conf
sed 's/7000/7003/g' /data/redis/cluster/7000/redis.conf > /data/redis/cluster/7003/redis.conf
sed 's/7000/7004/g' /data/redis/cluster/7000/redis.conf > /data/redis/cluster/7004/redis.conf
sed 's/7000/7005/g' /data/redis/cluster/7000/redis.conf > /data/redis/cluster/7005/redis.conf
- 配置启动脚本
- 将redis-6.0.9/utils/redis_init_script启动脚本拷贝到/data/redis/run目录并重命名为redis_7000
cp /data/redis/redis-6.0.9/utils/redis_init_script /data/redis/run/redis_7000
- 修改redis_7000如下:
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
### BEGIN INIT INFO
# Provides: redis_6379
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Redis data structure server
# Description: Redis data structure server. See https://redis.io
### END INIT INFO
REDISPORT=7000
EXEC=/data/redis/redis-6.0.9/src/redis-server
CLIEXEC=/data/redis/redis-6.0.9/src/redis-cli
PIDFILE=/data/redis/run/redis_${REDISPORT}.pid
CONF="/data/redis/cluster/${REDISPORT}/redis.conf"
case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -p $REDISPORT shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
*)
echo "Please use start or stop as first argument"
;;
esac
- 基于redis_7000启动脚本,配置其他端口的启动脚本。
sed 's/7000/7001/g' /data/redis/run/redis_7000 > /data/redis/run/redis_7001
sed 's/7000/7002/g' /data/redis/run/redis_7000 > /data/redis/run/redis_7002
sed 's/7000/7003/g' /data/redis/run/redis_7000 > /data/redis/run/redis_7003
sed 's/7000/7004/g' /data/redis/run/redis_7000 > /data/redis/run/redis_7004
sed 's/7000/7005/g' /data/redis/run/redis_7000 > /data/redis/run/redis_7005
- 启动服务
cd /data/redis/run
./redis_7000 start
./redis_7001 start
./redis_7002 start
./redis_7003 start
./redis_7004 start
./redis_7005 start
此时所有的redis还是单独以集群模式运行,但并未组成集群。
- 使用Redis提供的工具redis-cli配置集群
cd /data/redis/redis-6.0.9/src/
./redis-cli --cluster create 192.168.1.19:7000 192.168.1.19:7001 192.168.1.19:7002 192.168.1.19:7003 192.168.1.19:7004 192.168.1.19:7005 --cluster-replicas 1
- 通过客户端连接,查看集群创建情况。
./redis-cli -h 192.168.1.19 -p 7000
学习中,如有错误,请广大同行指正。