当前位置: 首页 > 科技观察

Redis主从复制如何保证数据不丢失?

时间:2023-03-16 18:44:18 科技观察

简介在生产环境中,为了系统的可靠性,我们会为Redis搭建一个master-slave。这样,当一个实例宕机时,另一个实例中还有数据,可以继续提供服务。主从库之间采用读写分离的模式。读操作:主库和从库都可以执行写操作:只能在主库上执行,主库会同步操作到从库,因为主库和从库都可以接收读请求,提高系统QPS。那么如何在主从数据库之间同步数据呢?全量复制“我们可以使用replicaof命令或者replicaof设置让redis形成主从关系”(redis5.0之前使用slaveof命令)假设现在有两个实例,实例一(172.16.19.1)和实例二(172.16.19.2)当我们在实例2上执行如下命令时,实例2成为实例1的从库,从实例1复制了数据replicaof172.16.19.16379。当然我们也可以在redis中配置如下内容示例2.conf配置文件replicaof172.16.19.16379整个同步过程如下图所示。主从库的全量复制主要分为以下三个阶段。从库发送psync命令,此时主库开始生成rdb文件。主库将生成的rdb文件发送给从库。主库将rdb文件生成后收到的write命令发送给从库。我们仔细分析一下这三个过程。从库发送psync命令,此时主库开始生成rdb文件,从库发送psync命令,表示要复制数据。psync命令包括以下两个参数“runID”:主库的runID。每一个redis实例启动时,都会自动生成一个随机ID来唯一标识该实例。第一次从库拷贝时,因为不知道主库的runID,所以设置runID为?“offset”:拷贝进度,第一个拷贝为-1主库将生成的rdb文件发送到从库的主库执行bgsave命令生成一个rdb文件发送到从库。从库中接收到rdb文件后,会清空当前数据库,然后加载rdb文件。因为从库在通过replicaof命令复制之前可能会保存其他数据,为了避免影响之前的数据,需要先清空从库。主库在rdb文件生成后,会将rdb文件生成后收到的write命令发送给从库,主库仍然可以执行写命令,这些写命令会放在复制缓冲区中。主库发送完rdb文件后,会将replicationbuffer中的命令发送给从库,由从库执行这些操作。主从同步。“后续正常的命令同步也是主库将命令写入复制缓冲区,然后发送给从库。”增量复制,主从命令传播过程中出现网络异常怎么办?在Redis2.8之前,如果出现网络异常,从库和主库会进行增量复制,代价非常大。Redis2.8之后,主从库将采用增量复制的方式进行同步。增量复制只会在主从库断开时将主库接收到的命令同步到从库。复制偏移量主库每次向从库发送n个字节的数据,从库每次从主库接收到n个字节的数据,它都会将自己的复制偏移量加到n,只需将自己的复制偏移量添加到nrepl_backlog_buffer(replicationbacklogbuffer)repl_backlog_buffer是master服务器维护的一个定长的先进先出(FIFO)队列,我们??举个例子,如果hello字符串放入一个定长的3个FIFO队列中,其值为[h,e,l][e,l,l][l,l,o]"每次在队尾添加值,弹出队头"复制积压缓冲区的结构如下Offset...202122232425...字节值...helllo..."服务器在进行命令传播时,不仅会向所有从服务器发送写命令,还会写入命令将排队到复制积压缓冲区。”当从库网络中断重新连接主库时,会向主库发送“psync主库id偏移”,主库根据复制偏移量确定从服务器进行何种复制operationtoperform?如果从库发来的主库id和当前连接的主库id相同,可以继续尝试增量复制,如果从库发来的主库id是与当前连接的主库id不同,表示主服务器断开连接,该行之前复制的主服务器不是当前连接的服务器,只能全量复制。如果offset后的数据offset(即从偏移量offset+1)开始的数据还存在于repl_backlog_buffer中,将命令放入replicationbuffer。然后发送到从库。如果偏移量offse之后的数据repl_backlog_buffer中不存在t,将执行repl的完整副本。icationbuffer和repl_backlog_buffer很多朋友一开始都分不清replicationbuffer和repl_backlog_buffer的作用,包括我其实理解的很好,replicationbuffer其实就是一个client-sidebuffer,redis每次把要发送的命令放在这里buffer发送前。“每个客户端一个复制缓冲区”“repl_backlog_buffer纯粹用于增量复制,redis服务器中只有一个。”转载本文请联系Java石塘公众号。