前面介绍Redis,我们都在一台服务器上进行操作的,也就是说读和写以及备份操作都是在一台Redis服务器上进行的,那么随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都很快,但是一定程度上也会造成一定的延时,那么为了解决访问量大的问题,通常会采取的一种方式是主从架构Master/Slave,Master 以写为主,Slave 以读为主,Master 主节点更新后根据配置,自动同步到从机Slave 节点。

  接下来我们就来介绍如何进行主从架构的搭建。

  ps:这里我是在一台机器上模拟多个Redis服务器,与实际生产环境中相比,基本配置都是一样,仅仅是IP地址和端口号变化。

  

一、修改配置文件

  首先将redis.conf 配置文件复制三份,通过修改端口分别模拟三台Redis服务器。

  

  然后我们分别对这三个redis.conf 文件进行修改。

  ①、修改 daemonize yes

  

  表示指定Redis以守护进程的方式启动(后台启动)

  ②、配置PID文件路径 pidfile

  

  表示当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面

  ③、配置端口 port

  

  ④、配置log 文件名字

  

  ⑤、配置rdb文件名

  

  依次将 6380redis.conf 、6381redis.conf 配置一次,则配置完毕。

  接下来我们分别启动这三个服务。

  

  通过命令查看Redis是否启动:

  

  接下来通过如下命令分别进入到这三个Redis客户端:

redis-cli -p
redis-cli -p
redis-cli -p

二、设置主从关系

  ①、通过  info replication 命令查看节点角色

      

  

  我们发现这三个节点都是扮演的 Master 角色。那么如何将 6380 和 6381 节点变为 Slave 角色呢?

  ②、选择6380端口和6381端口,执行命令:SLAVEOF 127.0.0.1 6379

      

  我们再看 6379 节点信息:

  

  这里通过命令来设置主从关系,一旦服务重启,那么角色关系将不复存在。想要永久的保存这种关系,可以通过配置redis.conf 文件来配置。

slaveof 127.0.0.1 

三、测试主从关系

  ①、增量复制

  主节点执行 set k1 v1 命令,从节点 get k1 能获取吗?

  

  

  

  由上图可知是可以获取的。

  ②、全量复制

  通过执行 SLAVEOF 127.0.0.1 6379,如果主节点 6379 以前还存在一些 key,那么执行命令之后,从节点会将以前的信息也都复制过来吗?

  答案也是肯定的,这里我就不贴测试结果了。

  ③、主从读写分离

  主节点能够执行写命令,从节点能够执行写命令吗?

  

  这里的原因是在配置文件 6381redis.conf 中对于 slave-read-only 的配置

  

  如果我们将其修改为 no 之后,执行写命令是可以的。

  

  但是从节点写命令的数据从节点或者主节点都不能获取的。

  ④、主节点宕机

  主节点 Maste 挂掉,两个从节点角色会发生变化吗?

  

  

  上图可知主节点 Master 挂掉之后,从节点角色还是不会改变的。

  ⑤、主节点宕机后恢复

  主节点Master挂掉之后,马上启动主机Maste,主节点扮演的角色还是 Master 吗?

  

  也就是说主节点挂掉之后重启,又恢复了主节点的角色。

四、哨兵模式

  通过前面的配置,主节点Master 只有一个,一旦主节点挂掉之后,从节点没法担起主节点的任务,那么整个系统也无法运行。如果主节点挂掉之后,从节点能够自动变成主节点,那么问题就解决了,于是哨兵模式诞生了。

  哨兵模式就是不时地监控redis是否按照预期良好地运行(至少是保证主节点是存在的),若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系。

  

  哨兵模式搭建步骤:

  ①、在配置文件目录下新建 sentinel.conf 文件,名字绝不能错,然后配置相应内容

   

sentinel monitor 被监控机器的名字(自己起名字) ip地址 端口号 得票数

  

  分别配置被监控的名字,ip地址,端口号,以及得票数。上面的得票数为1表示表示主机挂掉后salve投票看让谁接替成为主机,得票数大于1便成为主机

  ②、启动哨兵

redis-sentinel /etc/redis/sentinel.conf

  启动界面:

  

  接下来,我们干掉主机 6379,然后看从节点有啥变化。

  

  干掉主节点之后,我们查看后台打印日志,发现 6381投票变为主节点了。

  

  这时候我们查看从节点 6381的节点信息:

  

  6381 节点自动变为主节点了。

  PS:哨兵模式也存在单点故障问题,如果哨兵机器挂了,那么就无法进行监控了,解决办法是哨兵也建立集群,Redis哨兵模式是支持集群的。

五、主从复制原理

  Redis的复制功能分为同步(sync)和命令传播(command propagate)两个操作。

  ①、旧版同步

  当从节点发出 SLAVEOF 命令,要求从服务器复制主服务器时,从服务器通过向主服务器发送 SYNC 命令来完成。该命令执行步骤:

  1、从服务器向主服务器发送 SYNC 命令

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

  3、当主服务器的 BGSAVE 命令执行完毕时,主服务器会将 BGSAVE 命令生成的 RDB 文件发送给从服务器,从服务器接收此 RDB 文件,并将服务器状态更新为RDB文件记录的状态。

  4、主服务器将缓冲区的所有写命令也发送给从服务器,从服务器执行相应命令。

  ②、命令传播

  当同步操作完成之后,主服务器会进行相应的修改命令,这时候从服务器和主服务器状态就会不一致。

  为了让主服务器和从服务器保持状态一致,主服务器需要对从服务器执行命令传播操作,主服务器会将自己的写命令发送给从服务器执行。从服务器执行相应的命令之后,主从服务器状态继续保持一致。

  总结:通过同步操作以及命令传播功能,能够很好的保证了主从一致的特性。

  但是我们考虑一个问题,如果从服务器在同步主服务器期间,突然断开了连接,而这时候主服务器进行了一些写操作,这时候从服务器恢复连接,如果我们在进行同步,那么就必须将主服务器从新生成一个RDB文件,然后给从服务器加载,这样虽然能够保证一致性,但是其实断开连接之前主从服务器状态是保持一致的,不一致的是从服务器断开连接,而主服务器执行了一些写命令,那么从服务器恢复连接后能不能只要断开连接的哪些写命令,而不是整个RDB快照呢?

  同步操作其实是一个非常耗时的操作,主服务器需要先通过 BGSAVE 命令来生成一个 RDB 文件,然后需要将该文件发送给从服务器,从服务器接收该文件之后,接着加载该文件,并且加载期间,从服务器是无法处理其他命令的。

  为了解决这个问题,Redis从2.8版本之后,使用了新的同步命令 PSYNC 来代替 SYNC 命令。该命令的部分重同步功能用于处理断线后重复制的效率问题。也就是说当从服务器在断线后重新连接主服务器时,主服务器只将断开连接后执行的写命令发送给从服务器,从服务器只需要接收并执行这些写命令即可保持主从一致。

六、主从复制的缺点

  主从复制虽然解决了主节点的单点故障问题,但是由于所有的写操作都是在 Master 节点上操作,然后同步到 Slave 节点,那么同步就会有一定的延时,当系统很繁忙的时候,延时问题就会更加严重,而且会随着从节点slave的增多而愈加严重。

参考资料:https://www.cnblogs.com/ysocean/p/9143118.html

NoSql数据库Redis系列(5)——Redis主从复制的更多相关文章

  1. 项目实战11—企业级nosql数据库应用与实战-redis的主从和集群

    企业级nosql数据库应用与实战-redis 环境背景:随着互联网2.0时代的发展,越来越多的公司更加注重用户体验和互动,这些公司的平台上会出现越来越多方便用户操作和选择的新功能,如优惠券发放.抢红包 ...

  2. Redis系列(一):Redis的简介与安装

    原文链接(转载请注明出处):Redis系列(一):Redis的简介与安装 什么是 Redis Redis 是一个使用ANSI C 编写的开源.支持网络协议.基于内存.可选持久性的键值对数据库,它是一个 ...

  3. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  4. Redis系列一 Redis安装

    Redis系列一    Redis安装 1.安装所使用的操作系统为Ubuntu16.04 Redis版本为3.2.9 软件一般下载存放目录为/opt,以下命令操作目录均为/opt root@ubunt ...

  5. 企业级nosql数据库应用与实战-redis

    一.NoSQL简介 1.1 常见的优化思路和方向 1.1.1 MySQL主从读写分离 由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力.读写集中在一个数据库上让数据库不堪重负,大部 ...

  6. redis系列:redis介绍与安装

    前言 这个redis系列的文章将会记录博主学习redis的过程.基本上现在的互联网公司都会用到redis,所以学习这门技术于你于我都是有帮助的. 博主在写这个系列是用的是目前最新版本4.0.10,虚拟 ...

  7. NoSql数据库MongoDB系列(1)——MongoDB简介

    一.NoSQL简介    NoSQL(Not Only SQL ),意即“不仅仅是SQL” ,指的是非关系型的数据库 .是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨.No ...

  8. 深入剖析Redis系列: Redis集群模式搭建与原理详解

    前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...

  9. Redis系列之----Redis的两种持久化机制(RDB和AOF)

    Redis的两种持久化机制(RDB和AOF) 什么是持久化    Redis的数据是存储在内存中的,内存中的数据随着服务器的重启或者宕机便会不复存在,在生产环境,服务器宕机更是屡见不鲜,所以,我们希望 ...

  10. Redis系列二 Redis数据库介绍

    1.SELECT命令 通过查看配置文件可以知道Redis默认有17个库,从0-16. 默认是在0号库.选择库使用SELECT <dbid>命令.例如选择0号库  SELECT 0 2.DB ...

随机推荐

  1. vuecli3的项目搭建

    1.卸载旧版本 npm uninstall vue-cli -g 或者 yarn global remove vue-cli 2.安装cli3脚手架 npm install -g @vue/cli 或 ...

  2. JavaWeb 之 JSTL 标签

    JSTL 标签库 一.概述 1.概念 JSTL : JavaServer Pages Tag Library  JSP标准标签库. 是由 Apache 组织提供的开源的免费的 jsp 标签. 2.作用 ...

  3. python 系统定时关机

    #coding=utf-8 "shutdown at 23:00" from datetime import * import os import win32api import ...

  4. Windows下搭建TensorFlow的GPU版本

    1.下载python3.5.2版本并安装(必须是3.5版本,而且3.5后不带字母的版本) 2.使用下面的地址下载tensorflow的GPU版本 http://www.lfd.uci.edu/~goh ...

  5. [CAN].CAN总线详解

    转自:https://blog.csdn.net/cheatscat/article/details/82886889 CAN(Controller Area Network)总线协议是由 BOSCH ...

  6. HTML+Css+JavaScript知识点汇总

    HTML 部分 HTML基础知识 1. HTML简介 HTML(Hypertext Markup Language),超文本标记语言,HTML利用各种标记来标识文档的结构以及标识超链接的信息.它是从S ...

  7. spring cloud (五) 熔断面板 聚合熔断 turbine

    改造feign 项目 1 启动类添加注解  @EnableHystrix 2 添加如下配置文件 #ji eureka.instance.metadata-map.cluster=MAIN#actuat ...

  8. KClass与函数引用详解

    继续学习Kotlin反射相关的东东. KClass: 在上一次是通过类来获取它的KClass对象: 那如果是一个对象呢?与这个对象对应的类的KClass对象又是如何获取的呢?像Java也是一样有相关机 ...

  9. 关于srping的AOP事务管理问题,自定义切面是否导致事务控制失效

    applicationContext.xml: <!-- 方法调用时间记录 --> <bean id="methodExecuteTime" class=&quo ...

  10. 数组,字符串,json互相转换

    数组转字符串 var arr = [1,2,3,4,'巴德','merge']; var str = arr.join(','); console.log(str); // 1,2,3,4,巴德,me ...