什么是主从同步(复制)

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制的作用

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  2. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
  3. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  4. 读写分离:可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量;
  5. 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

Redis之主从同步的实现原理

1.当从库和主库建立ms(master和slave)关系后,会向主库发送sync命令。

2.收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。

3.当主服务器的BGSAVE命令执行完毕,主服务器将生成的RDB文件发送给从服务器,从服务器接收并加载这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。

4.主服务器将记录在缓冲区里面的所有命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器当前所处的状态。

命令传播

在同步操作完毕后,主从服务器两者的数据库状态达到一致,但是如果客户端发送写命令给主服务器时,将导致主从服务器状态不一致。

为了让主从服务器数据一致,主服务器需要对从服务器执行命令传播操作:主服务器会将自己执行的那条写命令,发送给从服务器执行,当从服务器执行了该写命令后,主从服务器将再次回到一致状态。

主从同步配置

1.环境准备,运行3个redis数据库,达到 1主 2从的配置

  1. 主库 6379.conf
  2. port 6379
  3. daemonize yes
  4. pidfile /data/6379/redis.pid
  5. loglevel notice
  6. logfile "/data/6379/redis.log"
  7. dbfilename dump.rdb
  8. dir /data/6379
  9. 从库 6380
  10. port 6380
  11. daemonize yes
  12. pidfile /data/6380/redis.pid
  13. loglevel notice
  14. logfile "/data/6380/redis.log"
  15. dbfilename dump.rdb
  16. dir /data/6380
  17. slaveof 127.0.0.1 6379 # 表示从库,主库为6379
  18. 从库 6381
  19. port 6381
  20. daemonize yes
  21. pidfile /data/6381/redis.pid
  22. loglevel notice
  23. logfile "/data/6381/redis.log"
  24. dbfilename dump.rdb
  25. dir /data/6381
  26. slaveof 127.0.0.1 6379 # 将这个写入才行

2.开启主从复制功能

  1. redis-cli info #查看数据库信息
  2. redis-cli info replication # 查看redis的复制授权信息
  3. 6380 6381数据库上 ,配置主从信息,通过参数形式修改配置,临时生效,注意要写入配置文件
  4. redis-cli -p 6380 slaveof 127.0.0.1 6379
  5. redis-cli -p 6381 slaveof 127.0.0.1 6379
  6. 此时检查6379的复制信息,以及6380 6381的复制信息
  7. redis-cli -p 6380 info replication # 查看redis的复制授权信息
  8. redis-cli -p 6381 info replication
  9. 主从复制是 读写分离的,master可写, slave只读

3.模拟主从复制故障,手动切换master-slave身份,low

  1. 1.杀死6379进程 ,干掉主库
  2. 2.手动切换 6381为新的主库,需要先关闭它的从库身份
  3. redis-cli -p 6381 slaveof no one
  4. 3.修改6380的新主库是 6381
  5. redis-cli -p 6380 slaveof 127.0.0.1 6381

2.8版本后的复制功能

为了解决旧版的问题,Redis2.8以后引入了PSYNC代替SYNC命令执行复制时的同步操作。

PSYNC命令具有完全同步和部分重同步功能。

完全同步和旧版的同步是一样的。

部分重同步主要是用于断线后的重复制情况:当从服务器断开重新连接后,如果条件允许,主服务器将断开期间的写命令发给从服务器,从服务器执行断开期间的写命令完成同步,将数据库更新到和主服务器一致。

部分重同步的实现

部分重同步的必备条件

  • 主服务器的复制偏移量和从服务器的复制偏移量。
  • 主服务器的复制积压缓冲区(队列,默认1MB)。
  • 服务器的允许ID。

主服务器和从服务器都会维护一个复制偏移量,主要是用户对比复制的执行结果。例如主从服务器的复制偏移量均为1000,当主服务器完成了3个写命令后,主服务器偏移量为1003,这时候将3个命令给从服务器执行,从服务器执行完毕,复制偏移量也为1003。

如果主从服务器的数据是一致的,那么他们的偏移量也是一致的。

复制积压缓冲区,在主服务器将写命令给从服务器后,还会写入到复制积压缓冲区,如果执行到了偏移量为1003的时候,从服务器A断开,主服务器继续执行了7个写入命令,这时候主服务器的偏移量为1010,A服务器连接上,请求复制主服务器,这时候主服务器会分情况处理。

1)主服务器不是A从服务器之前复制的主服务器(根据服务器ID判断),执行完全同步。

2)发现A从服务器之前复制的是自己。根据A从服务器的偏移量去复制积压缓冲区中看1004-1010命令是否依然存在,如果存在将1004-1010偏移量的命令返回给A从服务器执行。如果不存在,只能执行完全同步恢复数据一致了。

Redis哨兵

哨兵的原理

哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master.

每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown)。

若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置.

虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel).

redis-sentinel主从复制高可用

环境准备

  1. 三个redis数据库实例 ,配置好 1 2从的配置
  2. 6379.conf
  3. port 6379
  4. daemonize yes
  5. logfile "6379.log"
  6. dbfilename "dump-6379.rdb"
  7. dir "/var/redis/data/"
  8. 6380.conf
  9. port 6380
  10. daemonize yes
  11. logfile "6380.log"
  12. dbfilename "dump-6380.rdb"
  13. dir "/var/redis/data/"
  14. slaveof 127.0.0.1 6379
  15. 6381.conf
  16. port 6381
  17. daemonize yes
  18. logfile "6381.log"
  19. dbfilename "dump-6381.rdb"
  20. dir "/var/redis/data/"
  21. slaveof 127.0.0.1 6379

三个redis哨兵进程,指定好检测着谁,这里只列出一个

  1. # 对哨兵进行配置,每个哨兵都要有一个配置
  2. port 26379 # 端口
  3. dir /var/redis/data/ # 日志存储位置
  4. logfile "26379.log" # 日志文件
  5. # 当前Sentinel节点监控 192.168.182.130:6379 这个主节点
  6. # 2代表判断主节点失败至少需要2个Sentinel节点同意
  7. # mymaster是主节点的别名
  8. sentinel monitor mymaster 0.0.0.0 6379 2
  9. # 每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
  10. sentinel down-after-milliseconds mymaster 20000
  11. # 当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
  12. sentinel parallel-syncs mymaster 1
  13. # 故障转移超时时间为180000毫秒
  14. sentinel failover-timeout mymaster 180000

分别启动 三个redis数据库, 以及三个 哨兵进程 ,注意 :哨兵第一次启动后,会修改配置文件,如果错了,得删除配置文件,重新写。

  1. redis-server xxx.conf # 启动数据库
  2. redis-sentinel sentinel-26379.conf # 启动哨兵

验证哨兵是否正常

  1. redis-cli -p 26379 info sentinel # 验证哨兵是否正常
  2. master0:name=s21ms,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3 # 正常

现在如果主库挂掉,会自动切换设置其他的从库为主库。

redis-cluster集群搭建

并发问题,数据量太大,单个redis内存不足,使用cluster进行分片存储。

redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;

redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;

为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;

那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;

那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。

因为集群至少有一半以上判定某个节点挂掉,所以节点数至少有三个。

1.通过配置,开启redis-cluster

  1. # redis-7000.conf
  2. port 7000
  3. daemonize yes
  4. dir "/opt/redis/data"
  5. logfile "7000.log"
  6. dbfilename "dump-7000.rdb
  7. cluster-enabled yes # 开启集群模式
  8. cluster-config-file nodes-7000.conf # 集群内部的配置文件
  9. cluster-require-full-coverage no  
  10. #redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no
  11. # 6个实例,三个是主节点,三个是从节点,数量为6个节点才能保证高可用的集群。

2.创建6个配置文件,即6各节点,仅仅是端口的区别,内容均如上

  1. [root@yugo /opt/redis/config 17:12:30]#ls
  2. redis-7000.conf redis-7002.conf redis-7004.conf
  3. redis-7001.conf redis-7003.conf redis-7005.conf

3.启动6个节点,ps查看进程ps -ef|grep redis

  1. 1855 2018-10-24 15:46:01 redis-server redis-7000.conf
  2. 1856 2018-10-24 15:46:13 redis-server redis-7001.conf
  3. 1857 2018-10-24 15:46:16 redis-server redis-7002.conf
  4. 1858 2018-10-24 15:46:18 redis-server redis-7003.conf
  5. 1859 2018-10-24 15:46:20 redis-server redis-7004.conf
  6. 1860 2018-10-24 15:46:23 redis-server redis-7005.conf

4.分配redis slot 槽位

  • 手动写c语言 分配
  • 使用ruby大神 写的一个redis模块,自动分配

5.配置ruby脚本环境

  1. 1.yum安装最简单
  2. yum install ruby
  3. 2.自动配置好 PATH环境变量
  4. rubygem的环境变量
  5. 3.下载ruby操作redis的模块
  6. wget http://rubygems.org/downloads/redis-3.3.0.gem
  7. 4.ruby的包管理工具 gem 安装这个模块
  8. gem install -l redis-3.3.0.gem
  1. 5.通过ruby一键分配redis-cluster集群的槽位
  2. 找到机器上的redis-trib.rb命令,用绝对命令创建,如下所示:

6.开启集群,分配槽位

  1. /opt/redis-4.0.10/src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
  2. # 1表示1个主库带1个从库

7.启动集群,连接集群节点,连接任意一个即可

  1. redis-cli -p 7001 -c

注意:一定要加上-c,不然节点之间是无法自动跳转的!

8.登录redis并写入数据,发现槽位分配,且重定向之后,集群搭建成功

查看集群信息简单命令

1.查看当前集群信息

  1. cluster info
  2. # 集群主节点状态
  3. redis-cli -p 7000 cluster nodes | grep master
  4. # 集群从节点状态
  5. redis-cli -p 7000 cluster nodes | grep slave

2.查看集群里有多少个节点

  1. cluster nodes
  2. redis-cli -p 7000 cluster nodes # 等同于查看nodes-7000.conf文件节点信息

主从、哨兵、集群作用

redis主从:是备份关系, 我们操作主库,数据也会同步到从库。 如果主库机器坏了,从库可以上。就好比你 D盘的片丢了,但是你移动硬盘里边备份有。

redis哨兵:哨兵保证的是HA,即保证特殊情况故障自动切换,哨兵盯着你的“redis主从集群”,如果主库死了,它会告诉你新的主库是谁。

redis集群:集群保证的是高并发,因为多了一些兄弟帮忙一起扛。同时集群会导致数据的分散,整个redis集群会分成一堆数据槽,即不同的key会放到不不同的槽中。

主从保证了数据备份,哨兵保证了HA 即故障时切换,集群保证了高并发性。

Redis主从同步、哨兵、集群的更多相关文章

  1. 阿里云ECS部署Redis主备哨兵集群遇到的问题

    一.部署 详细部署步骤:https://blog.csdn.net/lihongtai/article/details/82826809 Redis5.0版本需要注意的参数配置:https://www ...

  2. C#两大知名Redis客户端连接哨兵集群的姿势

    前言 前面利用<Docker-Compose搭建Redis高可用哨兵集群>, 我们的思路是将Redis.Sentinel.Redis Client App链接到同一个网桥网络,这个网桥内的 ...

  3. kubernetes部署redis主从高可用集群

    1.redis主从高可用集群结构 2.k8s部署有状态的服务选择 对于K8S集群有状态的服务,我们可以选择deployment和statefulset statefulset service& ...

  4. Redis集合 安装 哨兵集群 配置

    redis相关 redis基础 redis发布订阅 redis持久化RDB与AOF redis不重启,切换RDB备份到AOF备份 redis安全配置 redis主从同步 redis哨兵集群 redis ...

  5. redis系列--深入哨兵集群

    一.前言 在之前的系列文章中介绍了redis的入门.持久化以及复制功能,如果不了解请移步至redis系列进行阅读,当然我也是抱着学习的知识分享,如果有什么问题欢迎指正,也欢迎大家转载.而本次将介绍哨兵 ...

  6. redis 主从同步&哨兵模式&codis

    主从同步 1.CPA原理 1. CPA原理是分布式存储理论的基石: C(一致性):   A(可用性):  P(分区容忍性); 2. 当主从网络无法连通时,修改操作无法同步到节点,所以“一致性”无法满足 ...

  7. redis + 主从 + 持久化 + 分片 + 集群 + spring集成

    Redis是一个基于内存的数据库,其不仅读写速度快,每秒可以执行大约110000的写操作,81000的读取操作,而且其支持存储字符串,哈希结构,链表,集合丰富的数据类型.所以得到很多开发者的青睐.加之 ...

  8. Redis 主从同步+哨兵

    简介 通过使用 Redis 自带“主从同步+哨兵守护”功能提高Redis稳定性. 主从同步:保障数据主从数据实时同步. 哨兵:实时监控主redis如果故障,将从redis作为主使用. 环境: 系统:C ...

  9. Redis之(七)主从同步与集群管理

    8.1 主从同步原理 像MySQL一样,Redis是支持主从同步的,而且也支持一主多从以及多级从结构. 主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的SORT就可以由从服务器来 ...

  10. redis 主从配置和集群配置

    主从配置 |  集群配置 redis主从 主从配置原因: 1.到达读写分离,读的操作和写操作比例10 : 1读数据频繁,写数据次数少,这样可以配置1个master数据库用来写数据,配置多个slave从 ...

随机推荐

  1. bzoj3510 首都 LCT 维护子树信息+树的重心

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3510 题解 首先每一个连通块的首都根据定义,显然就是直径. 然后考虑直径的几个性质: 定义:删 ...

  2. Docker(三):Docker入门教程-CentOS Docker 安装

    CentOS Docker 安装 Docker支持以下的CentOS版本: CentOS 7 (64-bit) CentOS 6.5 (64-bit) 或更高的版本 前提条件 目前,CentOS 仅发 ...

  3. git clone项目失败,Host key verification failed.

    在码云上创建了一个项目,配置好公钥后,克隆到我本地出现以下失败 百度了好久也没有找到解决办法,困扰了好久,后来还是百度到了, 原来是在提示 ey fingerprint is SHA256:FQGC9 ...

  4. 【leetcode】K-th Symbol in Grammar

    题目如下: 解题思路:直接把每行的数据计算出来肯定是不行的,因为N最大是30,那个第N行长度就是2^30次方,这显然不可取.那么就只能找规律了,我采取的是倒推法.例如假如我们要求出第四行第七个元素的值 ...

  5. Hybris commerce产品主数据的搜索API,批量返回若干主数据的值

    新建一个产品,identifier设置为i042416-1,创建之后立即能够在Backoffice里搜索出来: 等到Storefront的indexing做完之后,前台通过关键字i042416也能将这 ...

  6. JS中的执行机制(setTimeout、setInterval、promise、宏任务、微任务)

    1.执行机制 JS 是单线程的,处理 JS 任务(程序)只能一个一个顺序执行,所以 JS 中就把任务分为了同步任务和异步任务.同步的进入主线程先执行,异步的进入Event Table并注册函数,当指定 ...

  7. apache Internal Server Error 解决方法

    https://blog.csdn.net/qq_33684377/article/details/78536548 https://blog.csdn.net/LJFPHP/article/deta ...

  8. [BZOJ3236][AHOI2013]作业:树套树/莫队+分块

    分析 第一问随便搞,直接说第二问. 令原数列为\(seq\),\(pre_i\)为\(seq_i\)这个值上一个出现的位置,于是可以简化询问条件为: \(l \leq i \leq r\) \(a \ ...

  9. Layer Cake cf

    Layer Cake time limit per test 6 seconds memory limit per test 512 megabytes input standard input ou ...

  10. 170905-MyBatis中的关系映射

    ===关系映射=== 参考文档复习:1对1,1对多,多对多 1.映射(多)对一.(一)对一的关联关系 1).使用列的别名 ①.若不关联数据表,则可以得到关联对象的id属性 ②.若还希望得到关联对象的其 ...