一: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小时。
  

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

  1. SpringBoot开发二十四-Redis入门以及Spring整合Redis

    需求介绍 安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis ...

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

    一.概述      Redis的强大性能很大程度上都是因为数据时存在内存中的,然而当Redis重启时,所有存储在内存中的数据将会丢失,所以我们要将内存中的数据持久化. Redis支持两种数据持久化的方 ...

  3. Redis教程(十四):内存优化介绍

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/142.html 一.特殊编码: 自从Redis 2.2之后,很多数据类型都 ...

  4. Redis(十四)Redis 在Java Web 中的应用

    在传统的 Java Web 项目中,使用数据库进行存储数据,但是有一些致命的弊端,这些弊端主要来自于性能方面. 由于数据库持久化数据主要是面向磁盘,而磁盘的读/写比较慢,在一般管理系统中,由于不存在高 ...

  5. 二十四 Redis消息订阅&事务&持久化

    Redis数据类型: Redis控制5种数据类型:String,list,hash,set,sorted-set 添加数据,删除数据,获取数据,查看有多少个元素,判断元素是否存在 key通用操作 JR ...

  6. redis(十四):Redis 有序集合(sorted set)

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

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

    一.是什么 官网 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 二.能干嘛 读写分离  容灾恢 ...

  8. Redis(二十):Redis数据过期和淘汰策略详解(转)

    原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...

  9. Redis学习总结(四)--Redis主从配置

    在分布式系统架构设计中高可用是必须考虑的因素之一.高可用通常是指,通过设计减少系统不能提供服务的时间.而单点是系统高可用的最大的败笔,如果单点出现问题的话,那么整个服务就不能使用了,所以应该尽量在系统 ...

  10. Redis 详解 (四) redis的底层数据结构

    目录 1.演示数据类型的实现 2.简单动态字符串 3.链表 4.字典 5.跳跃表 6.整数集合 7.压缩列表 8.总结 上一篇博客我们介绍了 redis的五大数据类型详细用法,但是在 Redis 中, ...

随机推荐

  1. 继续bzoj

    我应该可以打卡下班了,回来继续bzoj

  2. Django ORM 查询

    过滤器 过滤器 作用 all() 查出所有行 filter() 可以添加过滤条件 order_by() 查出所有数据,如果有参数则按参数排序,参数是字符串 ,如:"-username&quo ...

  3. 警惕!Unity3D中UnityEngine.Object的一个小陷阱

    先看看如下C#的脚本代码: 猜猜控制台打出来的是什么? In the bool parameter function, value info is:  True 肯定出乎很多人的意料吧? transf ...

  4. memchr函数

    函数原型:extern void *memchr(void *str, char ch, unsigned count) 参数说明:从str所指内存区域的前count个字节查找字符ch.        ...

  5. AppWidget学习总结

    AppWidget学习总结 一.创建AppWidget.    1.在res/xml下创建一个xml文件,以设置widget占用的空间等信息.如widget_provider.xml        & ...

  6. squid总结

    squid可以完成的工作: 代理服务器 反向代理服务器 防火墙 缓存功能 透明代理 squid和varnish的对比,以及squid的优缺点说明: 缓存到硬盘,容易遇到I/O瓶颈 V3.2以下不支持多 ...

  7. Leetcode 380. 常数时间插入、删除和获取随机元素

    1.题目描述 设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构. insert(val):当元素 val 不存在时,向集合中插入该项. remove(val):元素 val 存在时 ...

  8. HDU 1074状压DP

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  9. MongoDB入门(5)- 我们自己封装的MongoDB-Java版本

    用法 实体定义 package com.wisdombud.mongotool; import java.io.Serializable; import java.util.Date; import ...

  10. Cppcheck代码分析下

    1.流解析 解析函数中的可能的代码执行流, 函数实际执行中只会执行代码流中的一条流 分析: 分支语句 if-else ,switch-case         循环语句 while, do-while ...