Redis的高可靠性?
redis的高可靠性主要是下面两点来保证:
  1. 使用AOF和RDB保证数据的持久性,数据尽量少丢失。
  2. 服务尽量少中断:增加副本冗余量,将一份数据同时保存在多个实例上。
 
多副本之间的数据如何保证一致性?
 
Redis提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。
  • 读操作:主库、从库都可以接收;
  • 写操作:首先到主库执行,然后,主库将写操作同步给从库。
0
为什么设计成读写分离?
如果要保持这个数据在三个实例上一致,就要涉及到加锁、实例间协商是否完成修改等一系列操作,但这会带来巨额的开销,当然是不太能接受的。
而主从库模式一旦采用了读写分离,所有数据的修改只会在主库上进行,不用协调三个实例。主库有了最新的数据后,会同步给从库,这样,主从库的数据就是一致的。
 
????主从库间如何进行同步?
当我们启动多个Redis实例的时候,它们相互之间就可以通过replicaof(Redis 5.0之前使用slaveof)命令形成主库和从库的关系,从库从主库上复制数据。
0
  • FULLRESYNC响应表示第一次复制采用的全量复制,也就是说,主库会把当前所有的数据都复制给从库。具体来说,主库执行bgsave命令,生成RDB文件,接着将文件发给从库。从库接收到RDB文件后,会先清空当前数据库,然后加载RDB文件。这是因为从库在通过replicaof命令开始和主库同步前,可能保存了其他数据。为了避免之前数据的影响,从库需要先把当前数据库清空。
  • 在主库将数据同步给从库的过程中,主库不会被阻塞,仍然可以正常接收请求。为了保证主从库的数据一致性,主库会在内存中用专门的replication buffer,记录RDB文件生成后收到的所有写操作。
????可以采用主从级联分担全量复制的主库压力
目前存在的问题
一次全量复制中,对于主库来说,需要完成两个耗时的操作:生成RDB文件和传输RDB文件。如果从库数量很多,而且都要和主库进行全量复制的话,就会导致主库忙于fork子进程生成RDB文件,进行数据全量同步。fork这个操作会阻塞主线程处理正常请求,从而导致主库响应应用程序的请求速度变慢。此外,传输RDB文件也会占用主库的网络带宽,同样会给主库的资源使用带来压力。
 

 

 

 
 
????主从间网络断了怎么办?
在Redis 2.8之前,如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重新进行一次全量复制,开销非常大。
从Redis 2.8开始,网络断了之后,主从库会采用增量复制的方式继续同步。听名字大概就可以猜到它和全量复制的不同:全量复制是同步所有数据,而增量复制只会把主从库网络断连期间主库收到的命令,同步给从库。
当主从库断连后,主库会把断连期间收到的写操作命令,写入replication buffer,同时也会把这些操作命令也写入repl_backlog_buffer这个缓冲区。
replication buffer和repl_backlog_buffer的区别?
replication buffer:主从同步数据时,存储增量数据用的
repl_backlog_buffer:环形缓存区,记录两个offset(master_repl_offset:主库写的位置,slave_repl_offset从库同步数据的位置),用于同步主从网络中断期间的数据。如果两个位置一致,则不需要同步。
repl_backlog_buffer是一个环形缓冲区,主库会记录自己写到的位置,从库则会记录自己已经读到的位置。

 

 

由于repl_backlog_buffer是环形的,如果写入速度大于读取速度,那么就可能会出现数据覆盖的情况。
为此我们需要设置合理的repl_backlog_size,缓冲空间的计算公式是:缓冲空间大小 = 主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小。在实际应用中,考虑到可能存在一些突发的请求压力,我们通常需要把这个缓冲空间扩大一倍,即repl_backlog_size = 缓冲空间大小 * 2。
 
主库挂了怎么办?