redis主从同步

273 阅读4分钟

主从库之间为什么采用读写分离?

如果所有库都可以写入,会造成数据不一致。为了防止数据不一致,需要引入加锁等机制,带来额外的开销。

数据只能在主库上写入,不会有写入瓶颈?

Redis单线程顺序写入内存,性能是很好的。如果应用程序的写入的确非常频繁,可以考虑使用切片集群(cluster)来分担单个主库的压力。

主从同步命令

客户端连接从库,执行以下命令(请自行替换自己的主库ip和端口):

replicaof master_ip master_port

redis5.0以前,命令是slaveof

执行以下命令,会关闭当前从服务器的复制并转变为主服务器

replicaof no one

执行replicaof后,执行info replication能看到主库信息,其中有个字段是master_link_status,表示与主库连接的状态。如果master_link_status是up,表示连接成功;如果是down,表示连接失败,这种情况很有可能是防火墙导致的。

主从库如何进行第一次同步?

  1. 建立连接,从库发送psync命令。
  2. 主库执行bgsave命令,生成RDB文件,发送给从库。从库收到文件后,清空当前数据库(因为可能有以前的数据),加载RDB文件。主库同步数据的过程中,不会被阻塞,可以继续执行客户端命令。这期间如果有写入命令,主库在内存中用专门的replication buffer记录这些写操作,以此保证主从数据一致性。
  3. 主库发送完RDB文件后,发送replication buffer中的写操作给从库,从库执行一遍。
  4. 主从间会一直维护一个长连接(避免频繁建立连接的开销),主库会把后续的写命令同步给从库。

从库太多,全量复制主库压力太大怎么办?

采用“主-从-从”模式,单个redis的实例不宜过大(考虑到数据备份和数据同步)

主从间网络断连了怎么办?

在Redis2.8之前,如果主从间网络断了,后续恢复连接后,需要重新进行全量复制,开销很大。

从Redis2.8开始,网络断了恢复后,主从间会采用增量复制的方式。网络断连后,主库为从库维护一个repl_backlog_buffer环形缓冲区。主库会记录自己的写到的位置,而从库会记录自己读到的位置。网络恢复后,通过这个偏移量,从库就可以进行增量数据恢复。但是如果断连时间太长,主库执行了大量写入命令,主从偏移量已经超出了repl_backlog_buffer的大小,那就只能执行全量同步了。

全量复制,为什么传输RDB文件而不是AOF文件?

  1. RDB文件内容是经过压缩的二进制数据(不同数据类型数据做了针对性优化),文件很小。而AOF文件记录的是每一次写操作的命令,写操作越多文件会变得很大,其中还包括很多对同一个key的多次冗余操作。在主从全量数据同步时,传输RDB文件可以尽量降低对主库机器网络带宽的消耗,从库在加载RDB文件时,一是文件小,读取整个文件的速度会很快,二是因为RDB文件存储的都是二进制数据,从库直接按照RDB协议解析还原数据即可,速度会非常快,而AOF需要依次重放每个写命令,这个过程会经历冗长的处理逻辑,恢复速度相比RDB会慢得多,所以使用RDB进行主从全量同步的成本最低。

  2. 假设要使用AOF做全量同步,意味着必须打开AOF功能,打开AOF就要选择文件刷盘的策略,选择不当会严重影响Redis性能。而RDB只有在需要定时备份和主从全量同步数据时才会触发生成一次快照。而在很多丢失数据不敏感的业务场景,其实是不需要开启AOF的。

主从采用读写分离,客户端怎麽知道往哪里写往哪里读?

客户端不知道往哪里写哪里读,需要客户端自己实现(例如Redisson客户端)。也可以在客户端和Redis集群之间增加一个代理。

从库是默认只读的吗?

从Redis 2.6开始,从库默认是被设置为只读的,配置项slave-read-only默认为yes