redis之(十四)redis的主从复制的原理

一:redis主从复制的原理,步骤。

第一步:复制初始化

--->从redis启动后,会根据配置,向主redis发送SYNC命令。2.8版本以后,发送PSYNC命令。

--->主redis收到SYNC命令后,开始在后台保存快照文件(即RDB持久化的过程),并将保存快照期间接收到的命令缓存起来。

--->当主redis完成快照后,主redis会将快照文件和缓存命令发送给从redis。复制初始化结束。

--->当主redis的复制初始化结束后,主redis每当收到写命令就会异步将写命令,发送给从redis

第二步:同步过程

--->当从redis发送SYNC后,接受到快照文件(RDB)和缓存命令后,将内容写到硬盘上的临时文件

--->当从redis把快照文件和缓存命令写完后,会根据从的配置文件(dir和dbfilename两个参数确定),将临时文件替代RDB文件。并把命令执行。从而达到主从redis内容一致。

--->复制同步阶段会贯穿整个主从同步过程的始终,直到主从关系终止为止。

下图为模拟主从复制过程。

二:redis主从复制原理中的重要问题。

第一个:主redis和从redis的数据同步是异步还是同步?

--->redis的主从复制,叫乐观复制。是异步的。容忍在一定时间内主从数据库的内容是不同的。但是两者的数据最终会同步。

--->既然是异步,就会存在一个主从redis数据不一致的时间窗口。

第二个:当主redis收到写命令,在向从redis发送同步的命令前,主从redis网络断连,如何解决。

--->redis提供一种限制策略。来防止主从断连后,主redis无法得知自己的写命令,是否都完整发送给从redis

--->两个配置参数:min-slaves-to-write 和min-slaves-max-lag

--->min-slaves-to-write 参数后边的数字n,是保证当至少有n台及n台以上的从redis和主redis正常连接,主redis才会对外提供写服务。

--->min-slaves-max-lag 参数后边的数字m(单位:秒),主redis和从redis最长的失联时间。当从redis最后与主redis联系(即发送REPLCONF ACK命令)的时间到当前时间的差值,小于这个m。则主redis认为主从连接正常,对外提供写服务。一旦大于这个值,则表示有从redis断连,而不与外界提供写操作。

--->这一特性,保证了网络分区下主从数据不一致。默认该特性是关闭的。

第三个:主从断连,重新连接上后,主从是怎么实现数据的同步。

--->redis2.6版本以前,每次重练,就需要快照文件和缓存命令进行一次完整同步,从头再来一遍,当数据量大的时候,同步效率会很低下。

--->redis2.8版本以后,新策略。能够支持[有条件的]增量数据传输,只需要将失联期间的没有同步的命令进行传输就ok了。

第四个:主从数据库可以实现读写分离的业务场景吗?

--->可以实现

第五个:从redis挂掉,重启,主redis会将数据同步给从redis。那么主redis挂掉,怎么实现数据的恢复以及集群继续对外提供写服务?

--->两种方案:(1)手动恢复(2)哨兵策略

--->手动恢复

1.在从数据中使用SLAVEOF NO ONE命令将从redis数据库升级成主数据库继续对外提供服务。

2.启动之前崩溃的主redis,然后使用SLAVEOF命令将其设置为新主redis的从数据库,从而可将数据同步回来。

3.注意点:当开启复制且主redis数据库关闭持久化功能时,一定不要使用Supervisor以及类似的进程管理工具令主数据库崩溃后自动重启,也避免在未将某一台从redis升级为主redis前手动重启旧的主redis,因为旧的redis启动后,因为没有持久化,数据库中的数据是空的,就会将所有的从redis节点也同步成空的。

三:redis的分布式特性

--->读写分离实现读多写少的场景

--->主数据库不持久化,从数据库持久化。

(1)但是会存在,主宕机重启后,由于不持久化,无数据记录,同时把从的数据也清空了的隐患。这种主从结构,需要先将一个从升级为主,再启动旧的主数据库.

--->无硬盘复制。

(1)目的是:减少硬盘读写,提升性能。

(2)主redis在复制过程(生成快照RDB)的快照文件时,不是往硬盘上写,而是直接通过内存传输给从redis数据库。目前2.8版本以后可以通过配置文件开启这个模式,属于测试实验阶段。repl-diskless-sync yes选项启动。

--->增量复制。

(1)目标:主从redis断连后,主redis不需要每次都实现全部数据的快照和命令缓存,去与失联的重新联系上的从redis进行同步。而是只同步失联期间的数据变化,从而提升性能。

(2)实现增量复制的基础

  ==>从redis会存储主redis的运行ID(run id)。每个redis实例均会拥有一个唯一的运行ID .每当实例重启后,就会自动生成一个新的运行ID

  ==>在复制同步阶段,主redis每将一个命令传送给从redis时,都会同时把该命令存放在一个积压队列(backlog)中,并记录下当前积压队列存放命令的偏移量范围。

  ==>从redis接收到主redis传来的命令时,也会记录下该命令的偏移量。

(3)实现增量复制的过程

  ==>从数据库需要主数据库进行复制的时候,2.8版本后,从redis会发送[PSYNC+主redis运行id+断开前最新的命令偏移量]给主redis

  ==>主redis接收到命令后,判断传送过来的主redis运行id和自己的运行id是否相同。同时判断传来的断开前最新的命令偏移量,是否在自身的积压队列里面。如果存在,则从自身的积压队列里决定复制多少命令给从redis,进而实现增量复制。

  ==>如果从redis传来的主redis的运行id和自己的运行id不相同,或者,运行id相同,但是偏移量不在主redis的积压队列里。则进行全量复制。(生成快照文件+缓存命令)

  ==>积压队列的大小配置:repl-backlog-size指定(默认1mb),

  ==>积压队列的释放时间:repl-backlog-ttl指定。即当有从redis和主redis断连开始,经过多长时间释放积压队列的内存空间。默认1小时。

  

时间: 2024-10-09 15:39:02

redis之(十四)redis的主从复制的原理的相关文章

二十四 Redis

Redis数据类型: Redis控制5种数据类型:String,list,hash,set,sorted-set 添加数据,删除数据,获取数据,查看有多少个元素,判断元素是否存在 key通用操作 JRedis:java操作redis 多数据库: 一个Redis实例可以包括多个数据库,客户端可以指定连接某个Redis数据库就好 一个Redis实例最多提供16个数据库,0~15 选中仓库: select 0 将当前仓库下的某个键值对的数据移动到其他仓库 move name 1 测试连接是否存活: p

Redis学习十:Redis的复制(Master/Slave)【重要】

一.是什么 官网 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 二.能干嘛 读写分离  容灾恢复 三.怎么玩 1.配从(库)不配主(库) 2.从库配置:slaveof 主库IP 主库端口 说明: 每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件 Info replication 3.修改配置文件细节操作 [1]拷贝多个redis.conf文件 [2]开启dae

Redis基础学习(四)—Redis的持久化

一.概述      Redis的强大性能很大程度上都是因为数据时存在内存中的,然而当Redis重启时,所有存储在内存中的数据将会丢失,所以我们要将内存中的数据持久化. Redis支持两种数据持久化的方式: RDB方式和AOF方式. (1)RDB方式会根据配置的规则定时的将内存中的数据持久化到硬盘上. (2)AOF则是在每次执行写命令之后将命令记录下来.   1.RDB方式      RDB方式的持久化是通过快照的方式完成的.当符合某种规则时,会将内存中的数据全部生成一个副本存储在硬盘上,Redi

企业级 SpringBoot 教程 (十四)在springboot中用redis实现消息队列

准备阶段 java 1.8 maven 3.0 idea 环境依赖 创建一个新的springboot工程,在其pom文件,加入spring-boot-starter-data-redis依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency

性能测试二十四:环境部署之Redis多实例部署

由于redis服务端是单线程实现的,因此只能占用CPU的单核,为了充分利用CPU资源,可以在一台服务器上同时启动多个redis-server实例 首先删除之前的rdb.aof文件 注释掉3个save appendonly改为no 配置方法: 每个实例创建一个conf文件 修改每个conf文件中的端口号 启动不同实例时指定不同的配置文件 复制一份conf,命名为6380.conf 该端口号.保存的文件名为6380 重启 关闭已启动的Redis进程 启动Redis,加载两个配置文件 使用查看进程和r

SpringBoot(二十四)整合Redis

缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多. 之前有两篇博文(centos安装Redis 和 Redis五大数据类型的常用操作),分别介绍了Redis的安装和Redis的常用操作.今天主要介绍介绍springboot整合Redis. v应用场景 现在公司做的项目都偏重论坛/社区/社交类产品,所以对Redis的实用场景主要集中在排行榜,最

redis内存优化、持久化以及主从复制

Redis 数据库内存优化参数的配置,每种持久化方式的利与弊以及主从复制的原理以及配置 一.常用内存优化手段与参数 redis的性能如何是完全依赖于内存的,所以我们需要知道如何来控制和节省内存. 首先最重要的一点是不要开启Redis的VM选项,即虚拟内存功能,这个本来是作为Redis存储超出物理内存数据的一种数据在内存与磁盘换入换出的一个持久化策略,但是其内存管理成本非常的高,所以要关闭VM功能,请检查你的redis.conf文件中 vm-enabled 为 no. 其次最好设置下redis.c

StackExchange.Redis学习笔记(四) 事务控制和Batch批量操作

Redis事物 Redis命令实现事务 Redis的事物包含在multi和exec(执行)或者discard(回滚)命令中 和sql事务不同的是,Redis调用Exec只是将所有的命令变成一个单元一起执行,期间不会插入其他的命令. 这种方式不保证事务的一致性,即使中间有一条命令出错了,其他命令仍然可以正常执行,并且无法回滚 下面的例子演示了一个基本的事务操作 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name mike QUEUED 127.0.

redis使用基础(十) ——Redis存储Session

redis使用基础(十) --Redis存储Session (转载请附上本文链接--linhxx) 一.概述 PHP默认是将session存于服务器的文件中.当并发量大,此方式效率低,因此可以采用redis存储session. 要改变session的存储位置,首先要改变php.ini中的配置项session.save_handler,将其值设置为user. 二.改变存储位置函数 php内置的函数session_set_save_handler可以重新设定session的保存方式,包括sessio