【Redis7】--3.Redis持久化

Redis持久化

Redis持久化(Redis persistence)是指将数据写入持久化存储,如固态硬盘(SSD)

Redis提供了一系列持久化选项,这些包括:

  • RDB(redis数据库):RDB持久化方式能够在指定的时间间隔对数据进行快照存储
  • AOF(追加文件):AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
  • No persistence(没有持久化):可以完全禁用持久化,这有时在缓存时使用
  • RDB+AOF:可以同时开启两种持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整

1.RDB

在指定的时间间隔,执行数据集的时间点快照

实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。

这个快照文件就称为RDB文件(dump.rdb),其中,RDB就是Redis DataBase的缩写。

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot内存快照,它恢复时再将硬盘快照文件直接读回到内存里

Redis的数据都在内存中,保存备份时它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中

1.1快照

在默认情况下,Redis将数据库快照保存在名字dump.rdb的二进制文件中。可以对Redis进行设置,让它在"N秒内数据集至少有M个改动"这一条被满足时,自动保存一次数据集。也可以通过调用SAVE或BGSAVE,手动让Redis进行数据集保存操作

比如说,以下设置会让Redis在满足"60秒内有至少有1000个键被改动"这一条件时,自动保存一次数据集:save 60 1000

image-20230912224441464

image-20230912224419550

redis6.2以及redis7.0

image-20230912224635180

1.2RDB优缺点

  • RDB的优点

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

    • 如果希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合,虽然可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),但是Redis要完整的保存整个数据集是一个比较繁重的工作,通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,可能会丢失几分钟的数据。
    • RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且CPU性能不是很好的情况下,这种情况可能会持续1秒,AOF也需要fork,但是可以调节重写日志文件的频率来提高数据集的耐久度。

1.3RDB配置

  • 配置dump.rdb文件保存路径

下面配置到了redis安装目录下,当然也可以配置到其他目录下,默认是./

先在redis7.conf配置文件的地方新建一个文件夹,dumpfiles保存于/myredis/dumpfiles

image-20230912230823141

  • 修改快照文件名

快照文件名默认为dump.rdb,可以对其进行修改

这里在名称中添加当前的端口号,设置为dump6379.rdb

image-20230912230941656

在redis中支持通过config get或set进行配置文件的更改

image-20230912231021266

1.4触发RDB快照和恢复

1.4.1自动触发

  • 设置redis.conf文件中的自动触发时间:save

    • 修改为7秒内3次修改:save 7 3 ,每7秒检查key操作数够不够3次,这个指的是7秒内达到3次修改,触发一次快照保存
  • FLUSHDB和FLUSHALL命令

执行flushdb或者flushall命令也会触发RDB快照不过里面是空的,以便下次启动redis服务是读取到的就是空文件。

  • SHUTDOWN命令

执行shutdown命令之前会将当前的数据进行一次快照保存。

总结:
不可以把备份文件dump.rdb和生成redis服务器放在同一台机器,必须分开各自存储,以防止生产机物理损坏后备份文件也挂了

1.4.2手动触发

Redis提供了两个命令来生成RDB文件,分别是save和bgsave

  • SAVE命令

SAVE命令在主程序中执行会阻塞当前进程,直到持久化工作完成,redis才能处理其他命令。工作中禁止使用该命令。

127.0.0.1:6379> set name Alice
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> save		# 立马将数据保存到快照中,如果数据量大会造成阻塞
OK

image-20230912232139067

  • BGSAVE命令

BGSAVE命令会fork一个子进程在后台异步进行持久化工作,持久化期间redis可以执行其他命令。

在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,尽量避免膨胀。

127.0.0.1:6379> set name Cindy
OK
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> BGSAVE
Background saving started		# 在后台执行持久化

image-20230912232227083

LASTSAVE命令可以获取最后一次成功执行快照的时间。得到的是一个时间戳,可以通过date -d @时间戳命令获取对应的时间。

127.0.0.1:6379> LASTSAVE
(integer) 1681223083
127.0.0.1:6379> quit
[root@redis ~]# date -d @1681223083
2023年 04月 11日 星期二 22:24:43 CST

1.4.3修复快照数据

有些情况下快照保存的数据不完整导致无法读取快照数据,可以使用redis-check-rdb命令对rdb文件进行修复。

[root@redis redis-7.0.10]# redis-check-rdb dump.rdb 
[offset 0] Checking RDB file dump.rdb
[offset 27] AUX FIELD redis-ver = '7.0.10'
[offset 41] AUX FIELD redis-bits = '64'
[offset 53] AUX FIELD ctime = '1681233313'
[offset 68] AUX FIELD used-mem = '1104992'
[offset 80] AUX FIELD aof-base = '0'
[offset 82] Selecting DB ID 0
[offset 155] Checksum OK
[offset 155] \o/ RDB looks OK! \o/
[info] 8 keys read
[info] 0 expires
[info] 0 already expired

1.4.4恢复快照数据

redis在启动服务时会读取配置的快照保存路径中的dump.rdb文件,所以只需要将备份的rdb文件放到配置的保存路径中,然后启动redis服务即可还原快照中的数据。

1.5禁用RDB快照

redis-cli config set save "":将save的值设置为空,即禁用了快照功能。

在redis客户端则直接执行config set save ""即可。

最好采用如下的配置禁用

image-20230912232548868

1.6什么情况会触发RDB快照

image-20230912232626433

1.7RDB优化配置项参数

image-20230912232720626

1.7.1 stop-writes-on-bgsave-error

停止写bgSave-错误

image-20230912232749818

默认yes

如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求

1.7.2rdbcompression

RDB压缩

image-20230912232906064

默认yes

对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。
如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能

1.7.3rdbchecksum

image-20230912233020781

默认为yes

在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能

1.7.4rdb-del-sync-files

image-20230912233054934

rdb-del-sync-files:在没有持久性的情况下删除复制中使用的RDB文件启用。默认情况下no,此选项是禁用的

1.8总结

image-20230912233210482

2.AOF

2.1介绍

Append Only File缩写。记录每次对服务器的写操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。

以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录,只许追加文件但不可用改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

AOF优缺点:

  • 优点:

    • 使用AOF 会让Redis更加耐久:可以使用不同的写回(fsync)策略:no、everysec、always。使用默认的everysec策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,最多丢失1秒的数据。
    • AOF文件是一个只进行追加的日志文件,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,也也可使用redis-check-aof工具修复这些问题。
    • Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
    • AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 如果不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
  • AOF缺点:

    • 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
    • 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入时,RDB 可以提供更有保证的最大延迟时间。

image-20230916214633971

2.2AOF工作流程

image-20230916203246892

①Client作为命令的来源,会有多个源头以及源源不断的请求命令

②在这些命令到达Redis Server以后并不是直接写入AOF文件,会将其这些命令先放入AOF缓存中进行保存。这里的AOF缓冲区实际上是内存中的一片区域,存在的目的是当这些命令达到一定量以后再写入磁盘,避免频繁的磁盘IO操作

③AOF缓冲会根据AOF缓冲区同步文件的三种写回策略将命令写入磁盘上的AOF文件

④随着写入AOF内容的增加为避免文件膨胀,会根据规则进行命令的合并(又称AOF重写),从而起到AOF文件压缩的目的

⑤当Redis Server服务器重启的时候会从AOF文件载入数据

image-20230916205035233

2.3AOF配置

2.3.1配置开启 保存机制更改

  • 开启AOF

AOF默认是关闭的,需要将配置文件中appendonly设置为yes。而保存机制我们就不改了,使用everysec

image-20230916210110800

2.3.2配置AOF文件保存路径(redis6 和redis7不同)

  • redis6

AOF保存文件的位置和RDB保存文件的位置一样,都是通过redis.conf配置文件的dir配置

image-20230916210307348

  • redis7

image-20230916210346511

dir + appenddirname

2.3.3修改AOF文件名和目录名(redis6和redis7不同)

  • redis6:有且只有一个

image-20230916210513257

  • redis7变成三个

image-20230916210556294

image-20230916210606191

aof文件的保存路径和rdb的保存路径是同一个,只不过AOF会在该路径下创建一个appendonlydir文件夹,然后将aof文件保存在该文件夹下。Redis7的aof文件分为三个文件:
appendonly.aof.1.base.rdb 基本文件:存储aof重写后的数据
appendonly.aof.1.incre.aof 追加文件:存储aof追加的数据,达到一定大小后触发AOF重写。
appendonly.aof.manifest 清单文件:追踪管理aof。

image-20230916211118038

2.4三种写回策略

AOF有三种写回策略:

  • Always:同步写回,每个写命令执行完立刻同步地将日志写入磁盘
  • Everysec:每秒写回,每个写命令执行完,先把日志写到AOF文件的内存缓冲区,每隔一秒把缓冲区的内容写入磁盘
  • No:操作系统控制的写回,每个写命令执行完,先把日志写到AOF的内存缓冲区,由操作系统决定何时将缓冲区内容写入磁盘。
配置项写回时机优点缺点
Always同步写回可靠性高,数据基本不丢失每个写命令都要同步记录,性能影响较大
Everysec每秒写回性能适中宕机时丢失一秒内的数据
No操作系统控制的写回性能好宕机时丢失数据较多

2.5AOF的恢复和修复

  • AOF文件数据恢复

在同时开启RDB和AOF持久化时,重启redis服务只会加载aof文件,不会加载rdb文件,即使启动时没有appendonlydir目录,也会创建一个新的appendonlydir目录。

image-20230916212054155

image-20230916212103210

image-20230916212111369

image-20230916212121671

  • AOF文件数据修复

在开启了AOF后,当AOF文件出现异常时,redis服务无法正常启动。可以使用redis-check-aof --fix 文件名命令修复文件。

image-20230916212839175

image-20230916212855717image-20230916212907680

  • AOF紧急恢复

如果误执行了FLUSHALL操作,先停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。因为FLUSHALL或者FLUSHDB也是写命令,会被追加到aof文件中。

2.6触发AOF日志重写

因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。

举个例子, 如果对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要记录100 条记录。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。

为了处理这种情况, Redis 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建,即自动执行BGREWRITEAOF 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令; Redis 2.4后则可以自动触发 AOF 重写。

2.6.1自动触发

自动触发需要满足配置文件中的设置,官方默认设置是:
auto-aof-rewrite-percentage 100:根据上次重写后的aof大小,判断当前aof大小是不是增长了1倍。100%表示一倍。
auto-aof-rewrite-min-size 64mb:重写时满足的文件大小,即incr.aof文件超过了64兆才会重写。

注意同时满足这两个条件才会触发。

2.6.2手动触发

执行命令BGREWRITEAOF即可执行AOF重写。

2.7AOF重写原理

1.在重写开始前,redis会fork一个“重写子进程”,这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
2.与此同时,主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
3.当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。
4.当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中。
5.重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

3.AOF+RDB混合模式

image-20230916213751322

image-20230916213809337

image-20230916213911142

推荐方式:RDB+AOF混合方式:RDB镜像做全量持久化,AOF做增量持久化

结合了RDB和AOF的优点,既能快速加载又能避免丢失过多的数据。

必须首先开启AOF:appendonly yes,默认是关闭的

开启AOF+RDB混合模式:aof-use-rdb-preamble yes,默认是开启的。

同时开启AOF和RDB持久化,当Redis重启时会优先加载AOF文件来恢复原始的数据,因为在通常情况下,AOF保存的数据集要比RDB文件保存的数据集要完整。

在持久化时,先使用RDB进行快照存储,然后使用AOF持久化记录所有写的操作,当重写策略满足或者手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB和AOF两部分恢复数据,既保证了数据的完整性,又提高了恢复数据的性能,简单来说:混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。----》AOF包括了RDB头部+AOF混写

image-20230916214232759

4.纯缓存模式

纯缓存模式即同时关闭AOF和RDB,这样可以最大化redis的读写性能,但无法保证数据的安全性。

关闭RDB:修改配置文件save ""

禁用RDB持久化模式,仍然可以使用命令save、bgsave生成rdb文件。

关闭AOF:修改配置文件appendonly no

禁用AOF持久化模式,仍然可以使用命令bgrewriteaof生成aof文件。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB-1入门介绍

NoSQL NoSQL(NoSQL Not Only SQL),意即反SQL运动,指的是非关系型的数据库 优点 1、对数据库高并发读写。 2、对海量数据的高效率存储和访问。 3、对数据库的高可扩展性和高可用性。 弱点: 1、数据库事务一致性需求 2、数据库的写实时性…

性能测试知多少---性能分析与调优的原理

最近一直纠结性能分析与调优如何下手,先从硬件开始,还是先从代码或数据库。从操作系统(CPU调度,内存管理,进程调度,磁盘I/O)、网络、协议(HTTP, TCP/IP )&…

webpack:css-loader和style-loader关系

测试 当我们webpack 的 rules 啥都没配置的时候 const path require(path);module.exports {entry: ./src/index.js,output: {filename: index.js,path: path.resolve(__dirname, dist)},module: {rules: []} };我们在 js 中导入了 css,发现报错,因为…

软件测试的基础知识

目录 前言 软件测试的生命周期 如何描述一个bug 如何定位bug的级别 bug的生命周期 和开发人员产生争执怎么办 设计一个测试用例 前言 上篇文章主要写了软件测试的一些基本概念以及软件测试的前置知识,这篇文章主要带大家了解在进行软件测试之前要准备的工作. 软件测试…

Trino HTTPS 与密码认证介绍与实战操作

文章目录 一、概述二、安装 Trino三、配置 HTTPS1)生成证书2)配置 Trino3)修改 Trino docker-compose yaml 文件4)开始部署 Trino5)测试验证 四、密码认证1)开启密码认证2)创建密码认证配置文件…

编辑器的缩略图实现原理

一、背景 部分 Web 版的 IDE 编辑器未曾实现缩略图功能,探寻一下缩略图的实现逻辑。以 VSCode 为例。 VSCode 的编辑器是monaco实现的,编辑器的编辑区都是采用的虚拟渲染,即仅渲染可视区的代码,可视区之外的动态去除 DOM 节点。…

SpringBoot结合MyBatis实现多数据源配置

SpringBoot结合MyBatis实现多数据源配置 一、前提条件 1.1、环境准备 SpringBoot框架实现多数据源操作,首先需要搭建Mybatis的运行环境。 由于是多数据源,也就是要有多个数据库,所以,我们创建两个测试数据库,分别是…

6. 装饰器

UML 聚合(Aggregation)关系&#xff1a;大雁和雁群&#xff0c;上图中空心菱形箭头表示聚合关系组合(Composition)关系&#xff1a;大雁和翅膀 &#xff0c;实心菱形箭头表示组合(Composition)关系 测试代码 #include <iostream> #include <stdio.h> #include &l…

R 语言的安装教程

一、下载相关软件 1、R 下载 官网&#xff1a;R: The R Project for Statistical Computing 找到中国镜像&#xff0c;下载快 历史版本点击这里 2、Rtools 下载 进入镜像后&#xff0c;点击这里 然后选择与上面下载的R版本相对应的版本即可 3、Rstudio 下载 官网&#xff1…

Spring 篇

1、什么是 Spring&#xff1f; Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架&#xff0c;目的是用于简化企业应用程序的开发&#xff0c;它使得开发者只需要关心业务需求。常见的配置方式有三种&#xff1a;基于XML的配置、基于注解的配置…

Prometheus+Grafana可视化监控【Nginx状态】

文章目录 一、安装Docker二、安装Nginx(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装nginx_exporter七、Grafana添加Nginx监控模板 一、安装Docker 注意&#xff1a;我这里使用之前写好脚本进行安装Docker&#xff0c;如果已经有D…

排查disabled问题之谷歌新版本特性

问题复现 最近我突然接手一个后台的bug&#xff0c;这个后台很久没有迭代更新了&#xff0c;我也不熟悉业务&#xff0c;所以只能看一下源码&#xff0c;问题很快就复现&#xff0c;测试的修复操作也很正确&#xff0c;就是因为渲染的input标签中存在disableddisabled’属性导…

Swing程序设计详解(一)

【今日】 “若你决定灿烂&#xff0c;山无遮&#xff0c;海无拦” 目录 初识Swing 一 Swing简述 二 Swing常用窗体 2.1 JFrame窗体 2.2 JDialog对话框 2.3JOptionPane小型对话框 (1)通知框 (2)确认框 (3)输入框 (4)自定义对话框 三 常用布局管理器 3.1 绝…

计算机组成与设计硬软件接口学习2

并行处理器&#xff1a;从客户端到云 任务级并行或进程级并行&#xff1a;通过同时运行独立的多个程序来使用多处理器 并行处理程序&#xff1a;同时在多个处理器上运行的单个程序 向量和标量 向量指令的重要属性&#xff1a; 单个向量指令指定了大量工作--相当于执行了完…

代码随想录训练营第四十八天|198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

198.打家劫舍 力扣题目链接(opens new window) 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系…

基于PyTorch使用LSTM实现新闻文本分类任务

本文参考 PyTorch深度学习项目实战100例 https://weibaohang.blog.csdn.net/article/details/127154284?spm1001.2014.3001.5501 文章目录 本文参考任务介绍做数据的导入 环境介绍导入必要的包介绍torchnet和keras做数据的导入给必要的参数命名加载文本数据数据前处理模型训…

Android高级开发-APK极致优化

九道工序 1. SVG(Scalable Vector Graphics)可缩放矢量图 使用矢量图代替位图可以减小 APK 的尺寸&#xff0c;因为可以针对不同屏幕密度调整同一文件的大小&#xff0c;而不会降低图像质量。 矢量图首次加载时可能消耗更多的 CPU 资源。之后&#xff0c;二者的内存使用率和…

Java集合之LinedList

LinedList类实现了List接口&#xff0c;他提供了&#xff08;双向的&#xff09;链表数据结构 在该链表中的每一个元素除了存储本身的内容之外还存储指向前一个元素的指针和指向后一个元素的指针&#xff0c;下图展示了一个包含三个元素的双向链表&#xff0c;每个链表都有一个…

jeesite实现excel导入功能(保姆级图文教程)

文章目录 前言一、准备工作1.准备一个excel模板,放入static目录2.application.yml文件中设置文件存储路径3.使用easyexcel插件解析excel数据,pom文件导入easyexcel二、使用步骤1.列表页添加下载模板按钮2.表单页添加文件上传3. 创建excel解析对应实体4.后台完成文件上传代码,…

深入探索智能问答:从检索到生成的技术之旅

目录 一、智能问答概述1. **语义理解**2. **知识库和数据库**3. **上下文感知**4. **动态学习和自适应** 二、发展历程1. **基于规则的系统**2. **统计方法的兴起**3. **深度学习和神经网络的突破**4. **预训练模型** 三、智能问答系统的主要类型四、基于知识库的问答系统五、基…