Redis主从复制,读写分离及sentinel监控的使用

在有redis基础的前提下,你肯定会发现redis真的很强大很实用,至少我是这么觉得的。废话不多说,本文将会简单说明redis集群中主从复制,读写分离的实现,以及监控运维工具sentinel的使用。

1.redis的主从配置说明

主从复制在redis中的实现非常简单,redis持久化的实现原理是rdb内存快照配合aof日志文件两种方式,本质上只需要将rdb的dump文件和aof日志文件在redis集群中共享就可以实现redis集群,从而达到负载的作用。另外redis主从有两种方式,分别是:

1)一个master跟着多个slave

Redis主从复制,读写分离及sentinel监控的使用_第1张图片

2)master只跟着一个slave1,slave1跟着另外一个slave2,于此同理

Redis主从复制,读写分离及sentinel监控的使用_第2张图片

两种方式相比较而言,第二种会相对好一点,因为当master宕机的时候,只需要将master切换到slave1即可,redis集群中其他的slave不需要做任何改变。而对于第一种方式而言,相对来说就略微麻烦一点,因为在所有slave间选择其一作为新任master之后,剩余的slave需要指向新的master。

那接下来使用方式二进一步说明redis主从复制的配置。

此处使用了虚拟机配置了三台同一Host不同端口的redis服务器,分别是:

192.168.137.201:6379(master) 

192.168.137.201:6380 (slave1)

192.168.137.201:6381 (slave2)

2.redis主从复制读写分离的实现

从官网下载redis下来之后,在redis目录下官方自带有一份redis.conf配置文件,端口默认为6379。作为master,可以将rdb内存快照的设置屏蔽掉,交给其他slave分担此部分的IO,但对于aof日志文件则应该保留在master,因为在master和slave之间是通过rbd+aof进行数据同步的,aof的粒度细度高,而master数据肯定是最新的,所以将aof开通在master下是最适当的。所以配置master的conf关闭rdb和打开aof即可。

关闭master(6379)中的rbd快照:注释掉以下三行即可

save 900 1      // 900内,有1条写入,则产生快照 
save 300 1000   // 如果300秒内有1000次写入,则产生快照
save 60 10000  // 如果60秒内有10000次写入,则产生快照

打开aof日志功能:

appendonly yes

另外备注一下配置aof的几个选项:

appendfilename "appendonly.aof"
Aof同步三种选择方式说明:
appendfsync always   # 每1个命令,都立即同步到aof. 安全,速度慢
appendfsync everysec # 折衷方案,每秒写1次
appendfsync no      # 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof. 同步频率低,速度快,
no-appendfsync-on-rewrite  yes: # 正在导出rdb快照的过程中,要不要停止同步aof
auto-aof-rewrite-percentage 100 #aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb #aof文件,至少超过64M时,重写

另外将端口为6380和6381的两台slave的conf文件(此处为了便于区分,分别取名为redis6380.conf和redis6381.conf)中的slaveof master host port打开,之后设置为slaveof master 192.168.137.201 6379。这样设置之后,就已经是将6380设置成是6379的slave,而对于6379而言,默认即为master角色。由于master的rdb功能关闭了,需要在其中一个slave中打开rdb功能,另外为了避免redis集群中数据不同步,需要将slave设置为只读,由master负责可读可写,而slave仅能读取,这样就即能保证redis集群中的数据同步,又可以实现redis的读写分离。

设置6380的conf文件:打开rdb,关闭aof,并且设置为只读和设置成6379的slave。

port 6380
pidfile /var/run/redis_6380.pid
dbfilename dump6380.rdb
dir /var/redis/
save 900 1      // 900内,有1条写入,则产生快照 
save 300 1000   // 如果300秒内有1000次写入,则产生快照
save 60 10000  // 如果60秒内有10000次写入,则产生快照
appendonly no # 是否打开 aof日志功能
slaveof 127.0.0.1 6379
slave-read-only yes

启动master:

./bin/redis-server ./redis.conf

在/var/redis目录下可以看到自动生成了一个appendonly.aof文件。启动一个客户端连接6379服务器./bin/redis-cli -h 127.0.0.1 -p 6379 ,接着输入info replication查看master信息:

Redis主从复制,读写分离及sentinel监控的使用_第3张图片

可以看到role为master,且连接的slave为0个。

接着启动slave6380:


同理启动一个slave6380的客户端连接,并且输入info replication查看:

Redis主从复制,读写分离及sentinel监控的使用_第4张图片

此时很明显可以看到当前6380服务器角色是slave,并且是master的IP和端口为127.0.0.1:6379.

不难理解回过头在master中再次输入info replication可以发现connectioned-slave为1.

Redis主从复制,读写分离及sentinel监控的使用_第5张图片

来检验一下master和slave6380之间的数据是否同步:在master中set几个key,在salve6380中查看是否能访问得到



反过来查看一下/var/redis下的aof和dump文件:

Redis主从复制,读写分离及sentinel监控的使用_第6张图片

还有一个上面设置了slave为只读状态,测试一下往slave中写入是否能成功:


上图很好的表明了到此步之后已经设置好了redis的主从复制,以及读写分离。

同理的另外一个6381slave配置和6380差不多,将6381的rdb也关闭了即可:

port 6381
pidfile /var/run/redis_6381.pid
dbfilename dump6381.rdb
dir /var/redis/
#save 900 1      // 900内,有1条写入,则产生快照 
#save 300 1000   // 如果300秒内有1000次写入,则产生快照
#save 60 10000  // 如果60秒内有10000次写入,则产生快照
appendonly no # 是否打开 aof日志功能
slaveof 127.0.0.1 6380
slave-read-only yes

Redis主从复制,读写分离及sentinel监控的使用_第7张图片

连接上分slave6381之后如上图所示,其为slave角色,且其master为6380.

Redis主从复制,读写分离及sentinel监控的使用_第8张图片

在slave6380中又可以查看出其为slave为角色,并且其master为6379,还有6381又是其slave。

测试6381slave是否同步数据:


至此,通过配置文件conf配置redis主从复制到此就顺利成功了,另外如果希望在不断开redis运行的状态下更改master和slave,还可以是config命令来实现:

修改一天slave为master

1)设置该redis不做其他redis的slave

命令:slaveof no one

2)修改其为readonly为no

其他的slave再指向新的master

命令:slaveof ip port


3.sentienl监控的使用

sentienl的作用就是在master宕机的时候,由sentienl来切换新的master。

其工作原理是:在指定的连接超时次数时,确认master为宕机状态,根据slave的优先级,选择优先级最高的slave,将其更改为master,并且将其他的slave改为指向该新的master上。

sentienl的几个配置参数:

sentinel monitor def_master 127.0.0.1 6379 1  
sentinel auth-pass def_master 密码 
##master被当前sentinel实例认定为“失效”的间隔时间  
##如果当前sentinel与master直接的通讯中,在指定时间内没有响应或者响应错误代码,那么  
##当前sentinel就认为master失效(SDOWN,“主观”失效)  
##   
##默认为30秒  
sentinel down-after-milliseconds def_master 30000  
  
##当前sentinel实例是否允许实施“failover”(故障转移)  
##no表示当前sentinel为“观察者”(只参与"投票".不参与实施failover),  
##全局中至少有一个为yes  
sentinel can-failover def_master yes  

其中需要特别说明的是最后一个sentinel can-failover mastername yes参数,这个在2.6版本之前需要指定这个参数,其作用是在多个sentinel存在的时候,发挥作用切换master时谁具有能力去切换。在2.8版本之后就不需要再指定这个参数了,因为本来这个参数只需要随便一个,有一个sentienl来执行就行。

为了更好的演示sentienl的效果将slave2也指向6379,先断掉所有redis进程:


更改slave6381的conf文件,然后启动三台服务器。查看master状态:

Redis主从复制,读写分离及sentinel监控的使用_第9张图片

在下载下来的redis目录下也带有一份sentinel.conf文件,做以下修改:

sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1

对master启动sentinel监控:

Redis主从复制,读写分离及sentinel监控的使用_第10张图片

现在测试一下将master6379模拟一下宕机的情况,shutdown一下:


过了30秒之后可以看到sentienl监控如下信息:

Redis主从复制,读写分离及sentinel监控的使用_第11张图片

查看此时的6381,已经被切换为master了

Redis主从复制,读写分离及sentinel监控的使用_第12张图片

如果先指定哪个slave优先切换为master,可以更改各自的conf的slave优先级属性值slave-priority,默认为100.

你可能感兴趣的:(分布式)