Redis5.0:简单的集群模式——主从模式详解

Stella981
• 阅读 679

主从模式

主从模式是最简单的集群模式,其实就是复制基本只能解决读写分离问题, 主机服务器一旦宕机基本完蛋,不具备高可用

基本上redis的性能瓶颈主要在于网络IO和内存主频上面,单机版Redis在不考虑高可用的情况下基本满足80%的项目需要,因为单机版Redis可以实现10W/S的请求,除非缓存K-V值过大,通过读写分离缓存网卡的压力,否则这个并发处理能力可以应对大部分项目。

几乎所有的主从模式都是从服务器只提供只读不写的功能,否则会出现数据不一致的情况,现在无论那种数据库都不支持双向同步。

屁话少说,上配置代码,主服务器不需要配置,只需简单一句代码配置从服务器即可,声明主服务器是谁,余下的redis会自行交流。

slaveof 192.168.3.143 6379

Redis5.0:简单的集群模式——主从模式详解

一主多从

主服务器:192.168.3.143
从服务器:192.168.3.144
从服务器:192.168.3.145

从服务器 redis.conf 配置文件加入
slaveof 192.168.3.143 6379

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

一主多从(链式结构),所谓链式结构就是可以从服务器同步从服务器

主服务器:192.168.3.143
从服务器:192.168.3.144
从服务器:192.168.3.145

从服务器 redis.conf 配置文件加入
slaveof 192.168.3.143 6379

从服务器:192.168.3.147 
从服务器 redis.conf 配置文件加入 
slaveof 192.168.3.144 6379

Redis5.0:简单的集群模式——主从模式详解

尝试一下程序上来实现读写分离,Net Core 使用StackExchange.Redis 进行访问Redis集群,其它组件自己研究吧

//声明服务器地址,StackExchange会自己认别那个是主从关系
ConfigurationOptions option = new ConfigurationOptions();
option.EndPoints.Add("192.168.3.143", 6379);
option.EndPoints.Add("192.168.3.144", 6379);
option.EndPoints.Add("192.168.3.145", 6379);
option.EndPoints.Add("192.168.3.147", 6379);
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(option);

IDatabase db = redis.GetDatabase();
db.StringSet("test", "testvalue", flags: CommandFlags.DemandMaster);//CommandFlags.DemandMaster 标明主服务器写入
string value = db.StringGet("test", flags: CommandFlags.DemandReplica);//CommandFlags.DemandReplica 标明从服务器读取
Console.WriteLine(value);

Redis5.0:简单的集群模式——主从模式详解

代码行得通,已经分别从主/从服务器读取到数据,接下来将是要测试,主服务器倒下来了,会是怎么样?如图:成功报错,恭喜某程序猿喜提系统异常一次

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

接下三张图片将展示依次关闭从服务器:192.168.3.147,192.168.3.145 ,192.168.3.144 最后一张图将意味着己关闭所有从服务器,所有从服务器己关闭,程序运行成功报错

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

接着测试一下,StackExchange.Redis 框架问题,而对三个从服务器是否能分流从不同的从服务器取值,从而减轻从服务器的压力

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

从监控的图片来,三张从服务器的图标显示,StackExchange.Redis的确平均的分流的请求的流量。

哨兵模式

哨兵模式基本就是主从模式的升级版, 主要解决高可用问题,实现自动容错和恢复

简单理解就是主从模式一旦主机服务器宕机需要人工处理,这样一来你或者运维,得有一个睡不着,Redis引进哨兵模式的作用就是监控Redis服务是否正常运作,主服务器出现故障将自动将从服务器转换为主服务器。

理想状态下的配置架构如下:哨兵监控主从服务器,哨兵之间相互监控,组成哨兵组推荐三个哨兵以上并且最好独立部署,唯一能节省成本的好消息就是他们可以监控多个主服务器。

Redis5.0:简单的集群模式——主从模式详解

工作原理:

  1. 每个哨兵都会监控主/从服务器及其它哨兵。
  2. 当有一个哨兵检查主服务器下线(没有规定时间回复ping请求),会将主服务器标识为主观下线
  3. 当主服务器被标为主观下线,其它哨兵会马上检查主服务在线状态。
  4. 当足够的哨兵(超过配置数量)将它标识为主观下线,主服务器会变成客观下线,如果数量不够则主观下线状态会除移。
  5. 主服务器客观下线之后哨兵会从“从服务器”中选中一台服务器当主服务器。
  6. 哨兵将修改其它从服务器以及被修复旧主服务器的配置,将统一修改为从服务器并且修改它们的主服务器地址。

注意:每个哨兵配置不一样,每个哨兵根据自己的配置超时时间来判断主服务器是否主观下线只有符合就标为主观下线,每个哨兵根据自己设定的“肯定数量”来判断主服务器是否客观下线,只要有一个哨兵的配置达到客观下线该哨兵就会执行故障迁移操作。

从服务器选举原理:

  1. 首先发现客观下线的哨兵会发起一个选举请求,根据Raft算法,一般会成为领头哨头。
  2. 根据与主服务器的断开的时间判断
  3. 根据从服务器配置文件的权重(slave-priority)选举为主服务器
  4. 复制偏移,从主节点收到更多的新数据的节点会被选择
  5. 在所有条件相同的情况,选择runid最小的为主服务器

配置:只需要配置主数据库即可,哨兵会自动发现所有从数据库并进行监控,哨兵之间可以相互发现,只要确保端口放行就可以了,简单版配置简单到只有一句话

sentinel monitor <master-group-name> <ip> <port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2 //示例
//监控一个叫做mymaster的主节点,地址是 127.0.0.1 端口号是6379,判断客观下线需要2个哨兵“肯定”
//当然还有一些其它较为重要的配置,可以手动设定
sentinel down-after-milliseconds mymaster 60000 //设定检查超时时间,超过这个时间将认定为主观下线,默认30秒

下面进一些场景测试以验证观点,虽然支持采用默认配置的方式来进行启动,我们还是使用配置文件的方式进行启动

//主服务器
bind 0.0.0.0
port 6379
daemonize yes

//从服务器
bind 0.0.0.0
port 6379
daemonize yes
slaveof 192.168.3.40 6379

测试场景一:简单版测试,一主一从一哨兵,主服务器故障,能否自动将从服务器转换为主服务器

sentinel monitor mymaster 192.168.3.40 6379 1
sentinel down-after-milliseconds mymaster 5000//内网配置五秒就足够了
daemonize yes

成功运行

Redis5.0:简单的集群模式——主从模式详解

编写检查代码

class Program
    {
        static void Main(string[] args)
        {
            //声明服务器地址,StackExchange会自己认别那个是主从关系
            ConfigurationOptions option = new ConfigurationOptions();
            option.EndPoints.Add("192.168.3.40", 6379);
            option.EndPoints.Add("192.168.3.167", 6379);
            ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(option);

            IDatabase db = redis.GetDatabase();
            db.StringSet("test", "testvalue");
            DateTime exStartTime = DateTime.Now;
            DateTime exEndTime;
            bool isEX = false;
            while (true)
            {
                try
                {
                    var value = db.StringGet("test");
                    Console.WriteLine(value);
                    if (!value.HasValue && isEX!)
                        Console.WriteLine(value);
                    if (isEX && value.HasValue == true)
                    {
                        exEndTime = DateTime.Now;
                        Console.WriteLine($"连接成功,获取的值是:{value}");
                        break;
                    }
                }
                catch (Exception e)
                {
                    if (isEX == false)
                    {
                        Console.WriteLine($"连接失败!{e.Message}");
                        exStartTime = DateTime.Now;
                        isEX = true;
                    }
                }
            }
            Console.WriteLine($"连接异常时间{exStartTime},故障迁移成功时间{exEndTime},花费{(exEndTime - exStartTime).TotalSeconds}秒");
        }
    }

悄悄打开ESXI 把虚拟机的网线拔掉

Redis5.0:简单的集群模式——主从模式详解

果然成功报错,并且进行故障转移

Redis5.0:简单的集群模式——主从模式详解

这个时候,重新把网络设置回来,并且查看两个redis.conf的配置文件内容,发现配置已被改动,192.168.3.40 己由主服务器转变成从服务器,哨兵的配置也相应作了改变

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

测试场景二:一主三从一哨兵

//主服务器(192.168.3.40)
bind 0.0.0.0
port 6379
daemonize yes

//从服务器(192.168.3.167)
bind 0.0.0.0
port 6379
daemonize yes
slaveof 192.168.3.40 6379

//从服务器(192.168.3.168)
bind 0.0.0.0
port 6379
daemonize yes
slaveof 192.168.3.40 6379

//从服务器(192.168.3.169)
bind 0.0.0.0
port 6379
daemonize yes
slaveof 192.168.3.40 6379

哨兵的配置依旧不变

//哨兵服务器(192.168.3.171)
sentinel monitor mymaster 192.168.3.40 6379 1
sentinel down-after-milliseconds mymaster 5000//内网配置五秒就足够了
daemonize yes

一顿操作猛如虎,断掉网络

Redis5.0:简单的集群模式——主从模式详解

成功切换,看看这四台服务器的配置都发现了什么变化吧

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

测试场景三:一主三从三哨兵

主从服务器的配置不变,哨兵的配置稍有变化,哨兵的服务器由一台增加到三台,分别是192.168.3.171,192.168.3.172,192.168.3.170,哨兵能相互发现和相互监控

sentinel monitor mymaster 192.168.3.40 6379 2 //裁仲服务器由1台变成2台
sentinel down-after-milliseconds mymaster 5000//内网配置五秒就足够了
daemonize yes

好了,准备就绪,故技重演,断网

Redis5.0:简单的集群模式——主从模式详解

查看一下四台Redis服务器配置发生什么变化

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

查看一下,三台哨兵的配置发生什么变化

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

Redis5.0:简单的集群模式——主从模式详解

今天就测到这里了

原文链接:http://www.cnblogs.com/netcore3/p/14121749.html

如果觉得本文对你有帮助,可以关注一下我公众号,回复关键字【面试】即可得到一份Java核心知识点整理与一份面试大礼包!另有更多技术干货文章以及相关资料共享,大家一起学习进步!

Redis5.0:简单的集群模式——主从模式详解

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Peter20 Peter20
3年前
Redis集群详解
Redis集群详解Redis有三种集群模式,分别是:主从模式Sentinel模式Cluster模式三种集群模式各有特点,关于Redis介绍可以参考这里:Redis官网:https://redis.io/,最新版本5.0.4主从模式主从模式介绍主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(sl
Stella981 Stella981
3年前
Redis主从模式的常用类型
本文介绍Redis主从模式的常用类型。Redis的可靠性主要有主从模式和集群模式。对于主从模式而言,Redis有以下方案:Sentinel方案;Keepalived方案。Sentinel方案作为Redis主推的官方方案,主要的实现原理是通过引入哨兵sentinel节点,来投标决定master节点故障后,
Stella981 Stella981
3年前
Redis(1.7)Redis高可用架构(理论篇)
【0】常用架构种类  (0.1)单机Redis  (0.2)单纯的Redis主从复制  (0.3)哨兵SentinelRedis主从复制集群(实现高可用自动故障转移)  (0.4)RedisCluster分布式数据库集群  (0.5)第三方中间件Redis主从复制【1】Redis主从复制
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Redis、MPP、kafka 、MongDB简介
Redis:间值数据库,适合缓存用户Session会话与经常需要查的数据1.Redis集群,为什么在项目中使用集群 1.持久化,持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要左右是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失;2、复制:主从复制是高可用Redis的基础,哨兵和集群都是在复制基础上实现高可用
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这