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小记(三)的更多相关文章

  1. 基于Redis的三种分布式爬虫策略

    前言: 爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多. 个人以为分布式爬虫需要考虑的点主要有以下几个: 爬虫任务的统一调度 爬虫任务的统一去重 存储问题 速度问题 足够“ ...

  2. redis入门(三)

    目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...

  3. 一文掌握Redis的三种集群方案

    在开发测试环境中,我们一般搭建Redis的单实例来应对开发测试需求,但是在生产环境,如果对可用性.可靠性要求较高,则需要引入Redis的集群方案.虽然现在各大云平台有提供缓存服务可以直接使用,但了解一 ...

  4. Redis系列三之持久化

    一.Redis持久化 Redis是一个支持持久化的内存数据库,redis需要经常将内存中的数据同步到磁盘来保证持久化. redis提供了不同级别的持久化方法: Snapshotting(快照,默认方式 ...

  5. Redis简介三

    目录 一.Key 二.String 三.Hash 四.List 五.Set 六.SortedSet 七.Pub/Sub 八.Transaction 九.Script 十.Connection 十一.S ...

  6. Redis 学习(三) —— 事务、消息发布订阅

    一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...

  7. C# Redis实战(三)

    三.程序配置 在C# Redis实战(二)中我们安装好了Redis的系统服务,此时Redis服务已经运行. 现在我们需要让我们的程序能正确读取到Redis服务地址等一系列的配置信息,首先,需要在Web ...

  8. Redis(三)Redis基本命令操作与API

    一Redis 连接 Redis 连接命令主要是用于连接 redis 服务. 实例 以下实例演示了客户端如何通过密码验证连接到 redis 服务,并检测服务是否在运行: redis 127.0.0.1: ...

  9. Redis学习三:Redis数据类型

    一.Redis的五大数据类型 1.String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value.string类型是二进制安 ...

随机推荐

  1. YOLO v3算法介绍

    图片来自https://towardsdatascience.com/yolo-v3-object-detection-with-keras-461d2cfccef6 数据前处理 输入的图片维数:(4 ...

  2. py_选择排序

    # 选择排序 # 一趟排序记录最小值,放到第一个位置 #再一趟排序记录记录列表无序区最小的数,放到第二个位置 #.... # 关键点:有序区.无序区.无序区最小值 #方法一 def select_So ...

  3. 认识JavaScript中Let和Var的区别

    本文转载自:https://www.cnblogs.com/songzxblog/p/11137117.html

  4. 前端模块化IIFE,commonjs,AMD,UMD,ES6 Module规范超详细讲解

    目录 为什么前端需要模块化 什么是模块 是什么IIFE 举个栗子 模块化标准 Commonjs 特征 IIFE中的例子用commonjs实现 AMD和RequireJS 如何定义一个模块 如何在入口文 ...

  5. wampserver64 apache2.4版本局域网互相访问总结

    wampserver64  apache2.4版本局域网互相访问总结 背景:在我的电脑上给算法组开发了一个工具,需要在局域网环境下其他同事都能访问到,搞了一下午终于搞定,于是整理了这篇文档,给其他同行 ...

  6. 发生错误 1069 sqlserver

    ---------------------------SQL Server 服务管理器---------------------------发生错误 1069 - (由于登录失败而无法启动服务.),此 ...

  7. Python の 在 VSCode 中使用 IPython Kernel 的方法

    本文介绍,在 VSCode 使用 IPython Kernel,的设置方法. 要达到的效果: 只需按下 Ctrl+:,选中的几行代码,就会自动发送到 IPython Kernel,并运行,得到结果!当 ...

  8. Windows下安装nvm管理多个nodejs版本

    平常在工作中难免会有node版本的要求,下面介绍一种利用nvm工具管理多个node版本的方法 下载安装 Github: Download nvm-windows --- nvm-setup.zip 程 ...

  9. Windows+Git+TortoiseGit+COPSSH安装图文教程

    http://blog.csdn.net/aaron_luchen/article/details/10498181/ http://jingyan.baidu.com/article/3a2f7c2 ...

  10. C#开发PACS医学影像处理系统(三):界面布局之工具栏

    工具栏布局采用WPF中Grid作为容器,按钮采用自定义样式和图标,并采用Separator分割线: XAML设计器代码: 其中  Style="{StaticResource ButtonS ...