1.复制
通过持久化功能,Redis保证了即使在服务器重启的情况下可以减少数据的损失,但是出现单点故障也会让数据丢失Redis不可用。所以Redis提供了复制功能,可以实现一台数据库的数据更新后,自动将更新的数据同步到其他的数据库上。
2.配置主从数据库
在复制的概念中,数据库分为两类,一类是主数据库,另一类是从数据库。主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步到从数据库中。而从数据库一般都是只读的,并接受主数据库同步过来的数据。一个主数据可以拥有多个从数据库,但是一个从数据库只能拥有一个主数据库。
使用复制功能非常容易,只需要在从数据库配置文件中加入“slaveof 主数据库地址 主数据库端口”即可,主数据库无须配置。
由于我是一台电脑上演示,所以需要开两个端口。通过以下代码可以运行一个新的redis实例,并作为从数据库监听6379端口的主数据库:
C:\Users\Xu>redis-server --port 6380 --slaveof 127.0.0.1 6379 [4716] 19 May 19:59:02.702 # Server started, Redis version 3.2.100 [4716] 19 May 19:59:02.702 * The server is now ready to accept connections on port 6380 [4716] 19 May 19:59:02.717 * Connecting to MASTER 127.0.0.1:6379 [4716] 19 May 19:59:02.717 * MASTER <-> SLAVE sync started [4716] 19 May 19:59:03.061 * Non blocking connect for SYNC fired the event. [4716] 19 May 19:59:03.061 * Master replied to PING, replication can continue... [4716] 19 May 19:59:03.061 * Partial resynchronization not possible (no cached master) [4716] 19 May 19:59:03.061 * Full resync from master: aae1b76beff63e123b9213737dbc5a2004e34242:1 [4716] 19 May 19:59:03.327 * MASTER <-> SLAVE sync: receiving 123 bytes from master [4716] 19 May 19:59:03.327 * MASTER <-> SLAVE sync: Flushing old data [4716] 19 May 19:59:03.327 * MASTER <-> SLAVE sync: Loading DB in memory [4716] 19 May 19:59:03.327 * MASTER <-> SLAVE sync: Finished with success
可以看到后面运行结果显示主数据中的数据已经被同步到从数据中了,我们打开Redis Desktop Manager可以查看到从数据库中同步到的数据,往6380端口的主数据库操作数据,从数据库也会同时变化数据。
通过设置从数据库配置文件中的slave-read-only为no可以使从数据库可以写,但是为了避免造成潜在的应用逻辑的错误,一般从数据库是不可写的。
通过slaveof命令还可以在运行时修改监听的主数据库,如果该数据库已经是其他主数据库的从数据库时,该命令会中止与原主数据库的同步,转而和新监听的主数据同步。还可以通过slaveof no one命令使当前数据库停止接受其他数据的同步,转为主数据库,原主数据库转为从数据库。
127.0.0.1:6379> slaveof no one OK
从数据库不仅可以接收主数据库的同步数据,自己也可以作为主数据库存在,并且数据会向下同步。
3.原理
当一个从数据库启动后,会向主数据库发送sync命令。同时主数据库接收到sync命令后会开始在后台报错快照,并将保存快照期间接收到的命令缓存起来。当快照完成后,redis会将快照文件和所有的缓存命令发送给从数据库。从数据库接收到后会加载快照文件并执行收到的缓存命令。以上使复制初始化的过程,当完成初始化后,主数据库每当收到写命令时就会将命令同步给从数据库,从而保证主从数据库的数据一致。
当主从数据库直接连接断开重连后,redis2.6以及之前的版本会重新进行复制初始化,这使得主从数据库断线重连后的恢复过程效率低下。在redis2.8版本后支持了断线重连后的增量数据传输,当从数据库连接上主数据库后,主数据库只需要将断线期间执行的命令发送给从数据库就可以了,提高复制的实用性。
redis采用了乐观复制的复制策略,允许容忍一段时间内主从数据库的内容是不同的,但是两者数据最终会同步。