从零单排学Redis【铂金二】
前言
只有光头才能变强
好的,今天我们要上【铂金二】了,如果还没有上铂金的,赶紧先去蹭蹭经验再回来(不然不带你上分了):
在上篇中抛出了一个问题:
抛个问题:如果从服务器挂了,没关系,我们一般会有多个从服务器,其他的请求可以交由没有挂的从服务器继续处理。如果主服务器挂了,怎么办?因为我们的写请求由主服务器处理,只有一台主服务器,那就无法处理写请求了?
Redis提供了哨兵(Sentinal)机制供我们解决上面的情况。如果主服务器挂了,我们可以将从服务器升级为主服务器,等到旧的主服务器(挂掉的那个)重连上来,会将它(挂掉的主服务器)变成从服务器。
- 这个过程叫做主备切换(故障转移)
在正常的情况下,主从加哨兵(Sentinal)机制是这样子的:
主服务器挂了,主从复制操作就中止了,并且哨兵系统是可以察觉出主服务挂了。:
Redis提供哨兵机制可以将选举一台从服务器变成主服务器
然后旧的主服务器如果重连了,会变成从服务器:
这篇文章主要讲讲Redis的哨兵(Sentinal)机制的一些细节。希望看完对大家有所帮助~
一、哨兵(Sentinal)机制
High Availability: Redis Sentinel is the official high availability solution for Redis.
哨兵(Sentinal)机制主要用于实现Redis的高可用性,主要的功能如下:
- Monitoring. Sentinel constantly checks if your master and slave instances are working as expected.
- Sentinel不停地监控Redis主从服务器是否正常工作
- Notification. Sentinel can notify the system administrator, another computer programs, via an API, that something is wrong with one of the monitored Redis instances.
- 如果某个Redis实例有故障,那么哨兵负责发送消息通知管理员
- Automatic failover. If a master is not working as expected, Sentinel can start a failover process where a slave is promoted to master, the other additional slaves are reconfigured to use the new master, and the applications using the Redis server informed about the new address to use when connecting.
- 如果主服务器挂掉了,会自动将从服务器提升为主服务器(包括配置都会修改)。
- Configuration provider. Sentinel acts as a source of authority for clients service discovery: clients connect to Sentinels in order to ask for the address of the current Redis master responsible for a given service. If a failover occurs, Sentinels will report the new address.
- Sentinel可以作为配置中心,能够提供当前主服务器的信息。
下面来具体讲讲Sentinel是如何将从服务器提升为主服务器的。
tips:Sentinel可以让我们的Redis实现高可用,Sentinel作为这么一个组件,自身也必然是高可用的(不可能是单点的)
1.1启动和初始化Sentinel
首先我们要知道的是:Sentinel本质上只是一个运行在特殊模式下的Redis服务器。因为Sentinel做的事情和Redis服务器是不一样的,所以它们的初始化是有所区别的(比如,Sentinel在初始化的时候并不会载入AOF/RDB文件,因为Sentinel根本就不用数据库)。
然后,在启动的时候会将普通Redis服务器的代码替换成Sentinel专用代码。(所以Sentinel虽然作为Redis服务器,但是它不能执行SET、DBSIZE等等命令,因为命令表的代码被替换了)
接着,初始化Sentinel的状态,并根据给定的配置文件初始化Sentinel监视的主服务器列表。
最后,Sentinel会创建两个连向主服务器的网络连接:
- 命令连接(发送和接收命令)
- 订阅连接(订阅主服务器的
_sentinel_:hello频道)
1.2获取和更新信息
Sentinel通过主服务器发送INFO命令来获得主服务器属下所有从服务器的地址信息,并为这些从服务器创建相应的实例结构。
当发现有新的从服务器出现时,除了创建对应的从服务器实例结构,Sentinel还会创建命令连接和订阅连接。
在Sentinel运行的过程中,通过命令连接会以每两秒一次的频率向监视的主从服务器的_sentinel_:hello频道发送命令(主要发送Sentinel本身的信息,监听主从服务器的信息),并通过订阅连接接收_sentinel_:hello频道的信息。
- 这样一来一回,我们就可以更新每个Sentinel实例结构的信息。
1.3判断主服务器是否下线了
判断主服务器是否下线有两种情况:
- 主观下线
- Sentinel会以每秒一次的频率向与它创建命令连接的实例(包括主从服务器和其他的Sentinel)发送PING命令,通过PING命令返回的信息判断实例是否在线
- 如果一个主服务器在
down-after-milliseconds毫秒内连续向Sentinel发送无效回复,那么当前Sentinel就会主观认为该主服务器已经下线了。
- 客观下线
- 当Sentinel将一个主服务器判断为主观下线以后,为了确认该主服务器是否真的下线,它会向同样监视该主服务器的Sentinel询问,看它们是否也认为该主服务器是否下线。
- 如果足够多的Sentinel认为该主服务器是下线的,那么就判定该主服务为客观下线,并对主服务器执行故障转移操作。
在多少毫秒内无效回复才认定主服务器是主观下线的,以及有多少个Sentinel认为主服务器是下线才认定为客观下线。这都是可以配置的
1.4选举领头Sentinel和故障转移
当一个主服务器认为为客观下线以后,监视这个下线的主服务器的各种Sentinel会进行协商,选举出一个领头的Sentinel,领头的Sentinel会对下线的主服务器执行故障转移操作。
选举领头Sentinel的规则也比较多,总的来说就是先到先得(哪个快,就选哪个)
选举出领头的Sentinel之后,领头的Sentinel会对已下线的主服务器执行故障转移操作,包括三个步骤:
- 在已下线主服务器属下的从服务器中,挑选一个转换为主服务器
- 让已下线主服务器属下的所有从服务器改为复制新的主服务器
- 已下线的主服务器重新连接时,让他成为新的主服务器的从服务器
- (这三步实际上就是文章开头的图片)
挑选某一个从服务器作为主服务器也是有策略的,大概如下:
- (1)跟master断开连接的时长
- (2)slave优先级
- (3)复制offset
- (4)run id
最后
这篇文章主要讲解了Sentinel的作用和工作的基本过程(我觉得已经基本OK了),其中也涉及到了很多的细节,这里我就没有一一整理出来了。想要深入学习的同学最好自己看看书或者文档~~
tips:目前为止的主从+哨兵架构可以说Redis是高可用的,但要清楚的是:Redis还是会丢失数据的
丢失数据有两种情况:
- 异步复制导致的数据丢失
- 有部分数据还没复制到从服务器,主服务器就宕机了,此时这些部分数据就丢失了
- 脑裂导致的数据丢失
- 有时候主服务器脱离了正常网络,跟其他从服务器不能连接。此时哨兵可能就会认为主服务器下线了(然后开启选举,将某个从服务器切换成了主服务器),但是实际上主服务器还运行着。这个时候,集群里就会有两个服务器(也就是所谓的脑裂)。
- 虽然某个从服务器被切换成了主服务器,但是可能客户端还没来得及切换到新的主服务器,客户端还继续写向旧主服务器写数据。旧的服务器重新连接时,会作为从服务器复制新的主服务器(这意味着旧数据丢失)。
可以通过以下两个配置尽量减少数据丢失的可能:
min-slaves-to-write 1
min-slaves-max-lag 10
从零单排学Redis【铂金三】,敬请期待~
参考资料:
- 《Redis设计与实现》
- 《Redis实战》
如果你觉得我写得还不错,了解一下:
- 坚持原创的技术公众号:Java3y。回复 1 加入Java交流群
- 文章的目录导航(精美脑图+海量视频资源):https://github.com/ZhongFuCheng3y/3y
从零单排学Redis【铂金二】的更多相关文章
- 从零单排学Redis【铂金一】
前言 只有光头才能变强 好的,今天我们要上铂金段位了,如果还没经历过青铜和白银和黄金阶段的,可以先去蹭蹭经验再回来: 从零单排学Redis[青铜] 从零单排学Redis[白银] 从零单排学Redis[ ...
- 从零单排学Redis【黄金】
前言 只有光头才能变强 好的,今天我们要上黄金段位了,如果还没经历过青铜和白银阶段的,可以先去蹭蹭经验再回来: 从零单排学Redis[青铜] 从零单排学Redis[白银] 看过相关Redis基础的同学 ...
- 从零单排学Redis【白银】
前言 只有光头才能变强 今天继续来学习Redis,上一篇从零单排学Redis[青铜]已经将Redis常用的数据结构过了一遍了.如果还没看的同学可以先去看一遍再回来~ 这篇主要讲的内容有: Redis服 ...
- 【3y】从零单排学Redis【青铜】
前言 只有光头才能变强 最近在学Redis,我相信只要是接触过Java开发的都会听过Redis这么一个技术.面试也是非常高频的一个知识点,之前一直都是处于了解阶段.秋招过后这段时间是没有什么压力的,所 ...
- [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念
上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(二)顺序
这不是草稿 辛巴学院:正大光明的不务正业. 上一次的教程写出来之后,反馈还是挺多的,有很多都做了修改,也有一些让人崩溃,不得不说上几句.有些人有些很奇怪的地方,你写篇东西,被看了以后不说他感觉怎么 ...
- 带你零基础入门redis【二】
本篇文章介绍redis如何设置开机自启动以及如何在java中应用 一.设置redis开机自启 1.修改redis配置 [root@VM_6_102_centos ~]# vim /usr/local/ ...
- 零基础学redis
第一个阶段:redis基本知识了解: 1. redis的百度百科解释: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...
- 从零单排学JavaWeb
之前是一个asp爱好者,感觉前途渺茫,特此转向Powerful的Java阵型,寻求心灵上的慰藉. 把自己遇到的问题记录下来,同时也分享给大家. 环境-下载 1 JDK http://dlsw.bai ...
随机推荐
- zlib 压缩输出缓冲区 overflow 问题
[TOC] 问题 后台服务传包太大时,我们框架可以使用 zlib 库对响应进行压缩:在这次服务调试过程中,使用 zlib compress2 以 Z_BEST_COMPRESSION 模式进行压缩时, ...
- 并发编程(十):AQS
AQS全称为AbstractQueuedSynchronizer,是并发容器中的同步器,AQS是J.U.C的核心,它是抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类都 ...
- java项目获取根路径(web项目和application项目的区分)
Java项目中经常要读取配置文件,涉及到读取配置文件的地方,就会要读定位文件的路径.因此,在项目如何正确获取文件路径尤为关键. 根据不同的java项目,在获取文件路径时候有一些 小区别 测试环境:E: ...
- Python_语法和界面设计
http://www.runoob.com/python/python-gui-tkinter.html http://www.python-course.eu/python_tkinter.php
- 实现对ASP.NETMvc及Asp.NetCore的权限控制
AccessControlHelper Build Status Intro 由于项目需要,需要在 基于 Asp.net mvc 的 Web 项目框架中做权限的控制,于是才有了这个权限控制组件. 项目 ...
- Android 样式的开发(转)
Android(2) 目录(?)[-] rectangle oval line ring layer-list篇 普通图片 bitmap标签 点九图片 nine-patch标签 color标签 ...
- linux timerfd系列函数总结
网上关于timerfd的文章很多,在这儿归纳总结一下方便以后使用,顺便贴出一个timerfd配合epoll使用的简单例子 一.timerfd系列函数 timerfd是Linux为用户程序提供的一个定时 ...
- XML解析的四种方法 建议使用demo4j解析 测试可以用
https://www.cnblogs.com/longqingyang/p/5577937.html 4.DOM4J解析 特征: 1.JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功 ...
- PHP写的爬虫,爬指定网站页面上的各种图片
打算用php实现一个爬虫,这是爬指定页面的图片的一段程序,其他的部分还没调试好,先把这个放上来 <?php $string=file_get_contents("http://www. ...
- toFixed()一不小心踩了一个坑
toFixed,多么简单的一个函数,昨天突发奇想做两道算法题练练手.结果,踩到了一个从未遇到的坑! \n 简单来讲是要对输入的很多组数据,自己写一个函数做个处理,把每次函数处理的结果要相加求和.最后输 ...