redis的主从(master-slave)
-
单点redis服务器的弊端
单个服务器的情况下,如果这个服务器发生故障,那数据肯定就GG了。整个服务器要承受所有的请求负载(毕竟我们还是要做负载均衡嘛)
所以redis提供了复制功能(replication)功能。将数据库复制多个副本,然后放在不同的服务器上(放在一个服务器上,就是不同的redis实例咯)。这样即使一台数据库出现故障,其他的还是能提供服务。
redis复制中,数据库有两种,一种就做主数据库(可读可写),另一种叫做从数据库(一般就是只读的,但是可以接受从主数据库同步过来的数据)。就像这个样子:
windows下配置多个redis实例
首先进入redis的安装目录,复制redis.windows-service.conf文件,改名为例如redis.windows-service-6380.conf,修改里面的port和logfile(一定要修改,总不能所有的redis要一份日志文件吧?),在然后进入win32控制台,执行下面这条命令(E:\redis1是我的安装目录):
将这个redis实例配置成服务,下次你就可以直接启动该项服务了。
然后尝试连接新配置的redis实例:
接下来配置主从:修改配置文件,在配置文件中加上slaveof参数执行主数据库就好了或者在运行的时候直接通过命令行配置。
如果当前从数据库已经和一个主数据库同步了,slaveof命令会停止与先前的主数据库同步,转而与新的主数据库同步。还可以使用slaveof no one使得当前数据库升级为主数据库。
Master-Slave的原理
当一个从数据库启动后,会向主数据库发送sync命令。主数据库接收到命令之后会在后台(fork当前进程)进行RDB快照,以及缓存执行快照期间执行的命令,当快照完成之后,将数据发送给从数据库。从数据库接收到数据之后,将数据写入临时文件中,写入完成之后,用新的RDB文件替换旧的RDB文件,接下来RDB持久化启动恢复,再接着执行缓存的命令。至此,复制初始化的过程完成。从此以后,主数据库每当执行写命令时,会将该命令发送给它的所有从数据库,从而完成数据同步。
注意:即使主从数据库同步,在一定时间窗口,还是存在主从数据库不一致。
redis主从配置完成之后,这样即使一台服务器崩溃之后,还是有其他服务器提供服务(提高系统整体的容灾能力),同时做到了读写分离。-
redis的增量复制
在master-slave模式中,如果从数据库与主数据库掉线,那么就要重新发送sync命令进行数据同步。这时主数据库就不得不重新进行快照(I/O操作)并重传,仔细想想还怪费时的,这个时候只重传在此期间执行的命令就好了。所以redis2.8提供了增量复制的功能。
增量复制实现:
- 1.从数据库会存储主数据库的run id。每个redis实例都有一个,重启之后就会又生成一个新的run id
- 2.在复制同步阶段,主数据库每将一个命令发送给从数据库时,都会同时把命令放进一个积压队列中(backlog)中,并记录存放的命令的偏移量范围。
- 3.从数据库接收到命令之后,会记录该命令的偏移量。
首先主数据库判断从数据库传过来的run id是否和自己相同,相同的话再判断从数据库最后同步成功的命令偏移量是否在积压队列中,在就执行增量复制。两个条件不同时满足的话就进行一次全部同步。
执行info replication会显示积压队列相关信息: