最近在看付磊,张益军老师的《Redis开发与运维》。学到了很多,也遇到了很多坑,这里我想把比较重要的主从复制这一章节,我把自己的理解与实践记录下来,方便自己的学习,也为社区做一点贡献。

(1):一主二仆

概念:

主从复制最经典的结构就是"一主二仆"。即一个master主机,两个slave从机。一个master主机负责写入数据,而两个从机slave只负责读数据,真正实现了读写分离。在高并发下减轻了一台redis的压力。

图片描述

部署:

1:首先我们先开启三台redis服务器。端口分别为665,666,667

图片描述

2:其次将666, 667端口的服务器挂在665 master主机上。

具体可以用这个命令设置:slaveof host port (eg.. SLAVEOF 127.0.0.1 665)。最终结果如下图

图片描述

图片描述

图片描述

(2)哨兵

现在出现了一个问题啦。如果master在夜晚凌晨突然宕机了,怎么办怎么办????而我们的开发人员都还在睡觉呢???

此时出现而哨兵可以进行巡逻,发现问题然后解决问题???这句话怎么这么熟悉

1:首先建立一个名为 sentinel.conf 的配置文件。

sentinel monitor host12581 127.0.0.1 667 1

// sentinel monitor 哨兵名字 监控ip地址 监控端口号 投票超过多少才当选为leader

sentinel failover-timeout host12581 1800 // 投票失败后多少秒后进行重拾 默认30s
sentinel auth-pass host12581 changwenbo // 密码

2:其次用 redis-sentinel sentinel.conf 启动即可。

启动后他就会自动巡逻监控redis端口为665master,和666,667slave的服务器
3:此时我突然kill掉端口为665的master主机。
通过查看日志,我在 12580:M 16 May 14:59:23.294 # User requested shutdown... 59分23秒的时候shutdown掉了665master机子。

图片描述

是不是可以看出来,在23秒宕机后,哨兵在30s后,即53秒立刻发现了master已经连接不上出现了问题。

首先进行了投票选举,谁得到的票多,谁就成为新的老大,带领大家。可以看出来667当选了。然后他就成功当选了master,并且有了一个666的slave的小弟。
4:那突然此时已经宕机的665杀回来怎么办?
图片描述

通过看日志,明显可以看出来,在04分46秒我开启了665服务,在47秒哨兵侦测到。然后跟665旧的master说,不好意思,我们已经又老大了,老大是667,你去当667的小弟吧。最后665就是667的小弟了。最后的结果为:

图片描述

最终哨兵完成了自动化部署,减轻了开发人员的压力,你好我也好。

(3)总结与问题:

问题:当我开启哨兵以后,master主机宕机以后,哨兵并没有起作用,日志大概就是不能发现slave,不知道确定哪个slave当选master。经过不写努力的检查,发觉配置文件里面的这一句话:

################################## NETWORK ##################################### # By default, if no "bind" configuration directive is specified, Redis listens # for connections from all the network interfaces available on the server. # It is possible to listen to just one or multiple selected interfaces using # the "bind" configuration directive, followed by one or more IP addresses. # # Examples: # # bind 192.168.1.100 10.0.0.1 # bind 127.0.0.1 ::1 # # ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the # internet, binding to all the interfaces is dangerous and will expose the # instance to everybody on the internet. So by default we uncomment the # following bind directive, that will force Redis to listen only into # the IPv4 lookback interface address (this means Redis will be able to # accept connections only from clients running into the same computer it # is running). # # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES # JUST COMMENT THE FOLLOWING LINE. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
用我的渣英文翻译大概如下:
默认的,如果没有bind的配置指令,redis监听服务上的所有连接,如果你仅仅监听一个或者多个的话,bind的配置,按照如下的一个或者多个ip的方式
警告:如果电脑上的redis直接暴露给网络,绑定所有的了地址是危险的并且将会暴露给在网路上的每一个人。所以我们默认的取消注释,强制的配置了一个IPV4的回环地址。(那就意味着在redis运行时只可以接收来自本电脑的连接)。
但是:我的Java客户端连接远程的redis必须要把bind注释掉,那么所有网络外网均可访问。但是这样的话,当master挂掉之后,哨兵需要连接到slave,那么必须指定为localhost,负责找不到slave。亲测必须不能注销掉bind 127.0.0.1众所周知,校园网是没有ip的,只有一个全局ip通过NAT分配端口,实现联网的。那么如何配置只有特定的ip可以连接redis呢?
这里我必须把bind注销掉才可以远程连接,但哨兵正常工作又不能注销掉bind的,惆怅啊。有大佬能给一个不错的解决方案么?
总结:
redis是一个强大的缓存系统,有很多很不错的功能,搞得想看其中的源码了。但我一个Java程序员完全不懂C++那一套指针跑来跑去的。还有这个主从复制服务器我知道怎么配了,但客户端还不是很清楚,还需要继续学习。如何配置多端口的redis,挂掉了怎么实现客户端自动切换端口等一系列操纵。