【Redis】Redis 的学习教程(五)之 Redis 事务、持久化、集群

news2024/12/25 22:26:31

1. 事务

1.1 事务的概述

Redis 事务通过 MULTIEXECDISCARDWATCH 几个命令来实现

  • MULTI:开启事务
  • EXEC:提交事务
  • DISCARD:放弃事务
  • WATCH:为 Redis 事务提供 check-and-set (CAS)行为

Redis 事务可以一次执行多条命令,Redis 事务有如下特点:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行

事务操作如下:

在这里插入图片描述

1.2 事务发生错误

Reids 事务发生错误分为两种情况:

  • 事务提交前发生错误:在发送命令过程中发生错误
  • 事务提交后发生错误:在执行命令过程中发生错误

①:事务提交前发生错误

在这里插入图片描述
这里故意将 incr 命令 写错,从结果我们可以看到:这条 incr 命令 没有入队,并且事务执行失败,num1 和 num2 都没有值。

②:事务提交后发生错误

在这里插入图片描述
上面的事务命令中,我给 num1 设置了一个 a,然后执行自增命令,最后获取 num1 的值。

我们发现第二条命令执行发生了错误,但是整个事务依然提交成功了。

从上面现象中可以得出,Redis 事务不支持回滚操作。如果支持的话,整个事务的命令都不应该被执行。

1.3 Redis 为什么不支持事务回滚

以下是这种做法的优点:

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 incr 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 incr , 回滚是没有办法处理这些情况的

1.4 放弃事务

当执行 discard 命令时, 事务会被放弃, 事务队列会被清空, 并且客户端会从事务状态中退出

在这里插入图片描述

1.5 WATCH 命令

WATCH 机制:使用 WATCH 监视一个或多个 key , 跟踪 key 的 value 修改情况,如果有key 的 value 值在事务 EXEC 执行之前被修改了,整个事务被取消。EXEC 返回提示信息,表示事务已经失败

在这里插入图片描述
WATCH 监视了一个带过期时间的键,那么即使这个键过期了,事务仍然可以正常执行

1.6 取消 WATCH

  • WATCH 命令可以被调用多次。对键的监视从 WATCH 执行之后开始生效,直到调用 EXEC 为止。不管事务是否成功执行,对所有键的监视都会被取消
  • 当客户端断开连接时,该客户端对键的监视也会被取消
  • UNWATCH 命令可以手动取消对所有键的监视

1.7 Redis 脚本和事务

从定义上来说, Redis 中的脚本本身就是一种事务, 所以任何在事务里可以完成的事, 在脚本里面也能完成。 并且一般来说, 使用脚本要来得更简单,并且速度更快

2. 持久化

2.1 为什么需要持久化

我们知道 Redis 是内存数据库,主打高性能,速度快。相比 Redis 而言,MySQL 的数据则是保存再硬盘中速度慢,但是稳定性好。

你想想 Redis 数据保存在内存中,一旦服务器宕机了,数据岂不是全部都没了,这将会出现很大问题。所以 Redis 为了弥补这一缺陷,提供数据持久化机制,即使服务器宕机,依然可以保证数据不丢失

2.2 持久化简介

Redis 提供了两种持久化机制 RDB 和 AOF,适用于不同场景:

  • RDB 持久化方式:能够在指定的时间间隔能对你的数据进行快照存储
  • AOF 持久化方式:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。AOF 命令以 Redis 协议追加保存每次写的操作到文件末尾。Redis还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大

2.2.1 RDB

RDB 持久化是通过在指定时间间隔对数据进行快照。比如:在 8 点钟对数据进行持久化,那么 Redis 会 fork 一个子进程将 8 点那一刻内存中的数据持久化到磁盘上。

触发 RDB 持久化有以下几种方法:

  1. 执行 save 命令:执行 save 命令进行持久会阻塞 Redis,备份期间 Redis 无法对外提供服务,一般不建议使用,使用场景为 Redis 服务器需要停机维护的情况下
  2. 执行 bgsave 命令:bgsave 命令不会阻塞 Redis 主进程,持久化期间 Redis 依然可以正常对外提供服务
  3. 通过配置文件中配置的 save 规则来触发:
    在这里插入图片描述

save 900 1:900s 内有 1 个 key 发生变化,则触发 RDB 快照

save 300 10:300s 内有 10 个 key 发生变化,则触发 RDB 快照

save 60 10000:60s 内有 10000 个 key 发生变化(新增、修改、删除),则触发 RDB 快照

save “”:该配置表示关闭 RDB 持久化

2.2.1.1 RDB 持久化原理

Redis 进行 RDB 时,会 fork 一个子进程来进行数据持久化,这样不妨碍 Redis 继续对外提供服务,提高效率

2.2.1.2 RDB 优缺点

优点:

  • RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份。比如:你可以在每个小时报保存一下过去 24 小时内的数据。同时,每天保存过去30天的数据。这样,即使出了问题你也可以根据需求恢复到不同版本的数据集
  • RDB 在保存 RDB 文件时父进程唯一需要做的就是 fork 出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他 IO 操作,所以 RDB 持久化方式可以最大化 Redis 的性能
  • 与 AOF 相比,在恢复大的数据集的时候,RDB方式会更快一些

缺点:

  • 如果备份间隔时间较长,RDB 会丢失较多的数据。比如 8 点备份一次,8 点半服务器宕机,那么这半小时内的数据就会丢失了

2.2.2 AOF

AOF 持久化是通过日志的方式,记录每次 Redis 的写操作。当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF 命令以 Redis 协议追加保存每次写的操作到文件末尾。

Redis 还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大.

AOF 持久化配置:

# 是否开启 aof no:关闭;yes: 开启
appendonly no

# aof 文件名
appendfilename "appendonly.aof"

# aof 同步策略
# appendfsync always  # 每个命令都写入磁盘,性能较差
appendfsync everysec  # 每秒写一次磁盘,Redis 默认配置
# appendfsync no      # 由操作系统执行,默认Linux配置最多丢失30秒

# aof 重写期间是否同步
no-appendfsync-on-rewrite no

# 重写触发策略
auto-aof-rewrite-percentage 100 # 触发重写百分比 (指定百分比为0,将禁用aof自动重写功能)
auto-aof-rewrite-min-size 64mb # 触发自动重写的最低文件体积(小于64mb不自动重写)

# 加载aof时如果有错如何处理
# 如果该配置启用,在加载时发现aof尾部不正确是,会向客户端写入一个log,但是会继续执行,如果设置为 no ,发现错误就会停止,必须修复后才能重新加载。
aof-load-truncated yes

# aof 中是否使用 rdb
# 开启该选项,触发AOF重写将不再是根据当前内容生成写命令。而是先生成RDB文件写到开头,再将RDB生成期间的发生的增量写命令附加到文件末尾。
aof-use-rdb-preamble yes

2.2.2.1 AOF 文件写入

aof 文件是命令追加的方式,先将命令写入缓冲区,时间到了再写如磁盘中:

appendfsync always    # 每个命令都写入磁盘,性能较差
appendfsync everysec  # 每秒写一次磁盘,Redis 默认配置
appendfsync no        # 由操作系统执行,默认Linux配置最多丢失30秒

上面配置就是何时写入磁盘中

2.2.2.2 AOF 重写

aof 文件虽然丢失的数据少,但是随着时间的增加,aof 文件体积越来越大,占用磁盘空间越来越大,恢复时间长。所以 redis 会对 aof 文件进行重写,以减少 aof 文件体积:

-- 重写前的 aof
set k1 20
set k2 40
set k1 35
set k3 34
set k2 19

-- 这里 k1 最终的值为 35,k2 最终值为 19,所以不需要写入两个命令
-- 重写后
set k1 35
set k3 34
set k2 19

2.2.2.3 混合持久化

从 Redis 4.0 版本开始,引入了混合持久化机制,纯AOF方式、RDB+AOF方式,这一策略由配置参数aof-use-rdb-preamble(使用RDB作为AOF文件的前半段)控制,默认关闭(no),设置为yes可开启

  • no:按照AOF格式写入命令,与4.0前版本无差别;
  • yes:先按照RDB格式写入数据状态,然后把重写期间AOF缓冲区的内容以AOF格式写入,文件前半部分为RDB格式,后半部分为AOF格式。

混合持久化优点如下:

  • 大大减少了 aof 文件体积
  • 加快了 aof 文件恢复速度,前面是 rdb ,恢复速度快

2.2.2.4 AOF 数据恢复

AOF 数据恢复有两种:

  • 纯 AOF:恢复时,取出 AOF 中命令,一条条执行恢复
  • RDB + AOF:先执行 RDB 加载流程,执行完毕后,再取出余下命令,开始一条条执行

2.2.2.5 AOF 优缺点

优点

  • AOF 实时性更好,丢失数据更少
  • AOF 已经支持混合持久化,文件大小可以有效控制,并提高了数据加载时的效率

缺点

  • 对于相同的数据集合,AOF 文件通常会比 RDB 文件大
  • 在特定的 fsync 策略下,AOF 会比 RDB 略慢
  • AOF 恢复速度比 RDB 慢

3. Redis 集群

在生产环境中,我们使用 Redis 通常采用集群模式,因为单机版 Redis 稳定性可靠性较低,而且存储空间有限。

Redis 支持三种集群模式:

  • 主从复制
  • 哨兵模式
  • Cluster 模式

3.1 主从复制

主从复制模式,有一个主,多个从,从而实现读写分离。主机负责写请求,从机负责读请求,减轻主机压力

在这里插入图片描述

3.1.1 主从复制原理

主从复制过程如下:

在这里插入图片描述

  1. 从数据库启动成功后,连接主数据库,发送 SYNC 命令;
  2. 主数据库接收到 SYNC 命令后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;
  3. 主数据库 BGSAVE 执行完后,向所有从数据库发送快照文件,并在发送期间继续记录被执行的写命令;
  4. 从数据库收到快照文件后丢弃所有旧数据,载入收到的快照;
  5. 主数据库快照发送完毕后开始向从数据库发送缓冲区中的写命令;
  6. 从数据库完成对快照的载入,开始接收命令请求,并执行来自主数据库缓冲区的写命令;(从数据库初始化完成)
  7. 主数据库每执行一个写命令就会向从数据库发送相同的写命令,从数据库接收并执行收到的写命令(从数据库初始化完成后的操作)
  8. 出现断开重连后,2.8 之后的版本会将断线期间的命令传给重数据库,增量复制。
  9. 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。Redis 的策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

3.1.2 主从复制优缺点

优点:

  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
  • Slave 同样可以接受其它 Slaves 的连接和同步请求,这样可以有效的分载 Master 的同步压力
  • Master Server 是以非阻塞的方式为 Slaves 提供服务。所以在 Master-Slave 同步期间,客户端仍然可以提交查询或修改请求

缺点

  • 主从不具备容错和恢复能力,一旦主机挂了,那么整个集群处理可读状态,无法处理写请求,会丢失数据
  • 主机宕机后无法自动恢复,只能人工手动恢复
  • 集群存储容量有限,容量上线就是主库的内存的大小,无法存储更多内容

3.2 哨兵集群

哨兵的作用是起到监控作用。一旦 Redis 集群出现问题了,哨兵会立即做出相应动作,应对异常情况。

哨兵模式是基于主从复制模式上搭建的,因为主从复制模式情况下主服务器宕机,会导致整个集群不可用,需要人工干预。所以,哨兵模式在主从复制模式下引入了哨兵来监控整个集群,哨兵模式架构图如下:

在这里插入图片描述

哨兵功能:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。

  • 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。

  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。

  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

3.2.1 下线判断

Redis 下线分为主观下线和客观下线两种

  • 主观下线:单台哨兵任务主库处于不可用状态
  • 客观下线:整个哨兵集群半数以上的哨兵都认为主库处于可不用状态

哨兵集群中任意一台服务器判断主库不可用时,此时会发送命令给哨兵集群中的其他服务器确认,其他服务器收到命令后会确认主库的状态,如果不可用,返回 YES,可用则返回 NO,当有半数的服务器都返回 YES,说明主库真的不可用,此时需要重新选举:

在这里插入图片描述

3.2.2 主库选举

当哨兵集群判定主库下线了,此时需要重新选举出一个新的主库对外提供服务。那么该由哪个哨兵来完成这个新库选举和切换的动作呢?

注意:这里不能让每个哨兵都去选举,可能会出现每个哨兵选举出的新主库都不同,这样就没法判定,所以需要派出一个代表 ------ 哨兵代表选择

3.2.3 哨兵代表选择

哨兵的选举机制其实很简单,就是一个Raft选举算法: 选举的票数大于等于num(sentinels)/2+1时,将成为领导者,如果没有超过,继续选举

任何一个想成为 Leader 的哨兵,要满足两个条件:

  1. 第一,拿到半数以上的赞成票;
  2. 第二,拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。

以 3 个哨兵为例,假设此时的 quorum 设置为 2,那么,任何一个想成为 Leader 的哨兵只要拿到 2 张赞成票,就可以了。

3.2.4 新库选择

上面已经选举出了哨兵代表,此时代表需要完成新主库的选择,新库的选择需要满足以下几个标准:

  1. 新库需要处于健康状态,也就是和哨兵之间保持正常的网络连接
  2. 选择salve-priority从节点优先级最高(redis.conf)的
  3. 选择复制偏移量最大,只复制最完整的从节点

3.2.5 故障转移

故障转移要实现新老主库之间的切换

故障转移流程如下:

在这里插入图片描述

3.2.6 哨兵模式优缺点

优点

  • 实现了集群的监控,故障转移,实现了高可用
  • 拥有主从复制模式的所有优点

缺点

  • 集群存储容量有限,容量上线就是主库的内存的大小,无法存储更多内容

3.3 Cluser 集群

Redis 的哨兵模式实现了高可用了,但是每台 Redis 服务器上存储的都是相同的数据,浪费内存,而且很难实现容量上的扩展。所以在 redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容

3.3.1 Redis 集群的数据分片

Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽。

举个例子:比如当前集群有3个节点,那么:

  • 节点 A 包含 0 到 5500号哈希槽.
  • 节点 B 包含5501 到 11000 号哈希槽.
  • 节点 C 包含11001 到 16384号哈希槽.

这种结构很容易添加或者删除节点.。比如如果我想新添加个节点 D,我需要从节点 A, B, C中得部分槽到 D 上。如果我想移除节点 A,需要将 A 中的槽移到 B 和 C 节点上,然后将没有任何槽的 A 节点从集群中移除即可。

由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创业新机会?全球将有36%的员工永久远程办公!

刚刚过去的2020年是极其不平凡的一年,这一年面对的困难,严重程度超出了所有人的预料,很多公司都遇到的困难就是无法按时复工,这对于创业公司而言,无异于生死大考。 为了活下去,很多公司都开启了远程办公的…

欧科云链研究院探析Facebook稳定币发行经历会不会在PayPal重演

引言 作者最近的报告-探析PayPal发行稳定币是否会重蹈Facebook覆辙-近期被英国的金融时报(中文版)刊登。由于该报告在欧科云链研究院内部反响较好,下面就带大家简单的剖析这篇报告的主要内容。 *这篇文章主要由对比分析(已删减&a…

【高阶数据结构】AVL树 {概念及实现;节点的定义;插入并调整平衡因子;旋转操作:左单旋,右单旋,左右双旋,右左双旋;AVL树的验证及性能分析}

AVL树 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明…

定位与轨迹-百度鹰眼轨迹开放平台-学习笔记

1. 百度鹰眼轨迹的主要功能接口 百度的鹰眼轨迹平台,根据使用场景不同,提供了web端、安卓端等各种类型的API与SDK,本文章以web端API为例,介绍鹰眼轨迹的使用。 2. API使用前的准备 使用鹰眼轨迹API,需要两把钥匙&…

真香!Jenkins 主从模式解决问题So Easy~

01、Jenkins 能干什么 Jenkins 是一个开源软件项目,是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。 中文官网:https://jenkins.io/zh/ …

OpenCV(十一):图像仿射变换

目录 1.图像仿射变换介绍 仿射变换: 仿射变换矩阵: 仿射变换公式: 2.仿射变换函数 仿射变换函数:warpAffine() 图像旋转:getRotationMatrix2D() 计算仿射变换矩阵:getAffineTransform() 3.demo 1.…

并发(CAS ABA问题)07

CAS public class Hsss {public static void main(String[] args) {AtomicInteger atomicIntegernew AtomicInteger(201);//CAS compareAndSet 比较并交换//如果我期望的值达到了,那么就更新,否则,就不更新atomicInteger.compareAndSet(201,2…

Java版电子招投标管理系统源码-电子招投标认证服务平台-权威认证

项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…

TL6478(TI TMS320C6748 DPS)EVM开发板技术讲座 第一讲:串口终端ZOC软件的安装

串口终端ZOC软件的安装 1. 软件获得2. 安装软件3. 软件设置1. 软件获得 zoc602串口工具下载地址: https://download.csdn.net/download/Windgs_YF/88279060 2. 安装软件 1、将zoc602.zip文件解压,双击解压目录中的zoc602.exe安装文件,弹出如下安装界面: 2、点击 Next,…

Python+turtle实现一个图片播放器

我们可以利用Pythonturtle实现一个简易的图片播放器,我们先看一下效果图 完整版代码: [D:\照片\\ i for i in os.listdir(D:\照片)]:os.listdir(‘这里写上你图片的保存路径’) Screen().bgpic(pic_list[num]),加载图片至turtle的…

手敲视觉slam14讲 ch7 / pose_estimation_3d2d.cpp (1)

首先理清我们需要实现什么功能,怎么实现,提供一份整体逻辑:包括主函数和功能函数 主函数逻辑: 1. 读图,两张rgb(cv::imread) 2. 找到两张rgb图中的特征点匹配对 2.1定义所需要的参数:keypoints…

BOM对MES管理系统的影响与作用

在建设MES管理系统中,BOM(物料清单)具有至关重要的作用。它提供了产品的组成部分和结构信息,支持生产过程的监控、协调和管理。本文将详细探讨BOM在MES管理系统中的影响和作用。 一、生产过程指导 BOM为MES系统提供了产品的组成部…

MP中的字段还可以利用函数来查询拼接sql

//根据value查询GetMapping("getTest")public List<HashMap> getTest() {QueryWrapper<TTest> queryWrapper new QueryWrapper<>();queryWrapper.eq("substr(name,1,2)","99999");List<TTest> list1 testService.list…

电脑使用快捷键的各种方法

电脑使用快捷键可以帮助我们提高日常操作效率&#xff0c;例如&#xff1a; CTRLC&#xff1a;复制选中内容。 CTRLV&#xff1a;粘贴复制的内容。 CTRLX&#xff1a;剪切选中内容。 CTRLA&#xff1a;全选当前页面内容。 SHIFTDELETE&#xff1a;永久删除选中内容。 CTRL…

银河麒麟V10安装libmcrypt

本次安装是在华为云上执行。cpu是鲲鹏&#xff0c;操作系统是银河麒麟V10. 先下载安装包&#xff1a; wget http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz 解包&#xff0c;进入目录中。 执行如下命令&#xff1a; ./configure make make install 执…

GarageSale for Mac:Mac上最好的eBay在线拍卖客户端

GarageSale for Mac是一款适用于Mac操作系统的应用&#xff0c;它可以帮助用户在苹果电脑上创建、管理和组织自己的个人销售活动。如果你希望在Mac上进行有效的推广&#xff0c;以下是一些可能有帮助的建议&#xff1a; 确定目标受众&#xff1a;在推广之前&#xff0c;了解你…

Leetcode415 字符串相加

思路&#xff1a; 从末尾开始相加&#xff0c;进位可以最后统一处理&#xff0c;因为再怎么进也是最多只进一位 class Solution:def addStrings(self, num1: str, num2: str) -> str:# 确保1里是更长的字符串if len(num1) < len(num2):num1_list list(num2)num2_list …

持续加码,科士达重仓储能!

储能的热度&#xff0c;如温度计一样真实展现在各种数据榜单上&#xff1a;新注册企业的数量&#xff0c;转型跨界的企业&#xff0c;尤其IPO募资扩产规模&#xff0c;更是成为了储能企业竞赛的新标准。 日前&#xff0c;科士达一则新的定向募资预案&#xff0c;吸引了业内广泛…

腾讯音乐如何基于大模型 + OLAP 构建智能数据服务平台

本文导读&#xff1a; 当前&#xff0c;大语言模型的应用正在全球范围内引发新一轮的技术革命与商业浪潮。腾讯音乐作为中国领先在线音乐娱乐平台&#xff0c;利用庞大用户群与多元场景的优势&#xff0c;持续探索大模型赛道的多元应用。本文将详细介绍腾讯音乐如何基于 Apach…

【算法篇】动态规划(一)

文章目录 拆分字符串三角形最小路径和不同路径最小路径和背包问题 class Solution { public:int fib(int n) {// if(n0)// {// return 0;// }// if(n1||n2)// {// return 1;// }// return fib(n-1)fib(n-2);//上面的方法会发现时间复杂度太大&#xff0c;超出时间限制O…