redis主从 哨兵
entinel是redis高可用的解决方案,sentinel系统(N个sentinel实例,N >= 1)可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。
1. sentinel初始化
可以使用命令
redis-sentinel /path/to/sentinel.conf
或者
redis-server /path/to/sentinel.conf --sentinel
来启动sentinel
sentinel启动时,需要经过一下几个步骤
a. 初始化服务
sentinel本质上是一个特殊的redis服务,所以初始化的时候跟redis服务初始化差不多,不过有几点不一样;首先sentinel不会载入RDB或者AOF文件,因为sentinel根本不使用数据库,其次,sentinel不能使用数据库键值对方面的命令,例如set、del、flushdb等等,同时,sentinel也不能使用事务、脚本、RDB或者AOF持久化命令,最后,复制命令,发布与订阅命令,文件事件处理器,时间事件处理器等只能在sentinel内部使用。
b. 将普通redis代码转成sentinel专用代码
将redis服务的代码转成sentinel的专用代码,例如sentinel的command与redis的command命令表就不一样(redis很多命令,sentinel不需要)
c. 初始化sentinel状态
主要是初始化sentinelState结构,sentinelState里面保存了sentinel的所有功能和状态,sentinelState结构如下
d. 根据指定的配置文件,初始化sentinel监视的主服务器列表
其实就是初始化sentinelState中的masters属性,masters字典中记录了所有被监视的主服务器信息,其中键是服务器名字,值是服务对应的sentinelRedisInstance结构,主要有实例名字,运行id,实例地址,客观下线票数,主管下线的最大无响应时间等等
sentinelState中masters字典的大致结构如下:
e. sentinel创建与masters(所有master)之间的网络连接
创建与被监视的master的网络连接后,sentinel成为该master的客户端,它会向master发送命令,并从master的响应中获取master的信息。对于每个被监视的master,sentinel会向其创建两个异步的网络连接
命令连接,这个连接专门用于向master发送命令,并接收命令回复
订阅连接,专门订阅master服务的 sentinel:hello频道
2. 获取master信息
sentinel以每10秒一次的频率向master发送info命令,通过info的回复来分析master信息,master的回复主要包含了两部分信息,一部分是master自身的信息,一部分是master所有的slave(从)的信息,所以sentinel可以自动发现master的从服务。sentinel从master哪儿获取到的master自身信息以及master所有的从信息,将会更新到sentinel的sentinelState中及masters(sentinelRedisInstance结构)中的slaves字典中
3. 获取从服务器信息
当sentinel发现master有新的从服务时,不但为从服务创建相信的实例结构,而且还会创建连接到该从服务的命令连接和订阅连接,创建命令连接后,sentinel会10秒每次的向从服务发送info命令,并从回复信息中提取从服务ID、从服务角色、从服务所属的主服务的ip及端口、主从服务的连接状态、从服务的优先级、从服务的复制偏移量等信息;创建或者更新到从服务的sentinelRedisInstance结构。
4. 向被监视服务器发送询问命令
sentinel会以每两秒一次的频率向所有的被监视服务器(master和从服务)发送询问命令,命令格式如下
publish ___sentinel___:hello s_ip s_port s_runid s_epoch m_name m_ip m_port m_epoch
各个参数的解析如下
s_ip:sentinel的ip
s_port:sentinel的端口
s_runid:sentinel云心id
s_epoch:sentinel当前的配置纪元
m_name:主服务器名字
m_ip:主服务器ip
m_port:主服务器端口
m_epoch:主服务器纪元
5. 接收被监视服务器的频道信息
sentinel与被监视的服务之间,一方面,sentinel通过命令链接发送信息到频道,另一方面,通过订阅连接从频道中接收信息。
对于同一服务的多个sentinel,一个sentinel发送的信息,会被其他sentinel收到,用于更新对该sentinel以及被监视服务的认知,用于更新sentinelRedisInstance的sentinels字典信息(请看sentinelRedisInstance的数据结构)及master信息。
当sentinel通过频道发现新的sentinel时,不但会更新上图的sentinel字典,同时会与新的sentinel建立命令连接(不会建立订阅连接,没啥可订阅的,因为sentinel与master及从建立订阅连接,是用来发现新的sentinel,而sentinel之间是已知的,所以不需要订阅连接),最终,监视同一个服务的多个sentinel会互联形成一个网络。
6. 主观下线
首先解析一下什么叫主观下线,所谓主观下线,就是单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。
sentinel会以每秒一次的频率向所有与其建立了命令连接的实例(master,从服务,其他sentinel)发ping命令,通过判断ping回复是有效回复,还是无效回复来判断实例时候在线(对该sentinel来说是“主观在线”)。
sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度,如果实例在down-after-milliseconds毫秒内,返回的都是无效回复,那么sentinel回认为该实例已(主观)下线,修改其flags状态为SRI_S_DOWN。如果多个sentinel监视一个服务,有可能存在多个sentinel的down-after-milliseconds配置不同,这个在实际生产中要注意。
7. 客观下线
当sentinel监视的某个服务主观下线后,sentinel会询问其它监视该服务的sentinel,看它们是否也认为该服务主观下线,接收到足够数量(这个值可以配置)的sentinel判断为主观下线,既任务该服务客观下线,并对其做故障转移操作。
sentinel通过发送 SENTINEL is-master-down-by-addr ip port current_epoch runid,(ip:主观下线的服务id,port:主观下线的服务端口,current_epoch:sentinel的纪元,runid:*表示检测服务下线状态,如果是sentinel 运行id,表示用来选举领头sentinel)来询问其它sentinel是否同意服务下线。
一个sentinel接收另一个sentinel发来的is-master-down-by-addr后,提取参数,根据ip和端口,检测该服务时候在该sentinel主观下线,并且回复is-master-down-by-addr,回复包含三个参数:down_state(1表示已下线,0表示未下线),leader_runid(领头sentinal id),leader_epoch(领头sentinel纪元)。
sentinel接收到回复后,根据配置设置的下线最小数量,达到这个值,既认为该服务客观下线
8. 选举领头sentinel
一个redis服务被判断为客观下线时,多个监视该服务的sentinel协商,选举一个领头sentinel,对该redis服务进行古战转移操作。选举领头sentinel遵循以下规则:
所有的sentinel都有公平被选举成领头的资格
所有的sentinel都有且只有一次将某个sentinel选举成领头的机会(在一轮选举中),一旦选举某个sentinel为领头,不能更改
sentinel设置领头sentinel是先到先得,一旦当前sentinel设置了领头sentinel,以后要求设置sentinel为领头请求都会被拒绝
每个发现服务客观下线的sentinel,都会要求其他sentinel将自己设置成领头
当一个sentinel(源sentinel)向另一个sentinel(目sentinel)发送is-master-down-by-addr ip port current_epoch runid命令的时候,runid参数不是*,而是sentinel运行id,就表示源sentinel要求目标sentinel选举其为领头
源sentinel会检查目标sentinel对其要求设置成领头的回复,如果回复的leader_runid和leader_epoch为源sentinel,表示目标sentinel同意将源sentinel设置成领头
如果某个sentinel被半数以上的sentinel设置成领头,那么该sentinel既为领头
如果在限定时间内,没有选举出领头sentinel,暂定一段时间,再选举
9. 故障转移
故障转移分为三个主要步骤
a. 从下线的主服务的所有从服务里面挑选一个从服务,将其转成主服务
sentinel状态数据结构中保存了主服务的所有从服务信息,领头sentinel按照如下的规则从从服务列表中挑选出新的主服务
删除列表中处于下线状态的从服务
删除最近5秒没有回复过领头sentinel info信息的从服务
删除与已下线的主服务断开连接时间超过 down-after-milliseconds*10毫秒的从服务,这样就能保留从的数据比较新(没有过早的与主断开连接)
领头sentinel从剩下的从列表中选择优先级高的,如果优先级一样,选择偏移量最大的(偏移量大说明复制的数据比较新),如果偏移量一样,选择运行id最小的从服务
b. 已下线主服务的所有从服务改为复制新的主服务
挑选出新的主服务之后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master
c. 将已下线的主服务设置成新的主服务的从服务,当其回复正常时,复制新的主服务,变成新的主服务的从服务
同理,当已下线的服务重新上线时,sentinel会向其发送slaveof命令,让其成为新主的从
redis主从 哨兵的更多相关文章
- redis主从+ 哨兵模式(sentinel)+漂移VIP实现高可用系统
原文:https://www.jianshu.com/p/c2ab606b00b7 客户端程序 客户端程序(如PHP程序)连接redis时需要ip和port,但redis-server进行故障转移时, ...
- Redis 主从+哨兵+监控 (centos7.2 + redis 3.2.9 )
环境准备: 192.168.0.2 redis01 主 192.168.0.3 redis02 从 192.168.0.4 redis03 从 Redis 主从搭建 一:下载并安装redis软件 ...
- redis主从+哨兵模式
主从模式配置分为手动和配置文件两种方式进行配置,我现在有192.168.238.128(CentOS1).192.168.238.131(CentOS3).192.168.238.132(CentOS ...
- redis主从+哨兵模式(借鉴)
三台机器分布 192.168.189.129 // master的角色 192.168.189.130 // slave1的角色 192.168.189.131 // salve2的角色 ...
- 【Redis学习专题】- Redis主从+哨兵集群部署
集群版本: redis-4.0.14 集群节点: 节点角色 IP redis-master 10.100.8.21 redis-slave1 10.100.8.22 redis-slave2 10.1 ...
- Redis主从&哨兵集群搭建
主从集群 在搭建主从集群前,我们先把Redis安装起来: #解压Redis压缩包 [root@master lf]# tar -zxvf redis-6.2.1.tar.gz -- #安装gcc [r ...
- 三千字介绍Redis主从+哨兵+集群
一.Redis持久化策略 1.RDB 每隔几分钟或者一段时间会将redis内存中的数据全量的写入到一个文件中去. 优点: 因为他是每隔一段时间的全量备份,代表了每个时间段的数据.所以适合做冷备份. R ...
- Redis主从哨兵和集群搭建
主从配置 哨兵配置 集群配置 1.主从: 国王和丞相,国王权力大(读写),丞相权利小(读) 2.哨兵: 国王和王子,国王死了(主服务挂掉),王子继位(从服务变主服务) 3.集群: 国王和国王,一个国王 ...
- redis 主从 哨兵
数据库为什么要读写分离 写代码好多年了,大家先抛弃在代码框架里面各种花哨的设计之外,写的代码到最后无非就是为了增删查改数据库.一般项目数据库刚开始只是但一个库,随着数据量的增大,就开始优化数据库(抛开 ...
- redis主从+哨兵 安装配置一
一.目的 实现redis的高可用. 二.同步过程 注意:当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给Slave,而Slave则把内存清空后,加载该文件到内存中: ...
随机推荐
- lvs+keepalived+nginx+tomcat
# 拓扑如下所示 # 节点分布情况 LVS-dr-master eth0: 192.168.146.141 LVS-dr-slave eth0: 192.168.146.142 nginx1: eth ...
- js中关于一个数组中最大、最小值以及它们的下标的输出的一种解决办法
今天在学习js中的数组时,遇到的输出一个数组中最大.最小值以及它们的下表,以下是自己的解决方法! <script type="text/javascript"> var ...
- 贪心 CF 332 C 好题 赞
题目链接: http://codeforces.com/problemset/problem/332/C 题目意思: 有n个命令,要通过p个,某主席要在通过的p个中选择k个接受. 每个任务有两个值ai ...
- ECSTORE验证码优化
用ecstore的朋友应该知道,ecstore的验证码超级鸡肋. 特别是字母和数字混合,根本就看不懂写的是什么? 数字还好,但是字母就别提了.而且还小. 索性就把验证码换掉.研究一下发现,ecstor ...
- 自动启动docker container
当系统启动的时候要启动docker container, 可以利用systemctl来实现 比如拿mongodb为例 创建 /usr/lib/systemd/system/docker_mongodb ...
- 微信分享jsdk接口
HTML文件 <!DOCTYPE html><html><head> <meta charset="utf-8"> <titl ...
- Visual studio 内存不足的解决方案(out of memory)
编译Visual Studio项目,如果出现"out of memory "的编译错误,可以进行如下操作,加大应用程序可以使用的内存. 请先备份好系统和设置好系统还原点,大体步骤是 ...
- 使用C# DES解密java DES加密的字符串
转自 microAllen 最近需要使用C#的DES解密工具类解密字符串,但是要解密的字符串是使用java进行DES加密的,去网上查了关于C#和java关于DES加密解密的资料,发现可以相互加密解 ...
- rtf表格的合并
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil Calibri;}{\f1\fnil\fcharset134 \'cb\'ce\ ...
- Chrome下的语音控制框架MyVoix.js使用篇(一)
日前因工作需求,着手研究了语音识别技术,发现github上有网友发布了一款叫做voix.js的javascript框架.在拜读voix.js的源码后发现了不少问题,于是自己写了一款语音识别框架MyVo ...