redis的作用就不多介绍了,redis的原理相信也有很多文章。我这边的分享就直接分享一下实际业务使用的哨兵模式和集群模式。还有他们有什么不同,哪种业务场景应该用哪一种模式。
这一篇先来说哨兵模式,集群模式放在第7集。开始聊这个之前,有一个点比较重要,要保证各位的redis版本在6.0以上,因为有一个非常重要的配置,关乎到你运维的配置是高版本才有的,就是redis对于hostname配置的处理方式。发文这会,redis在github和hub.docker的最新的稳定版本去到7.0.11。各位尽量关注一下所使用中间件的版本,还有每个版本的升级都更新了什么,适当升级才能让我们的系统更加可持续的发展。然后我们继续往下看。
要说redis的哨兵模式,那首先就要先说一下主从模式,主从模式是什么呢,举个例子,譬如我们现在又3台服务器,分别是01、02、03。我们在01那台机启动一个redis实例,然后02、03两台机器也分别启动一个redis实例,但是02、03的实例在配置文件里面指定01为主节点,这样02、03两个实例自然而然就变成了从节点。主从模式在主节点失效的时候,它们是不会自己将从节点提升为主节点的,这样整个redis服务将会失去写功能。哨兵模式就是在主节点失效的时候,可以自动将从节点提升为主节点的一种模式。
在主从模式下,只有主节点能同时读写,从节点只能读,并且从节点会定期同步主节点的数据。这样可做到读写分离,提高整个redis服务的可用性。
在主从模式下,redis主节点出现问题,整个redis服务就只剩下读的功能了,写功能失效了。这样对于我们的业务来说肯定致命的,因此哨兵模式就出现了。哨兵模式并非改变整个redis实例的部署结构,而是为了解决主从模式主节点失效的问题而出现的。我们可以将哨兵模式看作两个部分,主从模式的redis+哨兵。这两块是分开,互相独立的,没有哨兵,我们的主从模式redis服务也是可以正常使用的。
哨兵是什么,哨兵是redis的其中一种功能,也是一种redis服务,只是它提供的不是存储服务,而是调度服务。同样我们也是启动redis实例,但是启动的时候,指定为这一个实例的启动是哨兵模式,并且启动的时候指定我们的redis服务的主节点地址。这样哨兵就能监控我们的redis服务了。哨兵也可以启动多个实例,每一个实例都必须指定我们的redis服务的主节点地址。
现在我们手上有了主从模式的redis服务+哨兵,也知道了哨兵是什么了。那哨兵是不是只做监控的功能呢,并不是,哨兵还提供一个非常重要的功能,那就是选举功能。在主节点失效的情况下,哨兵可以发送指令给主从模式的redis服务,将从节点提升为主节点。有了这一个功能,那是不是就解决了主从模式下主节点失效,整个redis服务写功能跟着失效的问题了,这就是哨兵模式。
哨兵模式需要指定主节点的地址,上面也提到了,从节点启动的时候,需要指定主节点的地址,还有一个配置,无论主节点还是从节点,redis实例启动的时候,都需要配置自己广播出去的地址和端口。这是什么意思呢,就是需要告诉别的节点,自己所在的服务器的地址,可以是域名,也可以是ip,譬如,01的机器上的redis服务,广播出去的地址就需要写01机器的地址,02的机器上的redis服务,广播出去的地址就需要写02机器的地址。
现在,主从节点都有了广播的地址,从节点也指定了主节点的地址,这样我们的哨兵在连接主节点的时候,就能从主节点那里取得主从节点的地址了,并且哨兵也能知道到底谁是主节点,谁是从节点了。这些信息都是哨兵在连接主节点的时候获得的,并且会将这些信息持久化到哨兵服务自己的文件里面。
上面配置了redis服务主从节点的广播地址,现在到哨兵群了,哨兵群也是需要配置广播地址的,因为需要知道整个哨兵群一共有多少个实例,而且每一个哨兵实例都分别在哪里嘛。这样,我们的需要交互的信息,就都配置好了。配置好之后,哨兵会定时向所有redis节点发送ping指令,以此来鉴别redis节点是否存活,假设主节点现在ping不通了,哨兵会向redis群发送主从节点的设置指令,将从节点提升为主节点。所以其实,哨兵就像一个大脑,是负责发送指令的,哨兵和redis群是相互独立的,没有哨兵,只是需要人工参与手动去设置redis服务群的主从而已,但是这样就不能很好的保证服务的可用性了。所以哨兵模式是我们日常比较常用的一个模式。
接下来我们开始搭建,也是需要3台服务器,主从模式我们以一主二从来做例子,当然一主N从也是可以的,那就看每个业务的情况来决定了。文章开始的时候提到,我们哨兵的redis镜像是需要在6.0以上的,因为6.0以上才开始支持域名的配置,否则即使redis服务群里面广播的地址写的域名,哨兵持久化主从节点信息的时候,还是会将域名解析为地址的。这样我们外网客户端连接哨兵的时候,哨兵群会给到我们的客户端一个内网地址的ip,这样外网的客户端就连接不上了,这样运维是非常不方便的,当然如果确定只需要在内网的服务内部使用,那是无所谓的,反正就是所有对于redis的操作都需要登陆到服务器使用redis-cli去操作而已。
为了表达出哨兵群和redis服务群是两个独立的服务,我redis群镜像用5.0.8版本,哨兵群镜像用6.2版本。接下来,我们先搭建主从模式redis服务,配置我选择用redis.conf配置的方式,意思就是一切配置都写在redis.conf这个文件里面,启动镜像的时候配置指定以这一个文件配置为准。因此我们的docker-compose.yaml其实没什么好写的,3台机器都一样即可。图片内从左到右分别是01、02、03机器,顺着看就可以了,我们以01机器作为主节点。
docker-compose.yaml:
version: '3'
services:
redis:
image: redis:5.0.8
container_name: docker_redis
privileged: true
volumes:
- ./volumes/data:/data
- ./volumes/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./volumes/logs:/logs
command: ["redis-server","/usr/local/etc/redis/redis.conf"]
ports:
- 9062:6379
environment:
- TZ="Asia/Shanghai"
接下来,看一下3份redis.conf有什么不同,其实也就是01的配置稍微有点不同,02、03的配置是一样的,因为都是从节点。
按照习惯,我们也是先创建好文件夹volumes。
配置文件我们放在volumes/conf里面,docker-compose.yaml文件里面自己写好挂载即可。
接下来我们看一下redis.conf的内容,我会用:set nu来显示出行,可以对着行号看。
首先提一下,就是我们的port端口,这个其实是不用改的,因为这个文件其实是和容器内的redis配置互相挂载了,因此对于端口来说的其实指的是容器内的redis端口,我们在外部做了映射,所以port 是不需要改的,就保留6379就可以了。
接下来往下看,一直找到replicaof这个属性,字面意思就是,从什么地方复制,所以这里配置的是主节点的地址,可以看见我这里写的是test01的地址,而01这台机器是注释掉的,因为他本来就是主节点,所以不需要写。
再往下找到masterauth这个配置,这里写的是主节点的密码。当然如果主节点没有配置密码,那这里就不需要写。
再往下找到replica-announce-ip和replica-announce-port,这里配置的就是广播的地址,意思就是,你向外广播你是谁的时候给出去的地址,所以这里写的是各自本机器的地址。这里如果有外网访问要求,请写域名,不要写内网ip,否则之后哨兵拿到的就是内网ip,然后给到你的外网客户端也是这一个内网的ip。那就连不上了。
redis的配置就这么多,之后就出去外面docker-compose up -d启动就好了,但是启动需要有顺序,先启动01主节点的,然后再启动02、03两个从节点的。毕竟两个从节点是写了主节点的ip去找主节点的,如果同时启动或者先启动从节点,那就找不到主节点了。
然后我们进入docker容器内部,redis-cli -p 端口 -a 密码进入redis命令行,输入info replication
就能看见主从节点的信息了,至此主从模式的redis服务就搭建完成了,我这里由于已经是验证过01那个主节点掉线的情况,所以已经被自动切换到02了,大家知道01是主节点就行。
下一步就是我们哨兵的搭建了,哨兵有一个配置文件sentinel.conf,这个文件和redis.conf一样,也是可以从redis的github里面找到的,大家打开github里面redis的项目,搜索一下这个文件,就能知道有什么属性了。
接下来说说这里面其中几个必须的属性,其他的属性各位看example文件解释就可以。
首先,我们先新建我们的文件夹,这里有一个点要注意,我们挂载文件虽然只有一个,sentinel.conf,但是我们docker-compose.yaml里面的volumes挂载不能直接用容器内的配置文件挂载到宿主机的配置文件,需要放在文件夹内,以容器内文件夹挂载到宿主机文件夹这样的方式。
接下来我们看一下我们的sentinel.conf文件配置了什么属性。
我们一个一个来讲。
1. sentinel monitor 集群名 主节点地址 主节点端口 客观下线的哨兵数
例子:sentinel monitor mymaster xxx.com.cn 6379 2
这一个配置是指定redis服务的主节点的配置,这个作用是什么就很明显了
2. sentinel auth-pass 集群名 主节点密码
例子:sentinel auth-pass mymaster mypassword
这是主节点的访问密码,客户端都需要配置密码才能访问,哨兵没有密码怎么访问呢是吧。毕竟说了几遍,他们是独立的嘛。
3. sentinel announce-ip "对外广播的地址"
例子:sentinel announce-ip "xxx.com.cn"
这一个广播地址和redis的广播地址不一样哦,这一个广播地址是用于哨兵之间的通讯的广播地址。
4. sentinel resolve-hostnames yes
这个配置非常重要,这一个是redis6.0版本才新增的一个配置,意思很清楚了,可以使用hostname,不然6.0以下的版本会将hostname解析为ip地址,然后持久化到你的sentinel.conf文件上面的。
5. sentinel announce-hostnames yes
这个同理
以上几个是必要的配置,更多配置请参考github上面的redis项目给出的sentinel.conf实例文件。
配置好这个文件之后,出去外面docker-compose up -d就可以启动你的哨兵了。
注意:哨兵启动之后,会生成一些关于其他节点的信息,持久化到你的那个sentinel.conf文件里面的,然后文件的用户会变成你docker的用户。我这边是root。这一点要注意。
最后启动完之后,就可以用客户端访问我们的哨兵,就可以连接到我们的redis服务啦。
test01、test02、test03是我们的redis服务群,访问主节点是有写key 的功能的,从节点如果写key会报错。
下面test01-sentinel、test02-sentinel、test03-sentinel 就是我们的哨兵,都是可读可写的,因为他们只负责发送指令给redis服务群,并非真正的redis服务。实际使用的时候是使用它们去连接我们的redis服务群。redis服务群节点出了问题也是由它们负责选举选出新的主节点。
那什么时候该用哨兵模式,什么时候该用集群模式呢。一般业务来说,其实平时数据量不大或者key的种类很复杂,或者各个业务的key需要分开redis数据库来存放的业务,一般就是用哨兵模式来做我们一些简单的缓存的。
集群模式则是应对比较庞大数据量的读写,结构比较单一,对redis数据库的选择没有要求(因为集群模式只有db0)的业务,会选择集群模式比较好。
至此,我们的哨兵模式的redis就搭建成功啦,其实这个还挺简单的,下一篇我们讲一下redis的集群模式,以及集群模式的原理。