1、什么是高可用?
单机redis支撑的并发量有限(一般QPS在1W-几W不等),如果并发量大可能导致redis挂掉;redis配置不合理,fork子进程同步也可能导致redis挂掉(伪挂);操作系统异常(JVM挂掉、OOM、CPU过载、磁盘满了IOYICHANG)或者网络变更、迁移等也可能导致redis挂掉(暂停对外服务)。等等这些,可能引起业务系统正常运转的,都是非高可用的表现。理想状态,后台redis挂掉不影响(或者较小范围影响)业务系统对缓存系统的访问,即高可用。高可用从体现上就是:故障转移(failover),也叫主备切换。
2、伪高可用
使用redis持久化方案(RDB、AOF)在进程挂掉后,重新启动加载缓存数据。
3、数据同步机制
一般redis读的压力大,为了更好的提供服务,支持主从(一主多从)复制(同步)。根据是否全量复制,分为:全量同步和增量同步。
全量同步
a、Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。
b、配置好主从后,无论slave是初次还是重新连接到master, slave都会发送PSYNC命令到master。
如果是重新连接,且满足增量同步的条件,那么redis会将内存缓存队列中的命令发给slave, 完成增量同步。否则进行全量同步。
具体步骤如下:
1)从服务器连接主服务器,发送SYNC命令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照(快照文件先接收保存到磁盘,最后加载到内存中);
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
增量同步
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
增量同步的条件:
几个重要概念:
- 内存缓存队列(in-memory backlog):用于记录连接断开时master收到的写操作
- 复制偏移量(replication offset):master, slave都有一个偏移,记录当前同步记录的位置
- master服务器id(master run ID):master唯一标识
现网络连接断开后,slave将尝试重连master。当满足下列条件时,重连后会进行增量同步(断点续传):
1. slave记录的master服务器id和当前要连接的master服务器id相同
2. slave的复制偏移量比master的偏移量靠前。比如slave是1000, master是1100
3. slave的复制偏移量所指定的数据仍然保存在主服务器的内存缓存队列中
Redis主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
redis replication的核心机制
(1)redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量
(2)一个master node是可以配置多个slave node的
(3)slave node也可以连接其他的slave node
(4)slave node做复制的时候,是不会block master node的正常工作的
(5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
(6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量,与高可用有关
(1)master和slave都会维护一个offset
master会在自身不断累加offset,slave也会在自身不断累加offset
slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset
这个倒不是说特定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况
(2)backlog
master node有一个backlog,默认是1MB大小
master node给slave node复制数据时,也会将数据在backlog中同步写一份
backlog主要是用来做全量复制中断候的增量复制的
(3)master run id
info server,可以看到master run id
如果根据host+ip定位master node,是不靠谱的,如果master node重启或者数据出现了变化,那么slave node应该根据不同的run id区分,run id不同就做全量复制
如果需要不更改run id重启redis,可以使用redis-cli debug reload命令