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

redis持久化机制 事务详解

目录

前言:

持久化机制

RDB(Redis DataBase)

手动触发 

save

bgsave

自动触发

RDB特点

AOF(append only file)

缓冲区刷新策略

重写机制

aof重写流程

混合持久化

事务

事务操作命令

WATCH

WATCH实现原理


前言:

    redis为了保证高可用引入了持久化机制,目的就是为了redis服务器重启时可以恢复原有的数据。redis提供了RDB,AOF和混合持久化三种机制,开发者可在不同的业务场景具体选择使用哪一个持久化机制。

持久化机制

RDB(Redis DataBase)

    定期备份,每隔一段时间将内存中的数据刷新到硬盘中,生成一个快照rdb文件(用来恢复数据)。

手动触发 

save

    执行save的时候,redis会全力以赴的进行“快照生成”的操作,此时就会阻塞其他客户端的命令,因为redis是单线程模型。(一般不建议)

bgsave

1)不会影响redis处理其他客户端的命令。redis在后台采用多进程方式生成rdb文件。

2)redis将内存中的数据以压缩的方式保存到二进制文件中(镜像文件,rdb文件)。

3)redis服务器重启时,需要加载这个快照文件,如果快照文件格式不对,redis服务可能会启动失败。同时redis提供了rdb文件检查工具,可以手动执行进行rdb文件校验。

执行流程

    当生成rdb镜像文件时,首先会保存在一个临时文件中,当快照生成完毕后。然后删除原来的rdb文件,将临时文件替换为新的rdb文件。(始终rdb文件只有一个)

    多进程处理bgsave。当触发bgsave命令时,redis首先会判断是否有其他进程在执行rdb文件操作,如果有其他正在运行的进程则直接返回。

    redis会fork一个和当前进程一模一样的子进程(文件描述符表,虚拟内存地址等等进程信息都是一致的)。并且也是共用同一块内存空间(防止内存数据量太大fork时就比较消耗资源),只有当父进程修改了内存中的数据时,此时子进程就会复制内存中的数据,不在和父进程共享同一块内存了。当子进程处理完rdb文件时,使用信号通知父进程,父进程就可以销毁这个子进程了。

redis生成快照操作触发时机:

1)配置文件中M时间内修改N次,自动触发。

2)通过shutdown命令正常停止redis服务。

3)redis进行主从复制的时候,主节点会自动生成rdb快照,然后把rdb快照传输给从节点。

自动触发

    在redis配置文件中,设置每隔多长时间/数据修改多少次就触发。

RDB特点

1)RDB是一个紧凑压缩的二进制文件,代表redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。

2)redis加载RDB文件恢复数据远远快于AOF的方式。(主要由于RDB是二进制文件)

3)RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要fork子进程,属于重量级操作,频繁执行成本过高。

4)RDB用特定的二进制文件保存,redis是有多个版本的,存在兼容性问题。

注意:

    rdb持久化机制不能做到实时持久化,每次持久化操作之间都会存在时间间隔。那么在时间间隔内,如果redis服务器宕机了,这段间隔时间内数据还没有生成rdb文件,那么服务器重启就会丢失数据。

AOF(append only file)

    AOF是一个文本文件,每次进行redis操作,都会被追加到文件末尾(直接追加操作redis命令)

注意:

    redis首先将内存中的数据写入内存中的缓冲区,积累一波后,再统一写入到硬盘中。(大大降低了写硬盘的次数)

    AOF每次将新的操作追加到文件末尾,属于顺序写入,效率相对较高。

缓冲区刷新策略

可配置值                                            说明
always命令写入aof_buf 后调用fsync同步,完成后返回
everysec命令写入aof_buf 后只执行write操作,不进行fsync,每秒由同步线程进行fsync
no命令写入aof_buf 后只执行write操作,由操作系统控制fsync频率

注意:

    上述缓冲区刷新策略由快到慢,那么数据可靠性由高到低,性能由低到高。配置文件中都是可修改的。

重写机制

    aof文件中存在一些冗余的记录(一些命令的中间状态也都保存了),redis重写机制针对aof文件进行整理,达到瘦身的效果。

    aof文件中数据只关注内存中最终状态,因此只需要将内存中的数据状态写入新aof文件,替换掉原来的就可以。

触发时机:

    手动触发:bgrewriteaof命令。

    自动触发:配置文件中进行配置(触发时aof最小文件大小,aof相比于上次文件大小增加的比例)

aof重写流程

    父进程会fork一个子进程,子进程将此刻内存数据按照aof格式写入到新aof文件。同时父进程继续处理命令,同时也写入到aof_rewrite_buf和旧aof文件中。

    当子进程将新aof文件写入完毕,使用信号通知父进程,然后将父进程写入的aof_rewrite_buf合并到新aof文件,然后替换掉旧aof文件。

问:为什么父进程需要写旧aof文件,不是最后要替换掉吗?

    如果子进程写新aof文件,突然进程挂了,那么aof文件就是不完整的。如果没有旧aof文件,数据就丢失了。

 

注意:

    重写只关注内存中的最终状态,不关注aof文件中原来有啥。

    如果,在执行bgrewriteaof的时候,已经在执行aof重写了,此时不会再次执行aof重写,直接返回了。

    如果,在执行bgrewriteaof的时候,redis正在生成rdb快照,此时redis的aof重写就会等待,等待rdb文件生成完毕,再执行aof重写。

混合持久化

    结合了aof和rdb机制的特点。

    按照aof的方式将每一步操作都记录到文件中。在触发aof重写机制后,就会把当前内存的状态按照rdb的二进制格式写入到文件中,后续再操作仍然是按照aof文本追加的方式写入文件。

注意

    当redis上同时存在aof和rdb文件时,以aof为主,rdb就被忽略了。

事务

    把多个操作打包到一起,要么全都执行,要么全都不执行。如果执行若干条命令,失败了,那就失败了,没有任何处理。(由于和mysql相比这里没有回滚操作,那么认为redis事务没有原子性)。

    不具备一致性:redis没有约束,也没有回滚机制。事务执行过程中如果某个修改操作失败,就会导致不一致的情况。

    不具备持久性:redis是内存数据库,数据存储在内存中的。虽然有持久化机制,但也是为了redis恢复数据,和这里没有关系。

    不涉及隔离性:redis是单线程处理请求命令,所有请求都是串行执行的,不涉及并发。

redis事务主要意义:

    就是为了打包命令,防止其他客户端命令插队。

注意:

    redis实现事务引入了队列(每个客户端都有一个)。开启事务的时候,客户端请求命令就会进入到这个队列,而不会立即执行,当提交事务的时候,redis才会打包一起按照顺序执行这些命令。主线程会把这些命令处理完,再处理其他客户端请求。

    redis如果按照集群模式部署,不支持事务。

事务操作命令

开启事务:MULTI

提交事务:EXEC

放弃当前事务:DISCARD

注意:

    当开启事务,并且客户端发送若干条命令后,如果redis服务重启,那么就会放弃当前的事务(DISCARD)。

WATCH

    监控某个key,是否在事务执行之前发生了改变。

    如果在事务执行时发现了某个key被其他客户端修改了,那么事务提交时就不会真正执行这条修改命令。

WATCH实现原理

    基于版本号机制实现类似“乐观锁”。预测锁竞争不是很激烈,即其他客户端在事务提交之前修改相同数据概率不是很大。

    当使用watch监控某个key时,会给这个key分配一个版本号,如果有其他客户端修改了这个key,则版本号会变大。当exec提交事务的时候就会判断,这个key版本号是否和之前watch记录的版本号一致。

    如果一致则说明key没有被修改过,就会正常执行事务中的命令。如果不一致则说明key被其他客户端修改过,就会直接丢弃事务中的操作,exec返回nil。

相关文章:

redis持久化机制 事务详解

目录 前言: 持久化机制 RDB(Redis DataBase) 手动触发 save bgsave 自动触发 RDB特点 AOF(append only file) 缓冲区刷新策略 重写机制 aof重写流程 混合持久化 事务 事务操作命令 WATCH WATCH实现原…...

java八股文面试[多线程]——有几种创建线程的方式

this逃逸问题:构造器中启动线程。 面试题: 用Thread和Runable创建线程的差别 一、Runnable和Thread的区别 继承性:Thread是一个类,因此如果继承Thread类,子类就不能再继承其他的类了,而实现Runnable接口…...

Desnet模型详解

模型介绍 DenseNet的主要思想是密集连接,它在卷积神经网络(CNN)中引入了密集块(Dense Block),在这些块中,每个层都与前面所有层直接连接。这种设计可以让信息更快速地传播,有助于解…...

clickhouse-压测

一、数据集准备 数据集可以使用官网数据集,也可以用ssb-dbgen来准备 1.准备数据 这里最后生成表的数据行数为60亿行,数据量为300G左右 git clone https://github.com/vadimtk/ssb-dbgen.git cd ssb-dbgen/ make1.1 生成数据 # -s 指生成多少G的数据…...

AI夏令营第三期用户新增挑战赛学习笔记

1、数据可视化 1.数据探索和理解:数据可视化可以帮助我们更好地理解数据集的特征、分布和关系。通过可视化数据,我们可以发现数据中的模式、异常值、缺失值等信息,从而更好地了解数据的特点和结构。2.特征工程:数据可视化可以帮助…...

pdf转ppt软件哪个好用?推荐一个好用的pdf转ppt软件

在日常工作和学习中,我们经常会遇到需要将PDF文件转换为PPT格式的情况。PDF格式的文件通常用于展示和保留文档的原始格式,而PPT格式则更适合用于演示和展示。为了满足这一需求,许多软件提供了PDF转PPT的功能,使我们能够方便地将PD…...

Linux 内核函数kallsyms_lookup_name

文章目录 一、API使用二、源码解析2.1 kallsyms_lookup_name2.2 kallsyms_expand_symbol2.3 kallsyms_sym_address2.3.1 x86_642.3.2 arm642.3.3 CONFIG_KALLSYMS_ABSOLUTE_PERCPU 参考资料 一、API使用 kallsyms_lookup_name 是一个内核函数,用于通过符号名称查找…...

强化学习在游戏AI中的应用与挑战

文章目录 1. 强化学习简介2. 强化学习在游戏AI中的应用2.1 游戏智能体训练2.2 游戏AI决策2.3 游戏测试和优化 3. 强化学习在游戏AI中的挑战3.1 探索与利用的平衡3.2 多样性的应对 4. 解决方法与展望4.1 深度强化学习4.2 奖励设计和函数逼近 5. 总结 🎉欢迎来到AIGC人…...

6 Python的异常处理

概述 在上一节,我们介绍了Python的面向对象编程,包括:类的定义、类的使用、类变量、实例变量、实例方法、类方法、静态方法、类的运算符重载、继承等内容。在这一节中,我们将介绍Python的异常处理。异常是指程序在运行过程中出现的…...

【跨语言通讯】

传统的跨语言通讯方案: 基于SOAP消息格式的WebService 基于JSON消息格式的RESTful 服务 主要弊端: XML体积太大,解析性能极差 JSON体积相对较小,解析相对较快,但表达能力较弱 如今比较流行的跨语言通讯方案&…...

Android 基础知识

一、Activity 1、onSaveInstanceState(),onRestoreInstanceState的调用时机 onSaveInstanceState 调用时机 从最近应用中选择运行其他程序时 但用户按下Home键时 屏幕方向切换时 按下电源案件时 从当前activity启动一个新的activity时 onRestorInstanceState调用时机 只…...

Linux常用命令_帮助命令、用户管理命令、压缩解压命令

文章目录 1. 帮助命令1.1 帮助命令:man1.2 帮助命令:help1.3 其他帮助命令 2. 用户管理命令2.1 用户管理命令: useradd2.2 用户管理命令: passwd2.3 用户管理命令: who2.4 用户管理命令: w 3. 压缩解压命令3.1 压缩解压命令: gzip3.2 压缩解压命令: gunzip3.3 压缩解压命令: ta…...

解决 KylinOS “Could not get lock /var/lib/dpkg/lock”错误

最近,我遇到了 “Could not get lock /var/lib/dpkg/lock”的错误,我既不能安装任何软件包,也不能更新系统。此错误也与“Could not get lock /var/lib/apt/lists/lock”错误密切相关。以下是 Ubuntu 20.04 上的一些样本输出。 Reading package lists… Done E: Could not…...

PHP pdf 自动填写表单

一、下载github上的项目,地址 二、下载pdftk 地址 // 转化PDF模板 pdftk modele.pdf output modele2.pdf# 填充pdf文件中的表单 require(fpdm.php); $fields array(name > My name,address > My address,city > My city,phone > My phone nu…...

Win2016Server绑定多网卡实现负载均衡

一、服务器端: 1、输入ncpa.cpl打开网络连接,对要绑定的网卡勾掉IPV4,IPV4地址选择自动 2、输入servermanager.exe,打开服务器管理器 3、在 [本地服务器] 中,点后边的 “已禁用” ,在 [适配器和接口] 小窗口…...

微软宣布在 Excel 中使用 Python:结合了 Python 的强大功能和 Excel 的灵活性。

文章目录 Excel 中的 Python 有何独特之处?1. Excel 中的 Python 是为分析师构建的。高级可视化机器学习、预测分析和预测数据清理 2. Excel 中的 Python 通过 Anaconda 展示了最好的 Python 分析功能。3. Excel 中的 Python 在 Microsoft 云上安全运行,…...

学习心得03:OpenCV

数学真是不可思议,不管什么东西,都能用数学来处理。OpenCV以前也接触过,这次是系统学习一下。 颜色模型 RGB,YUV,HSV,Lab,GRAY 颜色转换cvtColor()/convertTo(),通道分离split()&…...

ubuntu学习(五)----读取文件以及光标的移动

1、读取文件函数原型介绍 ssize_t read(int fd,void*buf,size_t count) 参数说明: fd: 是文件描述符 buf:为读出数据的缓冲区; count: 为每次读取的字节数(是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文…...

Python 数据分析——matplotlib 快速绘图

matplotlib采用面向对象的技术来实现,因此组成图表的各个元素都是对象,在编写较大的应用程序时通过面向对象的方式使用matplotlib将更加有效。但是使用这种面向对象的调用接口进行绘图比较烦琐,因此matplotlib还提供了快速绘图的pyplot模块。…...

uniapp小程序位置信息配置

uniapp 小程序获取当前位置信息报错 报错信息: getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json 需要在manifest.json配置文件中进行配置:...

《基于 Vue 组件库 的 Webpack5 配置》1.模式 Mode 和 vue-loader

一定要配置 模式 Mode,这里有个小知识点,环境变量 process.env.NODE_ENV module.exports {mode: production,// process.env.NODE_ENV 或 development, }一定要配置 vue-loader Vue Loader v15 现在需要配合一个 webpack 插件才能正确使用; …...

01.sqlite3学习——数据库概述

目录 重点概述总结 数据库标准介绍 什么是数据库? 数据库是如何存储数据的? 数据库是如何管理数据的? 数据库系统结构 常见关系型数据库管理系统 关系型数据库相关知识点 数据库与文件存储数据对比 重点概述总结 数据库可以理解为操…...

视频集中存储/云存储平台EasyCVR国标GB28181协议接入的报文交互数据包分析

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理…...

容器技术,1. Docker,2. Kubernetes(K8s):

目录 容器技术 1. Docker: 2. Kubernetes(K8s): Docker和Kubernetes 容器的主要应用场景有哪些? 容器技术 有效的将单个操作系统的资源划分到孤立的组中,以便更好的在孤立的组之间平衡有冲突的资源使…...

Jtti :sql server怎么备份数据库?

在 SQL Server 中备份数据库是一项重要的操作,它可以确保你的数据在意外情况下得以恢复。以下是在 SQL Server 中备份数据库的基本步骤: 使用 SQL Server Management Studio (SSMS) 进行备份: 打开 SQL Server Management Studio(SSMS)并连接…...

Stable Diffusion 系列教程 | 打破模型壁垒

目录 1.模型基本分类 1.1 CheckPoint 大模型/底模型/主模型 1.2 VAE美化模型/变分自编码器 1.3 HyperNetwork 超网络 1.4 embeddings(/Textual Inversion) 嵌入式向量 1.5 loRa 低秩适应模型 2. 下载途径和渠道 2.1 C站 2.1.1 如何筛选到自己需…...

Cypress 做 e2e 测试,如何在获得某个 checkbox 后先判断它是否被 check 然后再更改它的状态?

比如如果这个 checkbox 已经被 check 了,就不做操作,否则将它 check。 我们假设这个 checkbox 的 data-testid 属性是 VendorCodeCheckbox-0-test-id。Cypress 的代码如下: cy.getByTestId(VendorCodeCheckbox-0-test-id).shadow().find([r…...

基于PIC单片机温度-脉搏-DS18B20温度-液晶12864显示(proteus仿真+源程序)

一、系统方案 1、上电初始化液晶第一行显示脉搏,第二行显示温度,第三行显示模式,第四行显示强度;按下K1按键可以选择模式,催眼模式或治疗模式。 2、治疗模块下,可以通过K2、K3修改强度。 二、硬件设计 原理…...

【C++进阶(一)】STL大法以及string的使用

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C   🔝🔝 STL标准库 1. 前言2. STL库的版本以及缺陷3. ST…...

leetcode做题笔记99. 恢复二叉搜索树

给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。 思路一:模拟题意 int midOrder(struct TreeNode **pre, struct TreeNode **err1, struct TreeNode **err2, struct TreeNo…...

24 | 紧跟时代步伐:微服务模式下API测试要怎么做?

微服务架构(Microservice Architecture) 微服务是一种架构风格。在微服务架构下,一个大型复杂软件系统不再由一个单体组成,而是由一系列相互独立的微服务组成。其中,各个微服务运行在自己的进程中,开发和部…...

【论文阅读】POIROT:关联攻击行为与内核审计记录以寻找网络威胁(CCS-2019)

POIROT: Aligning Attack Behavior with Kernel Audit Records for Cyber Threat Hunting CCS-2019 伊利诺伊大学芝加哥分校、密歇根大学迪尔伯恩分校 Milajerdi S M, Eshete B, Gjomemo R, et al. Poirot: Aligning attack behavior with kernel audit records for cyber thre…...

K8S cluster with multi-masters on Azure VM

拓扑参考: 在 Azure VM 实例上部署 KubeSphere 基础模板 需要修改 IP 地址和 VM Image的可以在模板中修改。 {"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion": &q…...

初阶c语言:趣味扫雷游戏

目录 前言 制作菜单 构建游戏选择框架 实现游戏功能 模块化编程:查看前节三子棋的内容 初始化雷区 ​编辑 优化棋盘 随机埋入地雷 点击后的决策 实现此功能代码 game();的安排 前言 《扫雷》是一款大众类的益智小游戏&…...

JVM——内存模型

1.java内存模型 1.1 原子性 1.2 问题分析 这里与局部变量自增不同,局部变量调用iinc是在局部变量表槽位上进行自增。 静态变量是在操作数栈自增。 这里的主内存和工作内存时再JMM里的说法。 因为操作系统是时间片切换的多个线程轮流使用CPU. 1.3解决方法 JMM中…...

java八股文面试[JVM]——元空间

JAVA8为什么要增加元空间 为什么要移除永久代? 知识来源: 【2023年面试】JVM8为什么要增加元空间_哔哩哔哩_bilibili...

科技云报道:云计算下半场,公有云市场生变,私有云风景独好

科技云报道原创。 大数据、云计算、人工智能,组成了恢弘的万亿级科技市场。这三个领域,无论远观近观,都如此性感和魅力,让一代又一代创业者为之杀伐攻略。 然而高手过招往往一瞬之间便已胜负知晓,云计算市场的巨幕甫…...

Oracle 如何给大表添加带有默认值的字段

一、讲故事 你是否遇到过开发人员添加字段,导致数据库锁表问题? 但是令开发疑惑的事,他们添加字段,有的时候很快,有的时候很慢? 为什么呢? 询问得知,**加的慢时候是带上了default默…...

记录Taro大坑2丢失api无法启动

现象 解决方案 看了很多。很多说要改成一致的版本号。其实没什么用。 正确方案 再新建一个模板跑起来对比config的配置,以及package.json发现关闭预编译即可。预编译导致api丢失...

Java-Maven-解决maven deploy时报 401 Reason Phrase Unauthorized 错误

Java-Maven-解决maven deploy时报 401 Reason Phrase Unauthorized 错误 环境 Java JDK 1.8Maven 3.3.9 引言 项目需要打成jar包上传到私服,供其它项目引用。此时需要执行 mvn clean deploy 命令,执行过程中报 401 错误。 解决401错误 报错信息 执…...

【数据结构】 栈(Stack)的应用场景

文章目录 🌏前言🍀改变元素的序列🚩场景一📌解析: 🚩场景二📌解析: 🎍将递归转化为循环🌳[括号匹配](https://leetcode.cn/problems/valid-parentheses/)&…...

人力资源小程序的设计原则与实现方法

随着移动互联网的快速发展,小程序成为了各行各业推广和服务的新利器。对于人力资源行业来说,开发一款定制化的小程序不仅可以提升服务效率,还可以增强品牌形象和用户粘性。那么,如何定制开发人力资源类的小程序呢?下面…...

检查Javascript对象数组中是否存在对象值,如果没有向数组添加新对象

需求: 如果我有以下对象数组: [ { id: 1, username: fred }, { id: 2, username: bill }, { id: 2, username: ted } ]有没有办法循环遍历数组,以检查特定的用户名值是否已经存在,如果它什么都不做,但是如果它没有用…...

UG\NX二次开发 使用录制功能录制操作记录时,如何设置默认的开发语言?

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,C\C,Qt-CSDN博客 简介: NX二次开发使用BlockUI设计对话框时,如何设置默认的代码语言? 效果: 方法: 依次打开“文件”->“实用…...

【业务功能篇83】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-应用层实战

五、ElasticSearch应用 1.ES 的Java API两种方式 Elasticsearch 的API 分为 REST Client API(http请求形式)以及 transportClient API两种。相比来说transportClient API效率更高,transportClient 是通过Elasticsearch内部RPC的形式进行请求…...

VBJSON报错:缺少:语句结束

项目中使用JSON库VBJSON时报错: 编译错误:缺少:语句结束 cJSONScript和cStringBuilder报相同的错误,都在第一行: VERSION 1.0 CLASS 研究了半天没啥结果,之前使用这个库的时候没有什么问题,所以判定是当前…...

Docker安装ES+kibana8.9.1

参考:基于Docker安装Elasticsearch【保姆级教程、内含图解】_docker elasticsearch_Acloasia的博客-CSDN博客 创建网络 docker network create es-net 基于Docker安装Elasticsearch 拉取镜像 docker pull elasticsearch:8.9.1 挂载文件 mkdir -p /usr/local/e…...

12. Oracle中case when详解

格式: case expression when condition_01 then result_01 when condition_02 then result_02 ...... when condition_n then result_n else result_default end 表达式expression符合条件condition_01,则返回…...

【电路设计】220V AC转低压DC电路概述

前言 最近因项目需要,电路板上要加上一个交流220V转低压直流,比如12V或者5V这种。一般来说,比较常见也比较简单的做法是使用一个变压器将220V AC进行降压,比如降到22V AC,但是很遗憾的是,支持220V的变压器一般体积很大,而板子留给电源部分的面积又非常有限,所以不得不研…...

网络地址转换NAT-动态NAT的使用范围和配置-思科EI,华为数通

网络地址转换NAT-动态NAT的使用范围和配置 什么是动态NAT? 使用公有地址池,并以先到先得的原则分配这些地址。当具有私有 IP 地址的主机请求访问 Internet 时,动态 NAT 从地址池中选择一个未被其它主机占用的 IP 地址一对一的转化。当数据会话…...