Redis小记(三)
1、复制
通过slaveof命令或设置slaveof选项,实现一个服务器去复制另一个服务器,被复制的是主服务器,执行复制的是从服务器,复制过程中主从双方数据库保持数据一致
2.8版本以前,可分为初次复制和断线重复制两种情况,断线之后从服务器会向主服务器发送SYNC命令,主服务器收到SYNC命令之后执行BGSAVE命令,创建一个从开始到断线期间的RDB文件,并使用缓冲区记录接下来所执行的命令,并将RDB文件发送给从服务器,从武器进行数据同步,但是这样会占据大量的CPU资源、I/O资源、内存资源以及网络资源
2.8版本以后,使用PSYNC命令代替SYNC命令来执行复制时的同步操作,PSYNC命令分为完整重同步和部分重同步两种,完整重同步用于初次复制,部分重同步用于断线重复制,从服务器断线再连接会向主服务器发送PSYNC命令,主服务器收到PSYNC命令命令后会向从服务器返回+CONTINUE命令,执行部分重同步,把断线期间执行的命令发送给从服务器,从服务器执行命令后完成与主服务器数据同步
部分同步同过复制偏移量、复制积压缓冲区、服务器运行ID三部分来实现
复制的过程:客户端向服务器发送SLAVEOF <ip> <port> 命令,设置主服务器的地址端口
从服务器根据命令中的IP和端口,创建向主服务器的套字连接
当从服务器成为主服务器的客户端后,向服务器发送一个ping命令,ping用于检查通讯是否正常,主服务是否可以正常处理命令,主服务器会返回一个PONG
从服务器收到主服务器返回的PONG后,进行身份验证
通过验证后,向主服务器发送从服务器的监听端口号
从服务器向主服务器发送PSYNC命令开始同步
同步之后,主从服务器就会进入命令传播阶段,这阶段主服务器会一直把自己执行的命令发送给从服务器,从服务接收并执行,以达到数据同步的期望
命令传播阶段,从服务器会每隔1秒向主服务器发送心跳检测命令
2、Sentinel(哨兵)
Redis高可用性解决方案之一,由一个或多个Sentinel实例组成的Sentinel系统可以随意监视多个主服务器以及其下的从服务器
通过$ redis-server /path/to/your/sentinel.conf --sentinel来启动Sentinel
启动Sentinel的步骤:初始化服务器、将普通服务器使用的代码替换为Sentinel专用服务器、初始化Sentinel状态、根据给定的配置文件,初始化Sentinel的监视服务器列表、创建向主服务器的连接(命令连接,向主服务器发送命令和接收命令回复、订阅链接,订阅主服务器的_Sentinel_:hello频道)
Sentinel会默认10秒一次向服务器发送INFO命令并通过解析回复命令获取当前服务器的信息
故障转移:在已经下线的主服务器属下的从服务器中挑选出一个,作为新的主服务器
让其他从服务器改为复制新主服务器
将已下线的主服务器设置为新主服务器的从服务器
挑选新主服务器的步骤:将所有从服务器保存到列表里,方便过滤
删除下线和断线的从服务器
删除最近5秒内没有回复过Sentinel的INFO命令的从服务器
删除与已下线主服务器连接断开超过down-after-milliseconds*10毫秒的从服务器
根据优先级选出剩下从服务器优先级最高的从服务器作为主服务器
3、集群
Redis集群是分布式数据库,集群通过分片(sharding)进行数据共享、复制以及故障转移
一个集群由多个节点组成,在集群中,一个节点就是一个redis服务器,每个节点相互连接,携手工作,可以用命令CLUSTER MEET <ip> <port> 来完成节点连接,某一节点发送CLUSTER MEET命令时,会与ip和port指定的节点进行握手,握手成功,ip和port指定的节点就会添加到这个节点的集群中
Redis服务启动时会根据cluster-enabled的配置来决定是否开启服务器集群模式,集群模式下可以使用单机模式的所有服务器组件
集群模式下使用到的数据会保存到clusterNode结构中,主要保存节点的创建时间、节点名字、当前的配置纪元、ip、端口、连接节点所需要的相关信息等,连接节点所需要的相关信息的link属性是一个clusterNode结构,保存了套接字描述字符、输入缓冲区、输出缓冲区
集群中每个节点都包含一个clusterNode,记录集群现在状态、包含多个节点、集群当前配置纪元信息等

CLUSTER MEET <ip> <port> 命令实现:客户端向A节点发送CLUSTER MEET <ip> <port> 命令,A节点会把指定IP、端口的B节点添加到A所在的集群里
A节点收到命令后,与B节点进行握手,确认B节点是否存在,此时A节点会为B节点创建一个clusterNode,并把这个clusterNode添加到自己的clusterStater.nades字典里,之后,A节点会向B节点发送一条MEET消息
B节点收到A节点发送的消息,为A节点创建一个clusterNode,并把这个clusterNode添加到自己的clusterStater.nades字典里,并向A节点返回一条PONG消息
A节点收到PONG消息后向B节点发送一条ping消息,此时A已知与B已经连通
B节点收到ping消息,此时B已知与A已经连通,握手完成
A节点会将B节点的信息通过Gossip协议传播给集群中其他节点,其他节点相继与B节点进行握手,全部完毕后,B节点加入集群
槽指派:redis集群通过分片来保存数据库中键值对,集群中数据库被分为16384个槽,数据库中每个数据都属于这个槽的其中一个,每个节点可以处理0到16384个槽
当集群中16384个槽都有节点处理时,集群处于上线状态,反之处于下线状态,通过CLUSTER ADDSLOTS命令可以把把一个或多个槽指派给节点
节点会把自己负责处理的槽记录到clusterNode中的slots(数组结构,记录处理哪些槽)属性和numslotss属性(记录处理槽的数量),还会把自己的slots(数组结构,包含16384个项,记录处理哪些槽)属性通过消息群发给集群中其他节点
集群模式下,当所有节点都加入到集群中并给每个节点都指派槽之后,集群正式上线,当客户端向节点发送处理数据的命令时,接收的节点会计算出命令要处理的数据属于哪个槽,并检查这个槽是否分配给自己,是,直接处理,否,向客户端返回一个MOVED的错误(MOVED错误是会隐藏的,不会打印出来),并指引客户端指向正确的节点,再次发送命令
集群数据库与单机数据库对键值对过期处理是一样的,但是集群数据库只能使用0号数据库
重新分片:集群中重新分片可以把任意数量的槽指派给别的节点,相关槽的键值对也会转移到新节点下,重新分配时,集群不用下线,可以继续处理数据
ASk错误:重新分片期间,客户端向A节点发送一条数据处理的命令,而此时A节点中这条数据已经转移到B节点,A节点会向客户端返回一个ASK错误,并指引客户端指向B节点
复制和故障转移:集群中节点分为主节点和从节点,主节点负责处理槽,从节点负责复制主节点和主节点下线时代替主节点继续处理命令,每个节点之间定期向其他节点发送ping命令并查看在规定时间内是否收到pong命令,以此来检测故障
故障转印步骤:在从节点中选出一个执行SLAVEOF NO ONE命令,提升为新的主节点
新的主节点会撤销所有对已下线主节点的槽的指派,并将这些槽都只派给自己
新的主节点向集群广播一条pong消息,这条pong消息会让其他节点知道主节点已经变更,新主节点负责处理原主节点所指派的槽
新节点开始接收和处理自己负责的槽的命令,故障转移完成
集群中节点发送消息类型:MEET消息,节点加入集群中时发送
PING消息,每个节点定期发送
PONG消息,回复MEET消息和PING消息
FALL消息,当A节点判断B节点进入FALL状态,会向集群中广播B节点进入FALL状态
PUBLISH消息,当一个节点收到PUBLISH命令时,节点会执行命令,并向集群广播这条命令
4、发布和订阅
redis中发布和订阅是通过PUBLISH、SUBSCRIBE、PSUBSCRIRE等命令组成
redis把所有的订阅关系都保存在服务器状态的pubsub_channels字典里,字典中键是被订阅的频道,键的值是一个链表,记录所有订阅频道的客户端
redis把所有的订阅关系都保存在服务器状态的pubsub_patterns的链表里,链表中每个节点都包含一个PubsubPatterns结构,PubsubPatterns中pattern属性记录被订阅的模式,client属性记录订阅这个模式的客户端
SUBSCRIBE:客户端通过此命令订阅一或多个频道,成为频道的订阅者,每当其他客户端向频道发送消息时,频道所有的订阅者都可以收到这条消息
UNSUBSCRIBE:退订频道,根据退订频道的名字在pubsub_channels字典中找到相应的订阅的信息,从链表中删除退订客户端信息,当客户端信息为0时,删除频道对应的键
PSUBSCRIBE:客户端通过此命令订阅一或多个模式,成为模式的订阅者,每当其他客户端向频道发送消息时,不仅频道所有的订阅者都可以收到这条消息,与这个频道相匹配的模式的订阅者也会收到
PUNSUBSCRIBE:退订模式,服务器在pubsub_patterns链表中查找并删除那些pattern属性为被退订模式,并且client属性为执行退订命令客户端的pubsubPattern结构
PUBLISH <channel> <meaasge>:将消息message发送给channel频道,频道的所有订阅者和与channel频道模式相匹配的模式的订阅者也会收到
查看订阅消息:PUBSUB CHANNELS,用于返回服务器当前被订阅的频道
PUBSUB NUMSUB,返回频道的订阅者数量
PUBSUB NUMPAT,返回服务器当前被订阅模式数量
5、事务
redis事务提供了一种将多个命令打包,然后一次性、顺序性的执行多个命令的机制,并且在执行事务期间,服务器不会中断事务而去执行其他客户端的命令请求,它会在事务执行完后在去执行其他命令
Redis小记(三)的更多相关文章
- 基于Redis的三种分布式爬虫策略
前言: 爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多. 个人以为分布式爬虫需要考虑的点主要有以下几个: 爬虫任务的统一调度 爬虫任务的统一去重 存储问题 速度问题 足够“ ...
- redis入门(三)
目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...
- 一文掌握Redis的三种集群方案
在开发测试环境中,我们一般搭建Redis的单实例来应对开发测试需求,但是在生产环境,如果对可用性.可靠性要求较高,则需要引入Redis的集群方案.虽然现在各大云平台有提供缓存服务可以直接使用,但了解一 ...
- Redis系列三之持久化
一.Redis持久化 Redis是一个支持持久化的内存数据库,redis需要经常将内存中的数据同步到磁盘来保证持久化. redis提供了不同级别的持久化方法: Snapshotting(快照,默认方式 ...
- Redis简介三
目录 一.Key 二.String 三.Hash 四.List 五.Set 六.SortedSet 七.Pub/Sub 八.Transaction 九.Script 十.Connection 十一.S ...
- Redis 学习(三) —— 事务、消息发布订阅
一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...
- C# Redis实战(三)
三.程序配置 在C# Redis实战(二)中我们安装好了Redis的系统服务,此时Redis服务已经运行. 现在我们需要让我们的程序能正确读取到Redis服务地址等一系列的配置信息,首先,需要在Web ...
- Redis(三)Redis基本命令操作与API
一Redis 连接 Redis 连接命令主要是用于连接 redis 服务. 实例 以下实例演示了客户端如何通过密码验证连接到 redis 服务,并检测服务是否在运行: redis 127.0.0.1: ...
- Redis学习三:Redis数据类型
一.Redis的五大数据类型 1.String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value.string类型是二进制安 ...
随机推荐
- 10分钟搞定 Java 并发队列好吗?好的
| 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...
- Docker 镜像构建之 Dockerfile
在 Docker 中创建镜像最常用的方式,就是使用 Dockerfile.Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明.官方文档:https://d ...
- day40:python操作mysql:pymysql模块&SQL注入攻击
目录 part1:用python连接mysql 1.用python连接mysql的基本语法 2.用python 创建&删除表 3.用python操作事务处理 part2:sql注入攻击 1.s ...
- 华为SEO搜索引擎主管招聘内容
http://www.wocaoseo.com/thread-166-1-1.html 华为SEO搜索引擎主管招聘内容: 职位职责 1. 提出全站的SEO策略和实施计划,推动和监督计划实施:负责提升各 ...
- Flink自定义Sink
Flink自定义Sink Flink 自定义Sink,把socket数据流数据转换成对象写入到mysql存储. #创建Student类 public class Student { private i ...
- 在Spring中拦截器的使用
Filter Filter是Servlet容器实现的,并不是由Spring 实现的 下面是一个例子 import java.io.IOException; import javax.servlet.F ...
- 攻防世界——Misc新手练习区解题总结<3>(9-10题)
第九题SimpleRAR: 下载附件后得到一个压缩包打开后得到如下提示 文件头损坏,让我们打开winhex看一下 7a为子块而文件头为74,这里将7a改为74(这里我也不是很清楚,详细大家可以自行去查 ...
- 我对Flutter的第一次失望
老孟导读:此文翻译自:https://medium.com/@suragch/my-first-disappointment-with-flutter-5f6967ba78bf 我喜欢Flutter. ...
- Robot Framework自动化测试框架核心指南-如何做好自动化测试平台框架的设计
自动化测试如果需要能高效快速的支撑软件项目的测试,项目的快速迭代以及上线,除了以上我们介绍的需要许多的Lib来支持以及需要高效的去编写自动化测试案例外,还需要一个好的自动化测试框架平台来支撑我们的自动 ...
- Mac Item2自动远程连接服务器
Mac Item2自动远程连接服务器 1.编写脚本 vi test #!/usr/bin/expect set PORT 端口 set HOST ip set USER root set PASSWO ...