在有redis基础的前提下,你肯定会发现redis真的很强大很实用,至少我是这么觉得的。废话不多说,本文将会简单说明redis集群中主从复制,读写分离的实现,以及监控运维工具sentinel的使用。
1.redis的主从配置说明
主从复制在redis中的实现非常简单,redis持久化的实现原理是rdb内存快照配合aof日志文件两种方式,本质上只需要将rdb的dump文件和aof日志文件在redis集群中共享就可以实现redis集群,从而达到负载的作用。另外redis主从有两种方式,分别是:
1)一个master跟着多个slave
2)master只跟着一个slave1,slave1跟着另外一个slave2,于此同理
两种方式相比较而言,第二种会相对好一点,因为当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信息:
可以看到role为master,且连接的slave为0个。
接着启动slave6380:
同理启动一个slave6380的客户端连接,并且输入info replication查看:
此时很明显可以看到当前6380服务器角色是slave,并且是master的IP和端口为127.0.0.1:6379.
不难理解回过头在master中再次输入info replication可以发现connectioned-slave为1.
来检验一下master和slave6380之间的数据是否同步:在master中set几个key,在salve6380中查看是否能访问得到
反过来查看一下/var/redis下的aof和dump文件:
还有一个上面设置了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
连接上分slave6381之后如上图所示,其为slave角色,且其master为6380.
在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.conf文件,做以下修改:
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
对master启动sentinel监控:
现在测试一下将master6379模拟一下宕机的情况,shutdown一下:
过了30秒之后可以看到sentienl监控如下信息:
查看此时的6381,已经被切换为master了
如果先指定哪个slave优先切换为master,可以更改各自的conf的slave优先级属性值slave-priority,默认为100.