原创

Redis深入学习—易伸缩,高可用的集群模式架构

1. 集群模式的高可用

前几篇文章我写了redis的主从模式和sentinel模式,主从模式没有高可用特性,而sentinel模式有高可用的特性,sentinel模式的高可用包括监控节点sentinel集群的高可用以及redis主节点的高可用。

redis主节点的高可用是依赖sentinel集群的高可用的,因为redis主从架构的故障发现和故障转移都是由sentinel集群完成的,redis主节点恢复的时间非常快,不需要人工介入。

集群模式的高可用也是类似sentinel集群的方式,只不过cluster模式下有多个主节点,而且故障发现和故障转移的工作都是由redis主节点集群完成,只要主节点下线,就会被其他主节点感知到,然后选出领导者节点主导主节点的从节点完成工作。

master集群中每个master都有从节点,如果某个master节点挂掉,redis cluster机制就会选择它的一个从节点切换成master。

那么高可用这一种特性就够了吗?sentinel模式已经有了高可用特性,那为什么还需要cluster特性呢?

如果项目只是需要几个G的容量,主要承载高并发高性能的场景,那么单机模式就足够了

项目的读请求量明显比写请求量高很多量级,这时候就需要redis的主从模式了,让多个从节点承担读的请求压力。

如果项目需要redis的高可用,保证redis缓存的数据时刻能使用,那就需要sentinel模式。主从集群保证redis主节点数据能获取到,也能写进去。

当读写请求量非常高,sentinel模式的主节点已经无法满足产品的写请求量的时候,我们就需要对主节点的并发能力进行扩展,一般cluster模式用于海量数据+高并发+高可用的场景。

2. 集群模式的易伸缩

redis集群模式一般使用在高并发+高可用+高性能的海量数据场景,redis集群模式具有易伸缩特性,支持系统在访问量突增的时候能扩充主节点,提高系统的访问能力;在系统访问量小的时候,也可以移除主节点集群中的部分节点,节省服务器的费用。

redis cluster机制的一些概述:

slot数据:每个master节点都绑定部分slot,master维护着所有的节点和slot的映射关系。

路由机制:每次来一个命令,都会先对key进行一次hash计算,得到相应的slot值,然后对比slot映射关系,计算得到相应slot对应的master节点,然后通知客户端将命令发往该节点去执行,其中着包含了key的重定向机制。

master节点的扩充和收缩:每次主节点的扩充,都会将slot映射元数据分配给新的master节点,收缩的时候会将slot映射范围还给其他master节点。

因此,正式redis的这种设计和路由机制,才使得redis具有易伸缩的特性。

3. 集群模式的工作原理概述

集群模式下,客户端发送命令到任意一个master节点的交互流程图:
alt

1)redis客户端发送命令到集群内的任意一个master节点

2)master节点对命令的key值进行hash计算,得到该key的slot值,再将slot值比对slot与master节点集合的映射关系,最终找到这个key的存储redis目标节点。

3)如果目标节点就是该master节点的话,就立刻执行redis命令。

4)目标节点不是该master节点,立刻通知客户端将命令发送到目标节点上去。

故障发现


所有分布式系统框架保持高可用的一个重要方法就是能及时发现集群内的故障节点,绝大部分系统使用的都是心跳检测机制,如负载均衡服务器对应用服务实例的心跳检测,分布式服务注册中心对已注册服务定期的心跳检测,sentinel监控集群的定时心跳检测机制等等,这些都是通过定期的心跳检查来发现故障节点。

redis节点之间的心跳检测使用的是ping命令,如果被检查正常则回复pong命令,如下图:

alt

4. 搭建集群模式

这是redis集群模式简单的搭建脚本,只要在linux主机上执行就能搭建完成。

##1、在/root/test/目录下创建目录7001 7002 7003 7004 7005 7006 以及env
##7001~7006目录用来存放redis的配置文件redis.conf,env用来存放生成的公共配置文件redis-env.conf


for ((i=1;i<=6;i++))
do
mkdir -p /root/test/700${i} /root/test/env
done


##2、进入env目录

cd /root/test/env

echo -e "port 7001\ncluster-enabled yes\ndir /root/test/7001\ncluster-config-file nodes-7001.conf\npidfile "/root/test/7001/redis-7001.pid"\nlogfile "/root/test/7001/redis-7001.log"\nappendonly yes\nprotected-mode no" > "redis-env.conf"


##3、拷贝公共配置文件redis-env.con 到7001~7006目录下,并根据端口修改7001

for ((i=1;i<=6;i++))
do
cp /root/test/env/redis-env.conf /root/test/700${i}/redis.conf
sed -i "s/7001/700${i}/g" /root/test/700${i}/redis.conf
done


##4、下载安装redis
##检查wget


check_results1=`rpm -qa | grep "wget"`
if [[ $check_results1 =~ "wget" ]]
then
    echo "package wget has already installed. "
else
    echo "This is going to install package wget"
        yum install wget -y
fi
cd /root/test


##安装redis

wget http://download.redis.io/releases/redis-5.0.5.tar.gz

##解压安装包

tar -zxvf redis-5.0.5.tar.gz

##编译

cd /root/test/redis-5.0.5
make

##如果你不想在执行redis脚本时候进入 redis目录,你可以在linux上安装redis
##make install

cd /root/test/redis-5.0.5
echo 'print path'
pwd


##5启动redis各个节点

for((i=1;i<=6;i++))
do
./src/redis-server /root/test/700$i/redis.conf &
sleep 1
done
cd /root/test/redis-5.0.5
sleep 1


##创建集群
##192.168.3.9 是我局域网内的一台电脑ip,你可以安装在本地 127.0.0.1
##redis 安装在多台主机上的脚本见文章内容分享

./src/redis-cli --cluster create --cluster-replicas 1 192.168.3.9:7001 192.168.3.9:7002 192.168.3.9:7003 192.168.3.9:7004 192.168.3.9:7005 192.168.3.9:7006

执行脚本: sh cluster.sh

脚本下载

5. 集群模式测试

脚本执行完成后,登入其中一个7002节点

redis-cli -c -h 192.168.3.9 -p 7002
alt

查看redis集群信息:cluster nodes

alt

可以看到主节点端口分别是7002,7003,7005。

在主节点上执行命令:get hello
alt

可以看到客户端连接的是7002节点,但是因为key=hello,所以7002告诉客户端重定向到7005。

因此,redis-cli客户端此时连接的是7005节点。整个过程,redis的路由和hash值计算机制就发挥了作用。

6. 集群模式架构优缺点

目前以我对redis的调研来看,redis的集群机制已经具备了技术上的可贵的指标:高可用,高并发,易伸缩,海量数据,从技术角度来看,是没有任何缺点的。但是如果从成本的角度来看,因为cluster模式下,从节点只是作为热备节点来用,没办法进行读,所以主节点越多,从节点也会相应的增加,这样就会需要使用很多的服务器,消耗很多服务器资源。

7. 简单谈谈我对集群模式架构的理解

作为开发人员,如果是使用redis集群模式,当然都愿意,但是是作为技术管理者,成本控制也是管理的日常工作,如果我们的项目需要数据要一直能被访问到,且性能要求也非常的高,那么对于服务器成本而言,我们会选择项目的这些特性。因此,作为技术管理人员,可以根据自己团队项目的需要来选择合适的技术架构。即所谓的技术选型。

正文到此结束
本文目录