这是我参与更文挑战的第2天,活动详情查看: 更文挑战
Redis的多机方案主要分为3种:复制、哨兵和集群。本文我们主要讲复制 replicate
复制 replicate
通过执行slaveof命令或设置slaveof参数,让一台服务器复制另一条服务器,被复制的为主服务器master,复制的为从服务器slave。
在从服务器客户端执行:
# slaveof <master_ip> <master_port>
slaveof 127.0.0.1 6379
复制代码
或在从服务器的配置文件redis.conf中配置:
slaveof <master_ip> <master_port>
或在启动从服务器redis-server的启动命令后加入 –slaveof <master_ip> <master_port>
同步和命令传播
Redis的复制分为同步和命令传播两个操作。
同步操作的主要步骤:
- 从服务器向主服务器发送sync命令。
- 主服务器收到sync命令后执行bgsave命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始的所有写命令。
- 当主服务器的bgsave命令执行完毕,会将生成的RDB文件发送给从服务器,从服务器载入这个文件,将数据库库状态同步到主服务器执行bgsave命令时的状态。
- 主服务器将缓冲区里的所有写命令发送给从服务器,从服务器执行,同步完成。
命令传播是客户端对主服务器的数据库状态进行修改时,主服务器对从服务器进行命令传播操作,使数据库状态保持一致。
Redis2.8的改进
从服务器对主服务器的复制主要分为以下两种场景:
一是初次复制,一是断线后重复制。
而在redis2.8之前,断线后的重复制,是让主服务器重新执行一次sync命令,这显然是十分低效的做法。因为sync命令十分消耗资源。
redis2.8开始,使用psync命令代替了sync命令来执行复制时的同步操作。
psync命令有完整重同步和部分重同步两种模式。完整重同步和之前的没什么不一样,而部分重同步则正是为了解决断线后复制低效的问题,它是让主服务器将断线期间的写命令发送给从服务器执行。
那么他是怎么做的呢?怎么才能让主服务器知道哪些是断线期间的数据呢?让我们来一探究竟。
部分重同步由以下3个部分构成:
- 主服务器的复制偏移量和从服务器的复制偏移量。
- 主服务器的复制缓冲区
- 服务器的运行ID
首先,主从服务器分别会维护一个复制偏移量offset,通过对比主从直接的偏移量,很容易得出主从状态是否一致。
其次,当主服务器发送命令传播时,不仅会将写命令发给从服务器,还会往复制缓冲区中塞。其构造为记录偏移量和对应的字节值。
最后,通过从服务器(初次复制时)保存的主服务器运行ID,便可以知道之前是否连接为此主服务器,从而判断是进行部分重同步还是完整重同步。
参考
- 《Redis设计与实现》