主从模式
解决的问题:
- 读写分离,能一定程度的提高效率
- 在主库宕机后,能很快用从库备用(但是这时候需要手动修改配置来切换主库)
主从间的数据同步是如何进行的
第一次主从同步机制
- psync ? -1
? 处传的是主库的runId(每一个redis实例启动时随机生成的ID)由于这里不知道所以传的?
-1 这里传的时候复制进度,-1表示第一次复制 - repl buffer
由于第二部数据同步是不会阻塞主库主线程的,所以在数据同步时还会有新的命令写入,这时候写入的数据都会放到repl buffer中
Redis和客户端通信也好,和从库通信也好,Redis都需要给分配一个 内存buffer进行数据交互
从库宕机后重连的数据同步机制
在redis2.8之前,宕机后从库重连都是全量数据重新同步,这样的话如果数据量很大的话,同步的消耗会很大;在redis2.8之后,就出现了增量复制;
听到增量复制就能想到:1、主库要记录写入操作;2、从库要记录下断开连接时的同步点;
那么redis2.8之后是怎么做增量复制的呢?
他使用到了一个环形缓冲区repl_backlog_buffer,如下图
主库会把所有的写操作命令写入到repl_backlog_buffer中,并且记录下主库写入的位置( master_repl_offset);从库来读的时候也会记录下读取的位置(slave_repl_offset);那么两个位置中间的操作就是需要进行增量同步的数据;
如果从库的读取速度比较慢,就有可能导致从库还未读取的操作被主库新写的操作覆盖了,这会导致主从库间的数据不一致。这时候需要增加缓冲区大小, repl_backlog_buffer缓冲区的大小是通过repl_backlog_size 这个参数控制的;
还记得第一次主从同步时传的< psync ? -1 >吗?那么在恢复连接的时候,这里psync 的?就能带上主库的runId(已经保存下来了),-1也会变成从库记录下的最后读取到的位置;
repl_backlog_buffer和replication buffer
- replication buffer
Redis和客户端通信也好,和从库通信也好,Redis都需要给分配一个 内存buffer进行数据交互; - repl_backlog_buffer
一个实例就一块区域共用,用于增量同步;
哨兵模式
主从模式虽然他能解决主从分离,也能在主库宕机后将从库切换为主库,但是这个切换的操作需要人工手动完成!这时候出现了哨兵模式很好的解决了这个问题;
哨兵顾名思义就是起到一个监控观察的作用;其大体的结构如下图
sentinel其实是一个特殊的redis进程,他会去监控着redis的运行状态,通过状态信息完成redis库的上下线及主从的切换;因此一旦redis莫个实例发生异常后,不需要手动的去完成主从的切换;
集群模式
主从模式和哨兵模式还存在一个问题,就是所有实例都存储着全量数据,如果数据量很大的话,并发量很高的情况下会有一定的瓶颈;
集群模式就解决了这个问题,一个切片集群被分为16384个slot(槽),每个key通过hash算法,均匀的分配到这16384个槽中去,然后不同的master实例存储不同的槽(有三个master节点,意味着redis的槽被分为三个段,假设三段分别是0-6000, 6000-12000、12001~16383);然后这些master节点又是有哨兵定义的,依然高可用;