redis入门指南(五)—— 复制与哨兵
写在前面
学习《redis入门指南》笔记,结合实践,只记录重要,明确,属于新知的相关内容。
一、复制
1、在复制中,数据库分为两类,一类主数据库,一类从数据库,主库用来读写,从库用来读,主库可以拥有多个从库,但从库只能拥有一个主库。
2、使用复制非常简单,只需要在从库的启动参数或运行时命令或配置文件中加入“ slaveof 主库地址 从库地址 ”即可,主库无需配置;可通过INFO replication查看主从的复制信息。
3、从库默认为只读,可通过修改配置文件参数slave-read-only为no使其可写,但从库的数据不会同步给主库;当使用slaveof命令修改了复制的主库,从库会停止和当前主库同步,转而同步新主库的数据;对于从库还可以使用SLAVE NO ONE停止接收从库信息,转换为主库。
4、复制原理:从库启动后向主库发送SYNC命令,主库收到后开始执行RDB持久化(即使没有开启持久化)并缓存持久化期间收到的命令,这两项任务结束后,会将rdb文件和缓存一并发给从库,从库使用临时文件保存这些数据,然后替换本地rdb文件并载入到内存,这一过程成为复制初始化,最后主库一旦收到写命令都会异步发送给从库。当主从断开重连后,2.6版本以前会重新执行复制初始化,2.8版本加入了增量复制。
5、主从复制采用异步方式,命令执行完毕立刻返回给客户端,之后异步发送命令给从库,这样保证了写入性能,但主从的数据会有一个不一致的时间窗,在命令同步完成前,如果网络断开,主库无法知道多少个从库同步了数据;通过设置参数min-slaves-to-write(至少有多少个从库连接才可以写入) 和min-slaves-max-lag(允许从库失去连接的最长时间)来降低主从不一致的可能性,这一特性默认关闭。
6、通过复制可以实现读写分离,并且从库也可以拥有自己的从库;对于较耗时的操作例如持久化,可以禁用主库的持久化而开启从库的,当从库崩溃重启后主库会自动同步数据过来;当主库崩溃时,必须先将从库提升为主库(通过slaveof no one),再将崩溃的主库设置为新的主库的从库,即可将数据同步。
注意:当开启复制,并关掉主库持久化功能时,若主库崩溃,一定不能使用监控工具直接重启主库,因为主库没有持久化,直接重启会导致主库数据丢失,并且从库会跟着复制主库,使得从库数据也被清空,失去持久化以及复制的意义。
7、基于RDB方式的持久化有明显的缺点,首先当主库禁用RDB时,依然会生成RDB文件,下次启动时会以该快照文件启动,这使得数据可能是任意时间点的,而不是最新的;其次,当硬盘性能较差时,每次和从库同步,都会执行一次快照对硬盘读写,性能会降低。2.8.18版本引入了无硬盘复制(通过参数repl-diskless-sync yes开启),不再将快照内容存储到硬盘,而是通过网络发送给从库,避免了硬盘性能瓶颈。
8、redis2.8版本实现了主从库的增量复制,首先,从库会存储主库的运行id(run id保证唯一),在复制同步阶段,主库每发一个命令,都会将其存放到一个积压队列中,并记录积压队列的存放命令的偏移量范围,然后从库每次收到命令会记录下该偏移量,重连时,主库判断从库传来的运行id是否与自己一致,接着判断命令偏移量是否在积压队列中,如果在则执行增量复制,将积压队列中相应的命令发给从库。如果不满足以上条件就会全部同步。
9、增量复制,使用“ PSYNC 主库运行id 断开前最新的命令偏移量 ”命令代替SYNC,增量复制的过程对于使用者来说时透明的;需要关注的就是积压队列(一个循环队列)的大小,通过参数repl-backlog-size(默认1M)来配置,参数repl-backlog-ttl(默认1小时)用来控制与从库断开多久后可以释放积压队列的内存。
二、哨兵
10、哨兵是一个独立的进程,提供了故障监控和自动化恢复的功能(如主库停止服务时,将从库提升为主库),哨兵可以用来监控数据库,也可以用来监控其他哨兵。
11、使用哨兵前,要先建立一个配置文件,如名为sentinel.conf,内容为:
格式为:sentinel monitor master-name ip port quorum
sentinel monitor mymaster 127.0.0.1
mymaster 表示主库名字,可以随便定义,之后是主库ip,port,1表示最低通过票数。配置哨兵时,只需配置主库,因为哨兵会主动发现主库的相关从库。
12、哨兵启动时,会先读取配置文件,master-name只能由字母、数字、“. - _”组成,quorum表示执行故障恢复操作前至少需要几个哨兵节点同意;一个哨兵节点可以监控多个主从系统(只需要配置文件多条配置),多个哨兵节点也可以监控同一个主从系统。
13、哨兵启动后,会与要监控的数据库建立两条连接,其中一条用来订阅主库的__sentinel__:hello频道以获取同样监控主库的其他哨兵的信息,由于订阅时无法执行其他命令,所以另一条连接用来发送其他命令。
14、建立连接后,哨兵执行三个操作,每10秒向主库和从库发送INFO命令,每2秒向主库和从库的__sentinel__:hello发送自己的信息,每1秒向主库,从库和其他哨兵节点发送PING。
15、发送INFO命令,获得数据库相关信息,运行id,复制信息等,从库的信息也在此时获得,并向每个从库建立两条连接,之后根据此信息不断更新自己的监控队列。
16、向频道__sentinel__:hello发送信息,用来与同样监控该数据库的哨兵分享自己的信息,如果发现新哨兵,则向其建立一条连接(用来发送PING,只需要一条连接),消息内容为:
<哨兵的地址>,<哨兵的断开>,<哨兵的运行id>,<哨兵的配置版本>,<主库的名字>, <主库的地主>,<主库的端口>,<主库的配置版本>
17、发送PING命令,实现了自动发现后,哨兵要通过PING监控节点是否运行,当配置参数down-after-milliseconds的值小于一秒时,会每隔down-after-milliseconds发送PING,大于1秒时,每隔一秒发送。
sentinel down-after-milliseconds master-name // 每隔1秒
sentinel down-after-milliseconds master-name // 每隔600毫秒
18、当超过down-after-milliseconds选项指定的时间后,仍没有回复,则哨兵认为其已经主观下线(表示从当前进程来看,该节点已停止服务),如果该节点是主库,则会判断是否需要故障恢复,哨兵发送SENTINEL is-master-down-by-addr询问其他哨兵是否也认为主库已停止服务,当达到指定数量(quorum参数),则会认为其客观下线,并选举领头哨兵对其执行故障恢复。
19、选举领头哨兵使用Raft算法,发现主库客观下线的哨兵向每个节点发送命令。要求对方选择自己成为领头哨兵,如果对方没有选过其他人,则会同意其成为领头哨兵,当发起选举的哨兵发现有超过半数且大于quorum个哨兵同意自己成为领头哨兵,则成功当选,当有多个哨兵时,会出现谁也没有当选的情况,此时会等待一个随机时间重新发起参选请求,直到成功;因为要有超过半数的哨兵同意,所以一次只会选举出一个领头哨兵。
20、选出领头哨兵后,开始进行故障恢复,先从停止服务的主库的从库中挑选一个来充当新的主库,选择优先级最高的从库,可通过slave-priority参数配置优先级,如果有多个优先级最高的从库,则选择复制的命令偏移量最大的(信息最完整),如果还没有选出唯一一个,则选择运行id最小的一个;选出数据库之后,领头哨兵发送SLAVE NO ONE使其升为主库,而向其他从库发送SLAVEOF命令使其成为新主库的从库,最后则是更新哨兵的内部记录,当旧的主库也更新为新主库的从库,使得当其恢复时以从库身份运行。
21、部署哨兵时,应尽可能地使哨兵的视角与每节点一致,如为每一个节点部署哨兵,每个哨兵与其对应的节点网络应尽可能一致,设置quorum参数为N/2+1(N为哨兵数量);但当节点较多时,会产生大量冗余连接,或者redis负载较高时,影响其对哨兵的回复或与其他哨兵的通信,所以哨兵配置还要根据实际的生存环境选择。
redis入门指南(五)—— 复制与哨兵的更多相关文章
- redis入门指南(六)—— 集群
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 配置集群 1.配置集群,集群解决了单点故障以及单台机器内存上限的问题,使用集群时,只需要将配置文 ...
- Redis入门指南之二(安装及配置)
本节主要内容 1. 前言2. redis安装3. 启动和停止Redis 1. 前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么red ...
- Redis入门指南之三(入门)
本节主要介绍Redis的5种数据类型,同时使用Python API来操作Redis,其中python版本为3.5, redis版本为4.0.2. redis-py 的API的使用可以分类为: (1)连 ...
- redis入门指南(四)—— redis如何节省空间
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 节省空间 1.redis对于它所支持的五种数据类型,每种都提供了两种及以上的编码方式去存储(具体 ...
- redis入门指南(七)—— 安全、协议、管理工具及命令属性
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 安全 1.可以使用bind参数绑定一个地址,使redis只接受这个地址的连接. 2.使用requ ...
- Redis入门指南之一(简介)
1. 简介 Redis是一个开源的.高性能的.基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同的场景下的缓存与存储需求.同时Redis的诸多高级功能使其可以胜任消息队列.任务队列等不同的 ...
- redis入门指南(二)—— 数据操作相关命令
写在前面 以下绝大部分内容取材于<redis入门指南>,部分结合个人知识,实践后得出. 只记录重要,明确,属于新知的相关内容,杜绝冗余和重复. 字符串 1.字符串类型是redis中最常见的 ...
- redis入门指南(三)—— 事务、过期时间、SORT命令、消息通知与管道
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 事务 1.redis中的事务由一组命令的集合组成,要么都执行,要么都不执行,同时redis的事务 ...
- redis入门指南书中概要
一.简介 1.redis是一个开源的.高性能的.基于键值对的缓存和存储系统,通过提供多种键值数据类型适应不同场景下的缓存和存储需求,同时redis高级功能能胜任消息队列.任务队列等不同角色. 2.内存 ...
随机推荐
- CODING DevOps 系列第一课:基于开源工具链打造持续交付平台
当下软件发展趋势 当今 IT 行业发展中比较流行的几个技术,首先是微服务化,将原有的一个系统拆分成多个,意味着有多个系统需要构建.测试.部署和运维. 第二个是敏捷开发模式,需求粒度更细化,要求一个可独 ...
- c++ cc24a_demo //转换函数,用来做转换操作符,int()括号里面必须是空的,必须定义为const,代码示范
c++ cc24a_demo //转换函数,用来做转换操作符,int()括号里面必须是空的,必须定义为const,代码示范 #include <iostream> #include < ...
- Redis命令速查
目录 string list set zset hash 记录下常用的,方便查找 string 内部sds,动态扩容.小于1M加倍扩,大于1M每次扩容1M.最大长度512M. SET name val ...
- 利用c++中的设计灵感,既要学BIM分类信息表,借助GIS完成环境搭建改善
我,一个平平无奇的城市规划专业(建筑专业.路桥专业)大学生,还有一年要毕业,很担心工作以后受到社会的毒打,遂问导师和学长,我要自学点什么技能和软件? 学长A:CAD,SketchUp,PS我都很熟练了 ...
- Django的F查询和Q查询,事务,ORM执行原生SQL
F查询和Q查询,事务及其他 F查询和Q查询 F查询 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个我们自己设定的常量做比较.如果我们要对两个字段的值做比较,那该怎么做呢? Django ...
- Java 多线程基础(十二)生产者与消费者
Java 多线程基础(十二)生产者与消费者 一.生产者与消费者模型 生产者与消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”.“消费者”.“仓库”和“产品”.他们之间的关系如下: ①.生 ...
- 解决start.spring.io无法访问的情况
将start.spring.io替换成下列网址 http://start.jetbrains.org.cn/ 或者----> 连接手机热点 因为绝大多数无法访问都是因为网络问题
- Mariadb之显式使用表锁和行级锁
首先我们来看看mariadb的锁定概念,所谓锁就是当一个进程或事务在操作某一资源时,为了防止其他用户或者进程或事务对其进行资源操作,导致资源抢占而发生冲突,通常在A进程操作该资源时,会对该资源进行加锁 ...
- dart快速入门教程 (7.2)
7.4.抽离类为单独文件 新建一个文件,单独存放一个类,例如:Person类抽离到person.dart文件中 class Person { final String name; final num ...
- JavaScript基础避免隐式的类型转换(004)
JavaScript在普通对比运算符“==”执行时可能会进行隐式的类型转换.比如:false==0和""==0的结果都是true.同理也适合于"!="运算符.要 ...