一、产生背景
上篇博客,我们了解了redis通过RDB和AOF两种方式实现数据的持久化,但是如果这台机器的硬盘出现故障,也会导致数据丢失。所以为了避免单点故障,redis提供了主从复制的操作。将数据复制多个副本存部署在不同的机器上。即使有一台服务器出现故障,其他的服务器仍然可以基础提供服务。同时这就要求一台服务器上的数据库更新之后,可以自动将更新后的数据同步到其他服务器上。Redis 提供了复制功能可以实现自动同步的功能。
二、相关配置
1.同步的数据库
同步后的数据库是分为两类,一类是主数据库,一类是从数据库。主数据库可以进行读写操作,从数据库一般是只读的,只接收从主数据库同步过来的数据。一个主数据库可以有多个从数据库,一个从数据库只能够从属于一个主数据库。(就好像,中国古代男人可以三妻四妾,但是女人只能够嫁给一个男人一样,哎)
2.怎么样建立从主复制关系?
可以通过两种方式,分别是配置文件方式和Slaveof命令方式
(1)配置文件方式
在redis中使用复制功能十分简单,只需要在从数据库的配置文件中添加“slaveof 主数据库IP 主数据库端口”,而主数据库无需任何配置。配置多台从数据库的方法也一样,在所有的从数据库的配置文件上添加slaveof参数指向同一个主数据库即可。
例如:salveof 127.0.0.1 6379
(2)使用命令slaveof
除了配置文件方式,还可以在运行时候,使用slaveof命令修改:
redis> slaveof 127.0.0.01 6379
注意:
如果该数据库已经是其他主数据库的从数据库了,slaveof命令会停止和原来数据库IDE同步转而和新数据库同步。
3.从数据库只读
默认从数据库是只读的,如果你去修改、删除从数据库的数据,会报错。(READONLY You can't write against a read only slave)
但是可以通过设置从数据库的配置文件 slave -read -only 为no来使从数据库可写,但是悲催的一点是,从数据库的任何修改都不会同步到主数据库,而且一旦主数据库做了修改,会覆盖从数据库的修改。
三、主从复制原理
1.复制过程
(1)当一个从数据库启动之后,会向主数据库发送SYNC命令
(2)主数据库收到SYNC命令手,开始在后台保存快照(即RDB持久化的过程),并且将保存期间接受的命令缓存起来。
(3)当主数据库快照完成之后,redis会将快照文件和所有缓存的命令发送给从数据库。
(4)从数据库收到之后,会载入快照文件,并且执行收到的缓存的命令。
(5)从数据库会将收到的内容写入到硬盘上的临时文件中,当写入完成之后,用该临时文件去替换旧的RDB文件。
当主从数据库连接断开之后,会重新执行上述操作,不支持断点续传。
2.主从复制详解
参考连接:Redis主从复制和集群配置
参考文章:Redis源码学习主从复制
3.注意
在同步的过程中,从数据库并不会阻塞,而是可以继续处理客户端发来的命令。
之后,主数据库的任何数据变化都会同步给从数据库,在复制的过程中,快照无论在主数据库还是在从数据库都起了很大的作用,只要执行复制就会进行快照。及时我们关闭了RDB方式的持久化(通过删除save参数)。更进一步说,无论redis是否启用了RDB方式的持久化,redis在启动过程中都会尝试读取dir和dbfinename两个参数指定的RDB文件来恢复数据库。
4.主——从(主)——从?
从数据库不仅可以接收主数据库的同步数据,而且本身也可以作为主数据库存在。形成类似图的结构。
如果所示:数据库A将数据同步到B、C中,而B中的数据也同步在D 和 E中,此时,向B中写入数据,不会同步到A、C中,只会同步给D 、E中。其实,可以看成,A是爷爷,B是爸爸,C是大爷,DE是兄弟俩,B当然会主要遗传爸爸的基因了。(当然也会遗传爷爷的,但是默认咱只遗传父亲的)
四、主从复制的好处?
(1)数据备份,保证数据不丢失,提高系统的高可用性。
(2)实现读写分离以提高服务器的负载能力。在常见的场景中,读的频率大于写,当单机的reids无法应对大量的读请求时,可以通过复制功能建立多个从数据库,主数据库只进行写操作,而从数据库负责读操作。
五、主从复制?读写分离?
一般来说,通过主从复制来实现数据同步,再通过读写分离来提高数据库的并发负载能力这样的方案来进行部署和实施的。
下图是MySql的一张读写分类和主从复制的过程示意图,觉得跟redis是一样一样的,可以参考下。
参考文章:MySQL主从复制和读写分离