首页 > 编程知识 正文

redis主从延迟怎么解决,redis主从如何保持数据一致

时间:2023-05-06 13:56:28 阅读:24360 作者:1117

Redis主从复制及其实现原理首先简要介绍什么是Redis主从复制。 假设我们的服务使用Redis,并且只有一台Redis服务。 如果Redis服务在某个时间点挂起,则整个服务的Redis将不可用。 在此期间,大量请求直接命中数据库(mysql ),数据库压力剧增,严重时数据库可能直接挂起。 这种情况称为单点故障。 为了解决Redis的单点故障问题,有Redis的主从复制。 这意味着服务中存在多个Redis服务,或称为Redis节点。所有Redis节点的数据都是一样的,其中一个Redis节点作为主节点(主库),其余的Redis节点作为该节点的从节点(从库)这就是Redis提供的主从机型。 并在主从模式下采用读写分离: 读取操作:主库可以从库中执行读取操作,主要从库中读取。 写入:只有主库执行写入,并将数据同步到每个从库,从而确保主和从库的数据一致性。 通过以上介绍,我想你应该知道了什么是Redis的主从复制。 那么,如何实现Redis的主从复制功能呢? 由于Redis提供主从模式功能,因此可以在Redis节点的配置文件(redis.conf )中配置相关项。 主节点不需要修改redis.conf配置文件中的相关配置。 #配置主节点ip和端口注意事项:从Redis5.0开始,slaveofof已更改为replicaofslaveof 127.0.0.1 6379#。 以后,在redis2.6以后,默认情况下是否从节点只读取slavexxxxx

x从节点配置上述信息后,启动主节点,然后启动从节点,主节点和从节点就会连接起来,主节点和从节点开始同步操作。

现在,让我们看看这个主从同步流程具体是如何执行的呢以及下面。

首先,让我们来看看整个流程图。 接下来,我将逐步介绍我做了什么。

步骤1 )当主从节点建立连接、协商数据同步和主从节点首次建立连接以进行完全复制时,连接全量复制,即主节点的所有数据在上图的第一步中,是否要从节点发送psync? -1指示并复制主节点。 3358 www.Sina.com/http://www.Sina.com/:每个Redis节点在启动时生成唯一的随机id来标识此Redis节点。 第一次从库中向主库发出复制请求时,不知道主库的runId,是否要将runId设置为问号?其中?代表主节点的 runId;-1 代表复制进度 offset。:如果复制进度为-1,则表示这是第一次复制。 主节点接收到从节点的psync命令时,用FULLRESYNC命令进行响应,并将自身的runId和当前复制进度offset发送到从节点。 步骤2 :在主节点通过RDB文件将所有数据发送到从节点的步骤2中,主节点运行bgsave命令生成RDB文件并将RDB文件发送到从节点。 从节点收到RDB文件后,首先清空自己的数据(防止主从数据不匹配),完成RDB文件的数据加载。 当主节点将数据同步到从节点时,RDB文件由子进程生成,而主节点不被阻止(fork子进程被阻止)。 在此期间,主节点仍会成功接收请求,但这些请求的写入操作未记录在刚生成的RDB文件runId或3358www.Sina.com/中。 步骤3 :主节点向从节点发送在执行步骤2时接收的写入请求,从节点然后重新执行这些操作以实现主从同步。 至此,Redis主从同步的具体执行过程,我们已经很清楚了。offset:在主从复制过程中,Redis在fork子进程中生成RDB文件,该fork子进程的操作阻止了Redis的主线程。 如果从节点非常多,则主节点会被fork子进程追赶,主节点会被阻止,该怎么办? 然后往下看:

此时,可以使用“主-从”模式将主节点生成和发送RDB文件的压力级联到从节点。

简而言之,可以选择配置相对较高的从节点作为其他从节点的主节点,如下图所示。

可以看到,从节点2和从节点3的主节点设置为从节点1,而不是主节点。 这样,可以有效地缓解主节点很多从复制的压力。

那么,除了上述问题以外还有其他问题吗? 答案是肯定的。为了保证主从数据一致性,主节点会把 RDB 文件生成后的写操作记录到内存中的一块缓冲区但是,如果这个连接中断了会怎么样呢?

在Redis2.8之前,replication buffer,这是因为在主从节点断开重新连接后执行总量复制,显然总量复制开销太大

is2.8之后就被淘汰了,升级成了增量复制。那么,什么是增量复制呢?

增量复制

断连重连之后,从节点不会复制所有的主节点数据,只会复制断连之后这段时间的写操作数据,这就是增量复制,顾名思义,就是只复制断连后增加的那部分数据量。

增量复制的实现依赖于一个环形缓冲区 repl_backlog_buffer只要有从节点在,这个环形缓冲区就会存在。主节点会在这个环形缓冲区记录自己写到的位置,从节点会在这个环形缓冲区记录自己已经读到的位置。如下图所示:


主节点的所有写操作除了复制给从节点之外,也会在这个环形缓冲区记录一份,也就是上面说到的主节点会在这个环形缓冲区记录自己写到的位置,只有预先缓存了这些写操作,当从节点断连之后,又恢复连接然后发送 psync {runId} {offset} 命令执行主从同步。主节点才能通过 {offset} 参数在环形缓存区 repl_backlog_buffer 中找到从节点断连的位置,然后发送增量数据(offset位置到主节点写到的位置之间的数据)给从节点。

注意:假如从节点断连时的读位置 offset 已经被主节点的写位置覆盖了,那么此时便无法执行增量复制操作了,只能再执行一次全量复制了。所以,为了尽量避免断连之后的全量复制,可通过 repl_backlog_size 这个参数合理设置 repl_backlog_buffer 的大小,减少发生全量复制的概率。

计算公式:缓冲空间大小 = 主节点写入命令速度 * 操作大小 - 主从节点间网络传输命令速度 * 操作大小
为应对突发情况,可将 repl_backlog_size 设置为缓冲空间大小的2倍。
即:repl_backlog_size = 缓冲空间大小 * 2

接着上面的说,增量数据是如何发送给从节点的呢,这就用到了 replication buffer

关于 replication buffer 的介绍

Redis和客户端或者从节点通信,都会分配一个对应的内存缓冲,通过这个内存缓冲完成数据交互,如果连接断开,这个内存缓冲也会不复存在。当和从节点进行交互的时候,这个内存缓冲专门用于复制主节点的写操作到从节点,所以叫 replication buffer。如果从节点处理数据特别慢,那么这个replication buffer 会持续增长,可能导致OOM。这个内存缓冲的大小可通过 client-output-buffer-limit 参数限制,如果超过这个限制,主节点会强行断开这个从节点(客户端)的连接。此时复制中断,如果之后再继续发起复制请求,可能会导致恶性循环,引发复制风暴,需格外注意。

以上内容参考了极客时间Redis专栏介绍以及yydlz大神的相关说明。

到此,Redis主从复制相关介绍就结束了。
这种模式可以解决Redis的单点故障问题,提高Redis的可用性。但是缺点也是很明显的,假如主节点挂了,从节点是无法自动升级成主节点的,这个过程需要人工处理,在此期间,Redis无法对外提供写操作。此时,Redis哨兵模式就该登场了,待更新…
此外,整个Redis的主从节点数据都是一样的,也就是冗余的,会造成一定的资源浪费。此时,Redis集群模式就该登场了,详见Redis集群搭建

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。