首页 > 数据库 >Redis(三)事务、管道、主从复制

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

时间:2024-07-28 12:59:51浏览次数:18  
标签:主从复制 slave 主机 Redis 事务 命令 管道 master 执行

事务

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

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,每次都要人工干预,重选一个主机

标签:主从复制,slave,主机,Redis,事务,命令,管道,master,执行
From: https://blog.csdn.net/2302_79468488/article/details/140748858

相关文章

  • Redis Java客户端(带示例代码)
    目录概述Jedis--快速入门Jedis简介创建项目和测试1.引入依赖2.建立连接3.测试4.释放资源Jedis连接池JedisPool简介创建连接池使用连接池概述在Redis官网中提供了各种语言的客户端网站:ConnectwithRedisclients标记为❤的就是推荐使用的java客......
  • Redis中缓存二进制数据
    使用FreeRedis访问:byte[]b=File.ReadAllBytes("e:\\3专职安全员C-模拟题库.pdf");Stopwatchp=newStopwatch();p.Start();cli.SetRange("key8",0,b);cli.Expire("key8",30);this.textBox1.Text=p.ElapsedMilliseconds.ToString();......
  • 【C# 】Pipe管道通信使用
    管道通信        管道通信(PipeCommunication)可以用来在两个或多个进程之间传递数据。        管道可以是匿名的也可以是有名的,有名管道允许不同进程间的通信,而匿名管道通常用于父子进程之间的通信。    详细参考pipe管道通信原理_核间通信pipe通信......
  • 基于redis实现分布式锁
           分布式锁1.基于redis实现分布式锁注意:这里设置过期时间,是为了预防死锁。如果某个线程获取了锁,但还没等它执行完业务,释放锁。服务器就宕机了,那么就不会有人再去释放锁,出现了死锁问题。简单业务代码:publicinterfaceILock{booleantryLock(longt......
  • Raft协议深度解析:RocketMQ中基于DLedger的日志主从复制
    本文所涉及的注释源码:bigcoder84/dledgerRaft协议主要包含两个部分:Leader选举和日志复制。前面我们在Raft协议深度解析:RocketMQ中的自动Leader选举与故障转移一文中已经详细介绍了DLedger如何实现Leader选举的,而本文主要聚焦于Leader选举完成后的日志复制的过程。一.Rock......
  • redis的使用场景-热点数据缓存
    1.什么是缓存?把一些经常访问的数据放入缓存中,减少访问数据库的频率,减少数据库的压力,从而提高程序的性能。【内存中存储】2.缓存的原理通过上图可以看出程序首先访问缓存,如果缓存中有访问的数据会直接方会给客户端,不需要访问数据库,如果缓存中没有需要的数据则访问数据库,命中......
  • 如何使用 LangChain 查看 MultiQueryRetriever 管道中的最终提示?
    我目前正在使用LangChain库开展一个项目,我想从向量数据库中检索相关文档,然后使用OllamaLLM根据这些文档生成答案。以下是我当前的实现:importlogginglogging.basicConfig()logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)#Defin......
  • 常用的NOSQL产品——redis(上)
    一,什么是NOSQLnosql[notonlysql]不仅仅是sql。所有非关系型数据库的统称。除去关系型数据库之外的都是非关系数据库。NOSQL和RDBMS的区别RDBMS--关系型数据库得到通称-高度组织化结构化数据。 -结构化查询语言(SQL)sql语句 -数据和关系都存储在单独的表中。-数据......
  • windows redis5使用,下载安装
    1.Reids下载Redis对windows支持停留在3版本,在github看到有大佬适配的5版本可用地址:https://github.com/tporadowski/redis/releases访问不了的可在此链接下载:https://download.csdn.net/download/qq_51355375/895851952.Redis使用2.1cmd启动redis-server.exe......
  • 管道与重定向
    一.重定向标准输入:0标准正确输出:1标准错误输出:2&表示将正确的和错误的混合输出二.输出重定向> ----覆盖>> ----追加正确输出:1>1>>等价于>>>错误输出:2>2>>;  命令分割符&&  上一条命令执行失败,不会进行下一条命令||    上一条命令执行......