当前位置: 首页 > news >正文

Redis(三)事务、管道、主从复制

事务

事务是可以执行一个命令,也可以执行多个命令,事务本质上是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化地执行而不会被其他命令插入

Redis事务和传统数据库的区别

  1. 单独的隔离操作:Redis的事务仅仅是保证事务里面的操作会被连续独占的执行,redis命令的执行是单线程架构,在执行完事务内的所有指令之前是不可能再去同时执行其他客户端的请求的
  2. 没有隔离级别的概念:因为事务提交前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里面的更新,在事务外查询不能看到”这种问题了
  3. 不保证原子性:Redis的事务不保证原子性,也就是不保证所有的指令同时成功或失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
  4. 排他性:Redis会保证一个事务内的命令依次执行,而不会被其他命令插入

事务相关命令

  1. DISCARD:取消事务,放弃执行事务块内的所有命令
  2. EXEC:执行事务块中的所有命令
  3. MULTI:标记一个事务的开始
  4. UNWATCH:取消WATCH对所有key的监视
  5. WATCH key [key ……] :监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断

事务情况

正常执行

MULTI、EXEC

先执行MULTI的命令,就会开始记录命令,接下来的命令都会放入一个队列中,最后使用EXEC命令,放入队列中的命令会依次执行

放弃执行

MULTI、DISCARD

执行了MULTI命令之后,开始创建事务,若是想要放弃执行此事务,就使用DISCARD命令,就会退出事务

全体连坐

只要有一个命令是错的(写命令的时候就是错的),整个事务都会放弃执行,只有整个事务中的命令都是没问题的,才能正常执行此事务

怨头债主

当写事务中的命令时,写命令的语法都没错,执行EXEC之后,编译有的命令没通过,此时编译的命令执行成功,编译错的命令执行失败,Redis不提供事务回滚的功能,开发者必须在事务执行出错后,自行恢复数据库状态。

watch监控

watch命令是一种乐观锁的实现,redis在修改时会检测数据是否被更改,如果更改了,则执行失败。

使用unwatch就可以放弃监控

一旦执行了EXEC,之前加的监控锁都会被取消掉了

当客户端连接丢失的时候(比如退出连接),所有的东西都取消监视

管道

管道(pipeline)可以一次性地发送多条命令给服务端,服务端依次处理完毕后,通过一条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出的特性保证数据的顺序性。

以下方式可以实现管道:

cat 写有命令的文件 | redis-cli -a 123456 --pine

Pipeline与原生批量命令对比

  1. 原生批量命令是原子性,pipeline是非原子性
  2. 原生批量命令依次只能执行一种命令,pipeline支持批量执行不同命令
  3. 原生批量命令是服务端实现,而pipeline需要服务与客户端共同完成

Pipeline与事务的对比

  1. 事务具有原子性,管道不具有原子性
  2. 管道一次性将多条命令发送到服务器,事务是一条一条地发,事务只有在接收到exec的命令后才会执行,管道不会
  3. 执行事务时会阻塞其他命令的执行,而执行管道中的命令时不会

使用Pipe命令注意事项

  1. pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行中发生异常,将会继续执行后续的指令
  2. 使用pipeline组装的命令不能太多,不然数据量过大,客户端阻塞的时间可能过久,同时服务端此时也被迫回复一个队列应答,占用很多内存

发布订阅

是一种消息通信模式:发送者(PUBLISH)发送消息,订阅者(SUBSCRIBE)接收消息,可以实现进程间的消息传递。Redis可以实现消息中间件MQ的功能,通过发布订阅实现消息的引导和分流。不推荐使用该功能,专业的事情交给专业的中间件来处理,redis只要做好分布式缓冲功能。所以此知识点做了解即可。

发布订阅其实是一个轻量的队列,只不过数据不会被持久化,一般用来处理实时性较高的异步消息

发布订阅的常用命令:

  1. 订阅一个或多个符合给定模式的频道:PSUBSCRIBE pattern [pattern……]
  2. 查看订阅与发布系统状态:PUBSUB subcommand [arg [arg……]]
  3. 将消息发送到指定的频道:PUBLISH channel message
  4. 退订所有给定模式的频道:PUNSUBSCRIBE [pattern [pattern]]
  5. 订阅给定的一个或者多个频道的信息:SUBSCRIBE channel [channel……]
  6. 退订所有给定的频道:UNSUBSCRIBE [channel [channel……]]

订阅的客户端可以收到一个三个参数的消息:

  1. 消息的种类
  2. 始发频道的名称
  3. 实际的消息内容

缺点

  1. 发布的消息在Redis系统中不能持久化,因此,必须先执行订阅,在等待消息发布。如果先发布了消息,那么该消息由于没有订阅者,消息将被直接丢弃
  2. 消息只管发送对于发布者而言消息是即发即失的,不管接收,也没有ACK机制,无法保证消息的消费成功。
  3. 以上的缺点导致Pub/Sub在生产环境中几乎无用武之地,为此Redis5.0新增了Stream数据类型,不仅支持多播,还支持数据持久化,相比Pub/Sub更为强大

主从复制

主机master上的redis以写为主,从机slave以读为主。当master数据变化的时候,自动将新的数据同步到其他的slave数据库

主从复制能解决 读写分离、容灾恢复、数据备份、水平扩容支持高并发 的问题

通常配置从库,不配置主库

权限细节:

master如果配置了requirepass参数,需要密码登录。那么slave就要配置masterauth来设置校验密码,否则的话master会拒绝slave的访问请求(在配置文件中配置)

基本操作命令

  • info replication:可以查看复制节点的主从关系和配置信息
  • replicaof 主库ip 主库端口:在从机上配置,指定是复制哪个主机(一般写入redis.conf内)
  • slaveof 主库ip 主库端口:每次与master断开之后,都需要重新连接,除非配置进reids.conf文件。在运行期间修改slave节点的信息,如果该数据库已经是某个主数据库的从数据库,那么将会定制和原主数据库的同步关系转而和新的主数据库同步,重新拜码头。
  • slaveof no one:使得当前数据库停止与其他数据库的同步

普通主从复制

配置文件配置时

从机切入点问题:

如果从机没启动,启动时会复制主机的数据,启动后,会跟上主机的写操作。

主机SHUTDOWN之后,从机的情况:

从机会停止不动,原地等待待命,从机的数据可以正常使用。等待主机开启后再正常运行。

主机重启后,主从关系还在,从机还能继续顺利复制

手动指定主从关系时

当从机指定了主机之后,要是SHUTDOWN之后,就会失去主从关系,使用手动命令指定的就仅限于此次运行时,所以建议确认了主机就使用配置文件配置

多代主从复制

比如有着三台服务器1、2、3,1是2的主机,2是3的主机,以这种多代的方式进行主从复制。比起2、3是1的从机,多代的方式减轻了主机1的写压力。

中途变更主机的时候,会清除之前的数据,重新拷贝新的主机的数据

主从复制工作流程

  1. slave启动成功后连接到master之后会发送一个sync命令。slave首次全新连接master,一次完全同步(全量复制)将被自动执行,slave自身原有的数据会被覆盖清除。
  2. master节点在收到sync命令后会开启在后台保存快照(即RDB持久化,主从复制的时候会触发RDB),同时收集所有接收到的用于修改数据集命令缓缓存起来,master节点执行RDB持久化完成后,master将rdb快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步。而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化。
  3. master会定期发送ping包,默认是十秒,保持主从的通信。
  4. master继续将新的所有收集到的修改命令自动依次传给slave,完成同步
  5. 从机下线后重连时,master会检查backlog里面的offset,master和slave都会保存一个复制的offset和一个masterId。offset是保存在backlog中的。master只会把已经复制的offset后面的数据复制给slave

主从复制的缺点

复制延时,信号衰减

由于所有的写操作都是现在master上操作,然后同步更新到slave上,所以master同步到slave机器有一定的延时,当系统很繁忙的时候,延迟问题会更加严重,slave机器的数量的增加也会倒是这个问题更加严重

主机挂了,要手动指定新主机

默认情况下,不会在slave节点中自动重选一个master,每次都要人工干预,重选一个主机

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 大语言模型-对比学习-Contrastive Learning
  • 昇思25天学习打卡营第10天|xiaoyushao
  • 中小企业常见的网络安全问题及防范措施
  • 【大师与bug里特】M_Studio《王国之梦》学习笔记
  • Oracle 计算年龄
  • 充电桩浪涌保护方案—保障充电设施安全稳定运行的关键
  • sqlalchemy使用mysql的json_extract函数查询JSON字段
  • 电脑屏幕录制软件哪个好?推荐3款,满足各种录制需求
  • 【Django】 读取excel文件并在前端以网页形式显示-安装使用Pandas
  • 辛弃疾是那个时代的「六边形战士」
  • C# 代理模式
  • 半导体行业黑话-02
  • 【Qt】文字换行
  • 【Zoom 】超全!!!Zoom收藏这一篇足矣!!Zoom视频会议软件:全面解析与高效使用指南 (全文近1W字)
  • 无人机10公里WiFi图传摄像模组,飞睿智能超清远距离无线监控,智能安防新潮流
  • 0x05 Python数据分析,Anaconda八斩刀
  • IndexedDB
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Promise面试题,控制异步流程
  • SQLServer插入数据
  • unity如何实现一个固定宽度的orthagraphic相机
  • Vue2.0 实现互斥
  • Vue小说阅读器(仿追书神器)
  • webpack入门学习手记(二)
  • 笨办法学C 练习34:动态数组
  • 产品三维模型在线预览
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 基于游标的分页接口实现
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 由插件封装引出的一丢丢思考
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • zabbix3.2监控linux磁盘IO
  • ​​​【收录 Hello 算法】9.4 小结
  • #### golang中【堆】的使用及底层 ####
  • #数据结构 笔记一
  • #微信小程序(布局、渲染层基础知识)
  • #微信小程序:微信小程序常见的配置传旨
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • $.ajax()参数及用法
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (vue)el-tabs选中最后一项后更新数据后无法展开
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (四)汇编语言——简单程序
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (一)插入排序
  • (转)树状数组
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .NET CF命令行调试器MDbg入门(一)
  • .net core 连接数据库,通过数据库生成Modell
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?