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

Redis持久化机制详解

为什么需要持久化

Redis通常被作为缓存使用,但是Redis一旦宕机,内存中的数据全部丢失,可能会导致数据库崩溃。如果是从数据库中恢复这些数据就会存在频繁访问数据库和读取速度慢的问题。所以redis实现数据的持久化,是至关重要的。

Redis 为了实现⽆畏宕机快速恢复,设计了两⼤杀⼿锏,分别是 AOF(Append Only FIle)⽇志和 RDB 快照。

RDB(内存快照)

什么是RDB

RDB(内存快照)是Redis DataBase的缩写,所谓内存快照,就是指内存中的数据在某一个时刻的状态记录。这就类似于照片,当你给朋友拍照时,一张照片就能把朋友一瞬间的形象完全记下来。

对Redis来说,它实现类似照片记录效果的方式,就是把某一时刻的状态以文件的形式写到磁盘上,也就是快照。即使宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。在做数据恢复时,我们可以直接把RDB文件读入内存,很快地完成恢复。RDB保存的是dump.rdb文件。

生成RDB策略

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

  • save:在主线程中执行,会导致阻塞(线上禁止使用);
  • bgsave:创建一个子进程,专门用于写入RDB文件,避免了主线程的阻塞,这也是Redis RDB文件生成的默认配置。
在对内存数据做「快照」的时候,内存数据还能修改么

避免阻塞和正常处理写操作并不是一回事。此时,主线程的确没有阻塞,可以正常接收请求,为了保证快照完整性,它只能处理读操作,因为不能修改正在执行快照的数据。

为了快照而暂停写操作,肯定是不能接受的。所以这个时候,Redis就会借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。

简单来说,bgsave子进程是由主线程fork生成的,可以共享主线程的所有内存数据。bgsave子进程运行后,开始读取主线程的内存数据,并把它们写入RDB文件。

如果主线程对这些数据也都是读操作(例如图中的键值对A),那么,主线程和bgsave子进程相互不影响。但是,如果主线程要修改一块数据(例如图中的键值对C),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave子进程会把这个副本数据写入RDB文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

image-20240421222944678

Redis 会使⽤ bgsave 对当前内存中的所有数据做快照,这个操作是⼦进程在后台完成的,这就允许主线程同时可以修改数据。

可以每秒执行RDB文件吗

过于频繁的执⾏全量数据快照,有两个严重性能开销:

  1. 频繁⽣成 RDB ⽂件写⼊磁盘,磁盘压⼒过⼤。会出现上⼀个 RDB 还未执⾏完,下⼀个⼜开始⽣成,陷⼊死循环。
  2. fork 出 bgsave ⼦进程会阻塞主线程,主线程的内存越⼤,阻塞时间越⻓。
RDB的优缺点

快照的恢复速度快,但是⽣成 RDB ⽂件频率不好把握,频率过低宕机丢失的数据就会⽐较多;太快,⼜会消耗额外开销。RDB 采⽤⼆进制 + 数据压缩的⽅式写磁盘,⽂件体积⼩,数据恢复速度快。

RDB持久化触发策略
  1. 自动触发策略

    自动触发策略,是指 Redis 在指定的时间内,数据发生了多少次变化时,会自动执行BGSAVE命令。自动触发的条件包含在了 Redis 的配置文件中。

    image-20240422223241004

    上图所示, save m n 的含义是在时间 m 秒内,如果 Redis 数据至少发生了 n 次变化,那么就自动执行BGSAVE命令。配置策略说明如下:

    save 3600 1 表示在 3600 秒内,至少更新了 1 条数据,Redis 自动触发 BGSAVE 命令,将数据保存到硬盘。

    save 300 10 表示在 300 秒内,至少更新了 10 条数据,Redis 自动触 BGSAVE 命令,将数据保存到硬盘。

    save 60 10000 表示 60 秒内,至少更新了 10000 条数据,Redis 自动触发 BGSAVE 命令,将数据保存到硬盘。
    只要上述三个条件任意满足一个,服务器就会自动执行BGSAVE命令。当然您可以根据实际情况自己调整触发策略。

    演示操作

    配置:save 5 2 – 5秒内2次修改

    image-20240422223721835

    修改dump文件保存路径

    ##创建myredis文件夹
    cd /opt/redis-7.0.0
    mkdir myredis
    ##创建dumpfiles文件夹
    mkdir dumpfiles
    

    将dir . 改为 /myredis/dumpfiles

    image-20240422224123404

    修改dump文件名称

    image-20240422225058758

    修改完配置文件尽量都重启下服务。

    连接服务

    ##进入/opt/redis-7.0.0
    cd /opt/redis-7.0.0
    ## 连接redis
    redis-cli
    auth 123456
    

    image-20240422224834311

    ##执行命令(查看myredis/dumpfiles文件夹下是空的)
    set k1 v1
    ##5秒内执行命令(查看myredis/dumpfiles文件夹下有文件)
    set k2 v2
    

    image-20240422230445974

    恢复redis数据

    1. 先备份dump文件
    ##备份
    cd /opt/redis-7.0.0/myredis/dumpfiles/
    mv dump6379.rdb dump6379.rdb.bak
    1. 清空redis数据
    ##进入/opt/redis-7.0.0
    cd /opt/redis-7.0.0
    ## 连接redis
    redis-cli
    auth 123456
    FLUSHDB
    

    image-20240422231826946

    3.查看dump文件

    执行flushall/flushdb时,也会产生rdb文件,只不过里面是空的,没有意义。

    image-20240422231912767

    1. RDB文件载入

    和使用SAVE命令或者BGSAVE命令创建RDB文件不同,RDB文件的载入工作是在服务器启动时自动执行的,所以Redis并没有专门用于载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入RDB文件。

    服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。

  2. 手动触发策略

有两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE。

SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求:

127.0.0.1:6379> save

和SAVE命令直接阻塞服务器进程的做法不同,BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求:

127.0.0.1:6379> bgsave
会触发RDB快照的情况
  1. 配置文件中默认的快照配置
  2. 手动save/bgsave命令
  3. 执行flushall/flushdb命令也会产生dump.rdb文件,但里面是空的
  4. 执行shutdown且没有设置开启AOF持久化
  5. 主从复制时,主节点自动触发

AOF追加日志

AOF是Redis的另外一种持久化方式。AOF就是将Redis服务端执行过的每一条命令都保存到一个文件,这样当Redis重启时只要按顺序回放这些命令就会恢复到原始状态。默认情况下,redis是没有开启AOF(append only file)的功能,需要设置配置:appendonly:yes。

有了RDB为什么还需要AOF

RDB保存的是一个时间点的快照,如果Redis出现了故障,丢失的就是从最后一次RDB执行的时间点到故障发生的时间间隔之内产生的数据。如果Redis数据量很大,那么丢失的数据也会很多。

而AOF保存的是一条条命令,理论上可以做到发生故障时只丢失一条命令。但由于操作系统中执行写文件操作代价很大,Redis提供了配置参数,通过对安全性和性能的折中,我们可以设置不同的策略。

为什么不直接使用AOF

用AOF方法进行故障恢复的时候,需要逐一把操作日志都执行一遍。如果操作日志非常多,Redis就会恢复得很缓慢,影响到正常使用。

AOF的持久化实现

AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤。

命令追加的原理

当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾。

## 例如在redis中执行命令
> set K1 value

那么服务器在执行这个SET命令之后,会将以下协议内容追加到aof_buf缓冲区的末尾:

*3\r\n$3\r\nSET\r\n$2\r\nK1\r\n$5\r\nvalue\r\n
## 例如继续在redis中执行命令
> RPUSH k2 ONE TWO THREE

那么服务器在执行这个SET命令之后,会将以下协议内容追加到aof_buf缓冲区的末尾:

*5\r\n$5\r\nRPUSH\r\n$2\r\nK2\r\n$3\r\nONE\r\n$3\r\nTWO\r\n$5\r\nTHREE\r\n

以第一个例子中的参数为例:以*3开始,表示命令共有3个参数。$3表示接下来的第1个参数(SET)长度为3,读取为SET,第1个参数就解析完毕。
以此类推,$2表示第2个参数的长度为2,读取为K1,$5表示第3个参数的长度为5,读取为value。至此,该条命令解析完毕。

AOF的写入和同步

为了提⾼⽂件的写⼊效率,当⽤户调⽤ write 函数,将⼀些数据写⼊到⽂件的时候,操作系统通常会将写⼊数据暂时保存在⼀个内存缓冲区⾥⾯,
等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写⼊到磁盘⾥⾯。
这种做法虽然提⾼了效率,但也为写⼊数据带来了安全问题,因为如果计算机发⽣停机,那么保存在内存缓冲区⾥⾯的写⼊数据将会丢失。
为此,系统提供了 fsync 和 fdatasync 两个同步函数,它们可以强制让操作系统⽴即将缓冲区中的数据写⼊到硬盘⾥⾯,从⽽确保写⼊数据的安全性。
Redis 提供的 AOF 配置项 appendfsync 写回策略直接决定 AOF 持久化功能的效率和安全性。

  1. always:同步写回,写指令执⾏完毕⽴⻢将aof_buf缓冲区中的内容刷写到 AOF⽂件。

  2. everysec:每秒写回,写指令执⾏完,⽇志只会写到 AOF ⽂件缓冲区,每隔⼀秒就把缓冲区内容同步到磁盘。

  3. no: 操作系统控制,写执⾏执⾏完毕,把⽇志写到 AOF ⽂件内存缓冲区,由操作系统决定何时刷写到磁盘。

同步写回:可以做到数据不丢失,但是每个“写”指令都需要写⼊磁盘,性能最差。
每秒写回:避免了同步写回的性能开销,发⽣宕机可能有⼀秒位写⼊磁盘的数据丢失,在性能和可靠性之间做了折中。
操作系统控制:执⾏写指令后就写⼊ AOF ⽂件缓冲就可以执⾏后续的“写”指令,性能最好,但是有可能丢失很多的数据。

AOF文件的载入与数据还原

AOF文件包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态。

Redis读取AOF文件并还原数据库状态的详细步骤如下:

  1. 创建一个不带网络连接的伪客户端(fake client):因为Redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行AOF文件保存的写命令,伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样。

  2. 从AOF文件中分析并读取出一条写命令。

  3. 使用伪客户端执行被读出的写命令。

  4. 一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被处理完毕为止。

当完成以上步骤之后,AOF文件所保存的数据库状态就会被完整地还原出来。

AOF重写机制

由于AOF持久化是通过保存被执行的写命令来记录数据库状态的,所以随着操作的不断增加,AOF文件中的内容会越来越多,文件的体积也会越来越大。由于体积越来越大如果要恢复数据则需要更多的时间。

可以看到为了记录这个list键的状态(如下图所示),AOF文件就需要保存六条命令。为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写(rewrite)功能。

redis> RPUSH list "A" "B" //["A","B"]
redis> RPUSH list "c" // ["A","B","C"]
redis> RPUSH list "D" "E" // ["A","B","C","D","E"]
redis> LPOP list "A" // ["B", "C","D","E"]
redis> LPOP list "B" // ["c","D","E"]
redis> RPUSH list "F" "G" // ["C","D","E","F","G" ]
文件重写的原理
  1. redis调用fork函数,产生一个子进程。
  2. 子进程把新的AOF文件写到一个临时文件里。
  3. 父进程持续把新的变动写到内存里的缓冲区(buffer),同时也会把这些新的变动写到旧的AOF文件里,这样即使重写失败也能保证数据的安全。
  4. AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,直接从数据库中读取键list的值,然后用一条终态命令来代替保存在AOF文件中的多条命令
  5. 当子进程完成文件的重写后,父进程会获得一个信号,然后把内存里的缓冲区内容追加到子进程生成的新AOF文件里。
设置日志重写条件

我们可以设置日志重写的条件。下面的实例表示当AOF文件的体积大于64 MB,并且AOF文件的体积比上一次重写之后的体积大了至少一倍(100%)的时候,Redis将执行日志重写操作。

auto aof-rewrite percentage 100
auto-aof-rewrite min size 64MB

Redis会记住自从上一次重写后AOF文件的大小。要禁用自动的日志重写功能,可以把百分比设置为0。

auto-aof-rewrite percentage 0
AOF重写机制为什么能缩小日志文件

重写机制有“多变⼀”功能,将旧⽇志中的多条指令,在重写后就变成了⼀条指令。

如果Redis使用主进程重写AOF,会造成服务器无法处理请求,所以Redis决定将AOF重写程序放到子进程里执行,这样做可以同时达到两个目的:

  • 子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求。
  • 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。
在重写中有数据写入怎么办

使用子进程也有一个问题需要解决,因为子进程在进行AOF重写期间,服务器进程还需要继续处理命令请求,而新的命令可能会对现有的数据库状态进行修改,从而使得服务器当前的数据库状态和重写后的AOF文件所保存的数据库状态不一致。

为了解决这种数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区。AOF 重写⼀个新⽂件,如果重写失败的话,直接删除这个⽂件就好了,不会对原先的 AOF ⽂件产⽣影响。等重写完成之后,直接替换旧⽂件即可。

在子进程执行AOF重写期间,服务器进程需要执行以下三个工作:

  1. 执行客户端发来的命令。
  2. 将执行后的写命令追加到AOF缓冲区。
  3. 将执行后的写命令追加到AOF重写缓冲区。

当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会调用一个处理函数,并执行以下操作:

  1. 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。
  2. 对新的AOF文件进行改名,原子的(atomic)覆盖现有的AOF文件,完成新旧两个AOF文件的替换。

AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。

image-20240427133003337

AOF案例演示
开启AOF日志

image-20240427174544824

日志路径

redis7的路径是dir+appenddirname:/opt/redis-7.0.0/myredis/dumpfiles/appendonlydir/appendonly.aof

image-20240427205820431

AOF文件方案

image-20240427210320332

MP-AOF实现方案概述
顾名思义,MP-AOF就是将原来的单个AOF文件拆分成多个AOF文件。在MP-AOF中,我们将AOF分为三种类型分别为:

  1. BASE: 表示基础AOF,它一般由子进程通过重写产生,该文件最多只有一个。
  2. INCR: 表示增量AOF,一般会在AOFRW开始执行时被创建,该文件可能存在多个。
  3. HISTORY: 表示历史AOF,它由BASE和INCR AOF变化而来,每次AOFRW成功完成时本次AOFRW之前对应的BASE和INCR AOF都将变为HISTORY,HISTORY类型的AOF会被Redis自动删除。我们引入了一个manifest(清单)文件来跟踪、管理这些AOF。同时,为了便于AOF备份为了管理这些AOF文件和拷贝,我们将所有的AOF文件和manifest文件放入一个单独的文件目录中,目录名由appenddirname配置(Redis 7.0新增配置项)决定。
AOF正常恢复
##进入redis
redis-cli -a 123456
##设置key-value数据
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"

进入/opt/redis-7.0.0/myredis/dumpfiles/appendonlydir,可以看到如下图所示,有三个文件。

image-20240427213329647

  1. 重启redis,重新加载数据,恢复数据
##备份aof文件夹
cp -r appendonlydir/ appendonlydir.bak
##清空内存数据
127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> keys *
(empty array)
##删除rdb文件
cd /opt/redis-7.0.0/myredis/dumpfiles
rm -rf dump6379.rdb
##关闭redis
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
##进入配置文件文件夹
cd /opt/redis-7.0.0/myredis/dumpfiles
rm -rf dump6379.rdb
rm -rf appendonlydir
mv appendonlydir.bak/ appendonlydir
##启动redis
redis-server redis.conf
##检查是否恢复
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "k3"
  1. AOF在异常下的恢复
##打乱aof的文件,模拟网络闪断,文件写error,如下图所示
[root@bogon appendonlydir]# vim appendonly.aof.1.incr.aof
##关闭redis
127.0.0.1:6379> SHUTDOWN

image-20240427222013843

##启动redis,发现启动失败
redis-server redis.conf

image-20240427222702964

##执行异常修复命令
cd /opt/redis-7.0.0/myredis/dumpfiles/appendonlydir
redis-check-aof --fix appendonly.aof.1.incr.aof

image-20240427222952973

##验证是否修复数据
cat appendonly.aof.1.incr.aof

image-20240427223019873

##启动redis服务
redis-server redis.conf
##连接redis
redis-cli -a 123456
##查看数据是否恢复
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"

Redis 4.0 混合⽇志模型

重启 Redis 时,我们很少使⽤ rdb 来恢复内存状态,因为会丢失⼤量数据。我们通常使⽤ AOF ⽇志重放,但是重放 AOF ⽇志性能相对 rdb 来说要慢很多,这样在 Redis 实例很⼤的情况下,启动需要花费很⻓的时间。

Redis 4.0 为了解决这个问题,带来了⼀个新的持久化选项——混合持久化。将 rdb ⽂件的内容和增量的 AOF ⽇志⽂件存在⼀起。这⾥的 AOF ⽇志不再是全量的⽇志,⽽是⾃持久化开始到持久化结束的这段时间发⽣的增量 AOF ⽇志,通常这部分 AOF ⽇志很⼩。

于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF ⽇志就可以完全替代之前的 AOF 全量⽂件重放,重启效率因此⼤幅得到提升。

所以 RDB 内存快照以稍微慢⼀点的频率执⾏,在两次 RDB 快照期间使⽤ AOF ⽇志记录期间发⽣的所有“写”操作。这样快照就不⽤频繁的执⾏,同时由于 AOF 只需要记录两次快照之间发⽣的“写”指令,不需要记录所有的操作,避免出现⽂件过⼤的情况。

相关文章:

Redis持久化机制详解

为什么需要持久化 Redis通常被作为缓存使用,但是Redis一旦宕机,内存中的数据全部丢失,可能会导致数据库崩溃。如果是从数据库中恢复这些数据就会存在频繁访问数据库和读取速度慢的问题。所以redis实现数据的持久化,是至关重要的。…...

Python 鼠标轨迹 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...

PB-DW-数据窗口-降级-从12.5降级到9.0

PB 数据窗口从125降级到90 供参考,有哪些属性仍然需要删除,请在评论区留言。谢谢。 如果您有更好的工具,能分享给我一份的话,就更好了,感谢。 12.5数据窗口降级9.01- release 12.5; 更改为 release 9;2- 第二行的 d…...

Logo语言的测试开发

Logo语言的测试开发 引言 随着编程教育的不断发展,学习编程的门槛逐渐降低,各种编程语言应运而生。其中,Logo语言作为一种经典的教育编程语言,在培养儿童的逻辑思维和解决问题的能力方面,发挥了重要的作用。本文将深…...

位图的深入解析:从数据结构到图像处理与C++实现

在学习优选算法课程的时候,博主学习位运算了解到位运算的这个概念,之前没有接触过,就查找了相关的资料,丰富一下自身,当作课外知识来了解一下。 位图(Bitmap)是一种用于表示图像的数据结构&…...

Faveo Helpdesk存在目录遍历漏洞(CVE-2024-37700)

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...

【Pytorch函数】PyTorch随机数生成全解析 | torch.rand()家族函数使用指南

🌟 PyTorch随机数生成全解析 | torch.rand()家族函数使用指南 🌟 📌 一、核心函数参数详解 PyTorch提供多种随机数生成函数(注意:无直接torch.random()函数),以下是常用函数及参数:…...

ML.NET库学习004:ML.NET基础知识复盘

文章目录 ML.NET库学习004:ML.NET基础知识复盘背景简单的 ML.NET 应用程序代码工作流机器学习模型基础进阶 ML.NET 架构构建管道训练模型使用模型 数据模型和架构模型部署 ML.NET库学习004:ML.NET基础知识复盘 学了几个小项目,发现好多方法莫…...

2. UVM的基本概念和架构

文章目录 前言1. UVM的基本概念1.1 UVM的核心组件1.2 UVM的基本架构1.3 UVM的工作流程 2. UVM的架构2.1 UVM的层次结构2.2 UVM的组件交互 3. 总结 前言 首先,得确定UVM的基本概念和架构包含哪些关键部分。我回忆起UVM的核心组件,比如uvm_component、uvm…...

算法10--哈希

哈希 原理经典例题[1. 两数之和](https://leetcode.cn/problems/two-sum/description/)[面试题 01.02. 判定是否互为字符重排](https://leetcode.cn/problems/check-permutation-lcci/description/)[217. 存在重复元素](https://editor.csdn.net/md?not_checkout1&spm1015…...

磁盘文件删除后恢复

磁盘文件删除后,文件数据并未立即消失,只是文件系统的指针被移除,标记该空间为可覆盖。要恢复文件,可以尝试以下方法: 1. 使用数据恢复软件 Recuva:适合Windows,能恢复多种文件类型。PhotoRec…...

STM32 CUBE Can调试

STM32 CUBE Can调试 1、CAN配置2、时钟配置3、手动添加4、回调函数5、启动函数和发送函数6、使用方法(采用消息队列来做缓存)7、数据不多在发送函数中获取空邮箱发送,否则循环等待空邮箱 1、CAN配置 2、时钟配置 3、手动添加 需要注意的是STM32CUBE配置的代码需要再…...

【大模型】Ubuntu下安装ollama,DeepSseek-R1:32b的本地部署和运行

1 ollama 的安装与设置 ollama官网链接:https://ollama.com/ 在左上角的【Models】中展示了ollama支持的模型在正中间的【Download】中课可以下载支持平台中的安装包。   其安装和模型路径配置操作流程如下: ollama的安装 这里选择命令安装curl -fsSL …...

Goland 内存逃逸问题

内存逃逸是什么? 在go语言中,内存分配存在两个方式:堆分配;栈分配。 栈分配:是在函数调用时为局部变量分配内存,当函数返回时,这些内存会自动释放。 堆分配:通过 new 或者 make 函…...

我们来学人工智能 -- 本地部署DeepSeek

本地部署DeepSeek 题记思考正题结语 题记 时不待我AI会淘汰各领域一些岗位AI可以精简部门,DP白菜价的落地,2025年会更加明显会AI的淘汰不会AI的第四次工业革命将在中国爆发 全产业链多年数字化建设以DP为代表的全球领先白菜价人工智能在各行各业的普及 …...

【GitHub】GitHub 2FA 双因素认证 ( 使用 Microsoft Authenticator 应用进行二次验证 )

文章目录 一、GitHub 的 2FA 双因素认证二、使用 Microsoft Authenticator 应用进行二次验证1、TOTP 应用2、下载 Microsoft Authenticator 应用3、安装使用 Authenticator 应用 三、恢复码重要性 一、GitHub 的 2FA 双因素认证 现在登录 GitHub 需要进行二次身份验证 ; 先登录…...

通过脚本实现自动将标签内容复制到下一个标签文件中

只需要将下面内容运行前 修改文件夹路径(控制修改范围的文件名 不需要的话 就随便写一个不相同的文件名 就行 需要的话就是在这个文件名字之前的会被修改) import os import time # 文件夹路径 image_directory r"C:\Users\Lenovo\Desktop\新建文件夹\images" # 替…...

Elasticsearch+Kibana安装启动与操作教程

在大数据时代,Elasticsearch(简称 ES)和 Kibana 作为强大的数据搜索与可视化工具,受到了众多开发者的青睐。本文将为您详细介绍在 Windows 和 Mac 系统上安装、启动 Elasticsearch 和 Kibana 的步骤,以及常用命令和 Ki…...

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中,处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性,帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性? overflow 属性用于控制当元素的内容…...

什么是XMLHttpRequest?及其详细使用说明

XMLHttpRequest(通常缩写为XHR)是一个JavaScript对象,用于在浏览器和服务器之间进行异步通信。它允许网页在不重新加载整个页面的情况下,向服务器发送请求并接收响应。XHR是Ajax(Asynchronous JavaScript and XML&…...

Chrome浏览器原理及优化

1. 相关面试题 1.1. 请说说从输入 URL 到页面渲染完成的全过程 1. 输入URL,用户在浏览器的地址栏输入一个URL,并按下回车键; 2. DNS解析; 浏览器需要将域名转换为服务器的IP地址,以建立连接。 (1). 如果浏览器缓存、操作系统缓存或路由器缓存中已有该域名的IP地址,…...

Vue 3 + Vite + JS 项目中实现组件全局自动化注册的魔法,极致组件自动化注册方案,开发效率飙升300%。

在Vue项目开发中,你是否还在为重复的组件注册代码而烦恼?是否经历过在大型项目中手动维护数百个组件注册的痛苦?本文将揭秘一种革命性的组件自动化注册方案,结合Vite的黑魔法和Vue3的最新特性,让你的开发效率实现质的飞…...

寒假2.8

题解 web:[RoarCTF 2019]Easy Calc 打开,是一个计算界面 看一下源代码,提示设置了WAF,并且有一个calc.php文件 访问一下calc.php文件,得到源码,使用get方式传参赋值给num,设置了黑名单&#x…...

企业如何利用DeepSeek提升网络安全管理水平

企业可以通过深度整合DeepSeek的AI能力,构建智能化、动态化的网络安全防御体系,以应对APT(高级持续性威胁)等复杂攻击。以下是具体策略与实践路径: 1. AI驱动的威胁检测与分析 多模态威胁狩猎 DeepSeek的深度学习技术能…...

C++ libfmt 实战: 高效便捷的格式化库

libfmt 是一个现代化的 C格式化库{fmt}, 具有以下关键特性: 安全性: 受 Python 格式化功能启发, {fmt}为printf系列函数提供安全替代方案. 格式字符串错误在编译时就能被检测出来, 并且通过自动内存管理避免缓冲区溢出错误.可扩展性: 默认支持格式化大多数标准类型, 包括容器,…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_max_sockets

在 Nginx 的源代码中, ngx_max_sockets 全局变量的声明位于 os/unix/ngx_os.h extern ngx_int_t ngx_max_sockets; 定义在 os/unix/ngx_posix_init.c ngx_int_t ngx_max_sockets; ngx_max_sockets 定义了 Nginx 能够同时使用的最大 Socket 文件描述符数量。它…...

Spring Boot接入Deep Seek的API

1,首先进入deepseek的官网:DeepSeek | 深度求索,单击右上角的API开放平台。 2,单击API keys,创建一个API,创建完成务必复制!!不然关掉之后会看不看api key!!&…...

大语言模型实践——基于现有API的二次开发

基于现有的API平台做一些实用的AI小应用。 API服务商:阿里云百炼 云服务器:阿里云(2核2GB) 部署框架:gradio 调用框架:openai 语言:Python (注:若搭建网站或API接口…...

ChunkKV:优化 KV 缓存压缩,让 LLM 长文本推理更高效

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

深入探究 Go 语言中的 Fx 框架:依赖注入的强大工具

在软件开发中,依赖注入(Dependency Injection,简称 DI)是一种重要的设计模式,它可以帮助我们降低代码的耦合度,提高代码的可测试性和可维护性。Go 语言作为一门高效、简洁的编程语言,拥有许多优…...

用 DeepSeek + Kimi 自动做 PPT,效率起飞

以下是使用 DeepSeek Kimi 自动做 PPT 的详细操作步骤: 利用 DeepSeek 生成 PPT 内容: 访问 DeepSeek 官网,完成注册/登录后进入对话界面。输入指令,例如“请用 Markdown 格式生成一份关于[具体主题]的 PPT 大纲,需包…...

【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战

【04】Java若依vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战 项目背景 本项目经费43000元,需求文档如下,工期25天,目前已经过了8天,时间不多了&#x…...

【C++】异常

前言 本篇博客我们来看下C有关异常的处理,了解下异常有关的知识 💓 个人主页:小张同学zkf ⏩ 文章专栏:C 若有问题 评论区见📝 🎉欢迎大家点赞👍收藏⭐文章 ​ 目录 1.异常的概念及使用 1.1异…...

Meta AI 最近推出了一款全新的机器学习框架ParetoQ,专门用于大型语言模型的4-bit 以下量化

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

金融资产配置

不要放在一个篮子里也不要放在太多篮子里: 尽量放在不相关的行业实现风险对冲 金融资产从风险类别上主要可以分为三类: 进攻型资产、稳定型资产和防守型资产 进攻型资产包括原油、股票、一级市场股权投资等 稳定型资产包括信托、理财、国债等 防守…...

(done) openMP学习 (Day14: 总结)

url: https://dazuozcy.github.io/posts/introdution-to-openmp-intel/#23-%E5%8F%AF%E6%80%95%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8Batomicsflushpairwise%E5%90%8C%E6%AD%A5%20 新手并行程序员与专家并行程序员之间的区别是专家have a collection…...

音频进阶学习十一——离散傅里叶级数DFS

文章目录 前言一、傅里叶级数1.定义2.周期信号序列3.表达式DFSIDFS参数含义 4.DFS公式解析1)右边解析 T T T、 f f f、 ω \omega ω的关系求和公式N的释义求和公式K的释义 e j ( − 2 π k n N ) e^{j(\frac{-2\pi kn}{N})} ej(N−2πkn​)的释义 ∑ n 0 N − 1 e…...

ssm的心得

spring是一个轻量级的ioc(控制反转)和aop(面向切面编程)容器框架,它可以管理和配置应用中的各种bean(对象),实现bean之间的依赖注入,以及提供事务管理、缓存、测试等功能…...

14vue3实战-----获取用户信息和用户的菜单树信息

14vue3实战-----获取用户信息和用户的菜单树信息 1.获取用户信息1.1封装接口1.2优化 2.获取用户的菜单树信息 1.获取用户信息 1.1封装接口 后端有根据id获取用户信息的接口,前端需要把该接口封装一下: service/login/login.ts: import hyRequest from…...

shell脚本学习笔记

Shell脚本学习笔记 参考资料:https://www.runoob.com/linux/linux-shell-passing-arguments.html 文章目录 Shell脚本学习笔记一、什么是Shell1.1、定义1.2、注释 二、Shell变量2.1、规则2.2、变量类型2.2.1、字符串2.2.2、整数2.2.3、数组2.2.4、环境变量2.2.5、特…...

Java中的线程池及其应用场景有哪些?

Java中的线程池是一种高效的并发编程机制,通过复用线程来管理任务的执行,从而提高资源利用率和系统性能。 本文将详细探讨Java线程池的概念、类型、应用场景以及实际代码示例,帮助读者全面理解线程池的使用方法及其在实际开发中的重要性。 …...

13.6 基于 LangChain架构优化实战:OpenAI-Translator翻译系统重构与10倍效率提升秘籍

LangChain架构优化实战:OpenAI-Translator翻译系统重构与10倍效率提升秘籍 关键词:LangChain 架构优化, 模块解耦, 翻译系统设计模式, 可扩展翻译框架, 多模型管理 1. 原架构痛点分析 问题维度原实现缺陷LangChain 优化方案大模型耦合直接调用 OpenAI API,切换模型需改代码…...

构建基于 SSE 协议通信的 MCP Server 和 Client

在之前的系列教程中,我们编写的 MCP 服务器与 MCP 客户端是通过 **stdio(Standard Input/Output,标准输入输出)**来进行交互的。客户端通过启动服务器子进程,并利用标准输入(stdin)和标准输出&a…...

Docker、Ollama、Dify 及 DeepSeek 安装配置与搭建企业级本地私有化知识库实践

在现代企业中,管理和快速访问知识库是提升工作效率、促进创新的关键。为了满足这些需求,企业越来越倾向于构建本地私有化的知识库系统,这样可以更好地保护企业数据的安全性和隐私性。本文将介绍如何利用 **Docker**、**Ollama**、**Dify** 和…...

第3章 使用 Vue 脚手架

第3章 使用 Vue 脚手架 3.1 初始化脚手架3.1.1 说明3.1.2. 具体步骤3.1.3 分析脚手架结构1 总结2 细节分析1 配置文件2 src文件1 文件结构分析2 例子 3 public文件4 最终效果 3.2 ref属性3.3 props配置项3.4 mixin混入3.5 插件3.6 scoped样式3.7 Todo-list 案例3.7.1 组件化编码…...

MySQL第五次作业

根据图片内容完成作业 1.建表 (1)建立两个表:goods(商品表)、orders(订单表) mysql> create table goods( -> gid char(8) primary key, -> name varchar(10), -> price decimal(8,2), -> num int); mysql> create t…...

pikachu[皮卡丘] 靶场全级别通关教程答案 以及 学习方法 如何通过渗透测试靶场挑战「pikachu」来精通Web渗透技巧? 一篇文章搞完这些问题

目录 Pikachu靶场 部署 暴力破解漏洞 学习地址: 靶场练习: 基于表单的暴力破解 验证码绕过(on server) 验证码绕过(on Client) token防爆破? XSS跨站脚本攻击 学习地址: 靶场练习: 反射型xss(get) 反射性xss(post) 存储型xss DOM型xss xss盲打 x…...

ai智能DeepSeek 在 Cursor 中的配置与应用实践

DeepSeek 是一款高效的深度搜索引擎,能够为开发者提供更智能、更精准的搜索体验。在数据量大、查询复杂的场景中,DeepSeek 能够帮助提升查询的响应速度和精确度。本文将介绍 DeepSeek 在 Cursor 中的配置与应用,帮助开发者理解如何在实际开发…...

登录到docker里

在Docker中登录到容器通常有两种情况: 登录到正在运行的容器内部:如果你想要进入到正在运行的容器内部,可以使用docker exec命令。 登录到容器中并启动一个shell:如果你想要启动一个容器,并在其中启动一个shell&…...

【大数据技术】搭建完全分布式高可用大数据集群(Kafka)

搭建完全分布式高可用大数据集群(Kafka) kafka_2.13-3.9.0.tgz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群 Kafka 的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/software目录下,软件安装至/opt目录下。 安…...