【Redis】Redis持久化深度解析

news2024/11/18 0:32:10

原创不易,注重版权。转载请注明原作者和原文链接

文章目录

    • Redis持久化介绍
    • RDB原理
      • Fork函数与写时复制
        • 关于写时复制的思考
      • RDB相关配置
    • AOF原理
      • AOF持久化配置
      • AOF文件解读
      • AOF文件修复
      • AOF重写
      • AOF缓冲区与AOF重写缓存区
      • AOF缓冲区可以替代AOF重写缓冲区吗
      • AOF相关配置
      • 写后日志
    • 混合持久化
    • 如何选择合适的持久化方式

在现今的数据驱动世界中,数据持久化成为了一项至关重要的任务。它不仅需要保证数据的安全,还要提供快速读写的功能。

对于许多现代化应用程序和服务来说,Redis被广泛使用作为一个高性能的键值存储系统。Redis以其卓越的性能和灵活性赢得了开发者们的青睐。然而,这些优点都离不开它强大的持久化机制。

通过本文,我们将深入探讨Redis的持久化策略,包括RDB(Redis DataBase)快照和AOF(Append Only File)日志,并解析如何根据自己的业务需求选择合适的持久化方案。

Redis持久化介绍

你也许会问,为什么需要持久化呢?因为Redis作为一款内存数据库,在进程异常退出或服务器断电之后,所有的数据都将消失。如果没有持久化功能,无法保证数据的持久性,那么这样的数据库还有什么用呢?

Redis持久化分为两种:「RDB(Redis DataBase)」和「AOF(Append Only File)」。

RDB是指将Redis内存中的数据定期写入磁盘上的一个快照文件中,而AOF则是以追加的方式记录Redis执行的每一条写命令。

你也可以同时开启两种持久化方式,在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始的数据。

接下来,我们将分别介绍RDB和AOF的实现原理。

RDB原理

RDB是Redis默认的持久化方式,它将Redis在内存中的数据定期写入到硬盘中,生成一个快照文件。快照文件是一个二进制文件,包含了Redis在某个时间点的所有数据。

RDB的优点是快速简单,适用于大规模数据备份和恢复。但是,RDB也有缺点,例如数据可能会丢失,因为Redis只会在指定的时间点生成快照文件。如果在快照文件生成之后,但在下一次快照文件生成之前服务器宕机,那么这期间的数据就会丢失

由于RDB文件是以二进制格式保存的,因此它非常紧凑,并且在Redis重启时可以迅速地加载数据。相比于AOF,RDB文件一般会更小。

RDB持久化有两种方式:手动自动

手动方式通过SAVE命令或BGSAVE命令进行:

  • SAVE命令会阻塞Redis服务器,直到快照文件生成完成。
  • BGSAVE命令会Fork一个子进程(注意是子进程,不是子线程)在后台生成快照文件,不会阻塞Redis服务器。

自动方式则是在配置文件中设置, 让它在**“ N 秒内数据集至少有 M 个改动”**这一条件被满足时, 自动保存一次数据集。

比如说,以下设置会让 Redis 在满足 “10秒内有至少100 个键被改动” 这一条件时, 自动保存一次数据集。

save 10 100

Fork函数与写时复制

在 Redis 中,Fork 函数被用于创建子进程。Redis 的使用场景中通常有大量的读操作和较少的写操作,而 Fork 函数可以利用 Linux 操作系统的写时复制(Copy On Write,即 COW)机制,让父子进程共享内存,从而减少内存占用,并且避免了没有必要的数据复制。

我们可以使用 Linux下的 man fork 命令来查看下Fork函数的说明文档。

翻译如下:

在Linux下,fork()是使用写时复制的页实现的,所以它唯一的代价是复制父进程的页表以及为子进程创建独特的任务结构所需的时间和内存。

简单来说就是 fork()函数会复制父进程的地址空间到子进程中,复制的是指针,而不是数据,所以速度很快。

在 Redis 中,当执行 RDB 持久化操作时,Redis 会调用 fork 函数创建子进程,然后由子进程负责将数据写入到磁盘中。为了避免父子进程同时对内存中的数据进行修改导致数据不一致。Redis 会启用写时复制机制。

这样,当父进程修改内存中的数据时, Linux 内核会将该部分内存复制一份给子进程使用,从而保证父子进程间的数据互相独立。

示意图如下:

当没有发生写的时候,子进程和父进程指向地址是一样的,发生写的时候,就会拷贝出一块新的内存区域,实现父子进程隔离。

通过使用 fork 函数和写时复制机制,Redis 可以高效地执行 RDB 持久化操作,并且不会对 Redis 运行过程中的性能造成太大的影响。同时,这种方式也提供了一种简单有效的机制来保护 Redis 数据的一致性和可靠性。

不过,需要注意的是:

fork的这个过程主进程是阻塞的,fork完之后不阻塞。RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求,数据集很大的时候,fork过程可能会持续数秒。

可能会因为数据量大而导致主进程长时间被挂起,造成Redis服务不可用。因此,在设计时应尽可能减少数据量或者优化fork的调用频率。

关于写时复制的思考

上述写时复制流程貌似有个问题:

比如,有个键值对 k1 a 。此时Redis正在bgsave。这时客户端发来一个请求,主进程发生写操作set k1 b,由于写时复制,此时子进程里k1的值还是a。最终持久化的也是a。

为什么不直接持久化新值而持久化旧值?写时复制的意义是什么?

基于上面的问题,可以给出的解释主要有两点:

  1. 其实Redis为了性能考虑,内存的持久化是一个顺序写的操作。子进程备份RDB是一个顺序写的过程,如果主进程的所有写入请求都随时记录到RDB文件中,那么理论更新的key可能在任何位置出现,就会变为随机写,性能低。
  2. 其次如果主进程一直在写入更新key的话,那么这次RDB备份一直都在写主进程写入的新值,永远不会停止。

RDB相关配置

以下是一些RDB的相关参数配置:

  • save:指定 RDB 持久化操作的条件。当 Redis 的数据发生变化,并且经过指定的时间(seconds)和变化次数(changes)后,Redis 会自动执行一次 RDB 操作。例如,save 3600 10000 表示如果 Redis 的数据在一个小时内发生了至少 10000 次修改,那么 Redis 将执行一次 RDB 操作。

  • stop-writes-on-bgsave-error:指定在 RDB 持久化过程中如果出现错误是否停止写入操作。如果设置为 yes,当 Redis 在执行 RDB 操作时遇到错误时,Redis 将停止接受写入操作;如果设置为 no,Redis 将继续接受写入操作。

  • rdbcompression:指定是否对 RDB 文件进行压缩。如果设置为 yes,Redis 会在生成 RDB 文件时对其进行压缩,从而减少磁盘占用空间;如果设置为 no,Redis 不会对生成的 RDB 文件进行压缩。

  • rdbchecksum:指定是否对 RDB 文件进行校验和计算。如果设置为 yes,在保存 RDB 文件时,Redis 会计算一个 CRC64 校验和并将其追加到 RDB 文件的末尾;在加载 RDB 文件时,Redis 会对文件进行校验和验证,以确保文件没有受到损坏或篡改。

  • replica-serve-stale-data:这是 Redis 4.0 中新增的一个配置项,用于指定复制节点在与主节点断开连接后是否继续向客户端提旧数据。当设置为 yes 时,在复制节点与主节点断开连接后,该节点将继续向客户端提供旧数据,直到重新连接上主节点并且同步完全新的数据为止;当设置为 no 时,复制节点会立即停止向客户端提供数据,并且等待重新连接上主节点并同步数据。需要注意的是,当 replica-serve-stale-data 设置为 yes 时,可能会存在一定的数据不一致性问题,因此建议仅在特定场景下使用。

  • repl-diskless-sync:这是 Redis 2.8 中引入的一个配置项,用于指定复制节点在进行初次全量同步(即从主节点获取全部数据)时是否采用无盘同步方式。当设置为 yes 时,复制节点将通过网络直接获取主节点的数据,并且不会将数据存储到本地磁盘中;当设置为 no 时,复制节点将先将主节点的数据保存到本地磁盘中,然后再进行同步操作。采用无盘同步方式可以避免磁盘 IO 操作对系统性能的影响,但同时也会增加网络负载和内存占用。因此,应该根据具体的场景和需求选择合适的同步方式

AOF原理

AOF持久化是按照Redis的写命令顺序将写命令追加到磁盘文件的末尾。AOF是一种基于日志的持久化方式,它保存了Redis服务器所有写入操作的日志记录,以保证数据的持久性、可靠性和完整性。

AOF持久化技术的核心思想是将Redis服务器执行的所有写命令追加到一个文件中。当Redis服务器重新启动时,可以通过重新执行AOF文件来恢复服务器的状态。

AOF有个比较好的优势是可以恢复误操作。

举个例子,如果你不小心执行了 FLUSHALL 命令,导致数据被误删了 ,但只要 AOF 文件未被重写,那么只要停止服务器,移除 AOF 文件末尾的 FLUSHALL 命令,并重启 Redis ,就可以将数据集恢复到 FLUSHALL 执行之前的状态。

AOF持久化配置

Redis的AOF持久化配置频率可通过appendfsync 参数进行控制。该参数有以下三个选项:

  • always:每次有数据修改都立即写入磁盘,是最安全的选项。
  • everysec:每秒钟写入一次,性能和安全之间做了一个平衡。
  • no:从不主动写入,完全依靠操作系统自身的缓存机制来决定何时将数据写入磁盘。

默认情况下,Redis的appendfsync参数设置为everysec。如果需要提高持久化安全性,可以将其改为always,如果更关注性能,则可以将其改为no。但是需要注意的是,使用no可能会导致数据丢失的风险,建议在应用场景允许的情况下谨慎使用。

AOF文件解读

一个简单的AOF文件示例如下:

其中:

  • *号:表示参数个数,后面紧跟着参数的长度和值。
  • $号:表示参数长度,后面紧跟着参数的值。

实际上AOF文件中保存的所有命令都遵循相同的格式,即以*开头表示参数个数,$开头表示参数长度,其后紧跟着参数的值。

AOF文件修复

服务器可能在程序正在对 AOF 文件进行写入时停机,造成AOF 文件损坏。

发生这种情况时,可以使用 Redis 自带的 redis-check-aof 程序,对 AOF 文件进行修复,命令如下:

$ redis-check-aof –fix

AOF重写

Redis的AOF重写机制指的是将AOF文件中的冗余命令删除,以减小AOF文件的大小并提高读写性能的过程。

Redis的AOF重写机制采用了类似于复制的方式,首先将内存中的数据快照保存到一个临时文件中,然后遍历这个临时文件,只保留最终状态的命令,生成新的AOF文件。

具体来说,Redis执行AOF重写可以分为以下几个步骤:

  1. 开始AOF重写过程,向客户端返回一个提示信息。
  2. 创建一个临时文件,并将当前数据库中的键值对写入到临时文件中。
  3. 在创建的临时文件中将所有的写命令都转换成Redis内部的表示格式,即使用一系列的Redis命令来表示一个操作,例如使用SET命令来表示对某个键进行赋值操作。
  4. 对临时文件进行压缩,去掉多余的空格和换行符等,减小文件体积。
  5. 将压缩后的内容写入到新的AOF文件中。
  6. 停止写入命令到旧的AOF文件,并将新的AOF文件的文件名替换为旧的AOF文件的文件名。
  7. 结束AOF重写过程,并向客户端发送完成提示信息。

通过AOF重写机制,Redis可以在不停止服务的情况下减小AOF文件的大小,提高读写性能,同时也可以保证数据的一致性。

Redis提供了手动触发AOF重写的命令 BGREWRITEAOF 。可以在Redis的客户端中执行该命令来启动AOF重写过程。Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令,到了 Redis 2.4 则可以自动触发 AOF 重写。

具体操作步骤如下:

  1. 打开redis-cli命令行工具,连接到Redis服务。

  2. 执行BGREWRITEAOF命令,启动AOF重写过程。

    $ redis-cli
    127.0.0.1:6379> BGREWRITEAOF
    
  3. Redis会返回一个后台任务的ID,表示AOF重写任务已经开始。

    127.0.0.1:6379> BGREWRITEAOF
    Background append only file rewriting started by pid 1234
    
  4. 可以使用 INFO PERSISTENCE 命令查看当前AOF文件的大小和重写过程的状态,等待重写完成即可。

    127.0.0.1:6379> INFO PERSISTENCE
    # Persistence
    aof_enabled:1
    aof_rewrite_in_progress:1
    aof_rewrite_scheduled:0
    aof_last_rewrite_time_sec:0
    aof_current_rewrite_time_sec:14
    aof_last_bgrewrite_status:ok
    aof_last_write_status:ok
    

需要注意的是,执行BGREWRITEAOF命令可能会占用较多的CPU和内存资源,因此在生产环境中需要谨慎使用,并确保有足够的系统资源支持。

同时,即使手动触发AOF重写,Redis也会在满足一定条件时自动触发AOF重写,以保证AOF文件的大小和性能。

需要注意的是:

在版本号大于等于 2.4 的 Redis 中,BGSAVE 执行的过程中,不可以执行 BGREWRITEAOF 。反过来说,在 BGREWRITEAOF 执行的过程中,也不可以执行 BGSAVE。目的是防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。

AOF缓冲区与AOF重写缓存区

在Redis中,尽管「AOF缓冲区」和「AOF重写缓冲区」的名称相似,但它们实际上是两个不同的概念。

AOF缓冲区是一个用于暂存需要写入AOF文件的命令的缓冲区。在Redis处理客户端发来的写命令时,如果开启了AOF持久化功能,则该命令将被先写入到AOF缓冲区。AOF缓冲区中的内容通过配置的规则持久化到磁盘上。持久化规则可以通过配置项appendfsync来调整。

AOF重写缓冲区是一个用于执行AOF文件的重写操作的缓冲区。AOF重写操作是一种将现有AOF文件重写成最小化的新AOF文件的操作。AOF重写操作的目的是减少AOF文件的大小,同时加快恢复速度。AOF重写缓存区在AOF重写时开始启用,Redis服务器主进程在执行完写命令之后,会同时将这个写命令追加到AOF缓冲区和AOF重写缓冲区

示意图如下:

AOF缓冲区可以替代AOF重写缓冲区吗

AOF缓冲区不可以替代AOF重写缓冲区。

原因是AOF重写缓冲区记录的是从重写开始后的所有需要重写的命令,而AOF缓冲区可能只记录了部分的命令(如果写回的话,AOF缓存区的数据就会失效被丢失,因而只会保存一部分的命令,而AOF重写缓存区不会)

AOF缓冲区主要是Redis用来解决主进程执行命令速度与磁盘写入速度不同步所设置的,通过AOF缓冲区可以有效地避免频繁对硬盘进行读写,进而提升性能。Redis在AOF持久化的时候,会先把命令写入到AOF缓冲区,然后通过写回策略来写入硬盘AOF文件。

AOF相关配置

在 Redis 的配置文件 redis.conf 中,可以通过以下配置项来设置 AOF 相关参数:

  • appendonly:该配置项用于开启或关闭 AOF,默认为关闭。若开启了 AOF,Redis 会在每次执行写命令时,将命令追加到 AOF 文件末尾。

  • appendfilename:用于设置 AOF 文件名,默认为 appendonly.aof。

  • appendfsync:该配置项用于设置 AOF 的同步机制。有三种可选值:

    • always:表示每个写命令都要同步到磁盘,安全性最高,但是性能较差。
    • everysec:表示每秒同步一次,是默认选项,既能保证数据安全,又具有较好的性能。
    • no:表示不进行同步,而是由操作系统决定何时将缓冲区中的数据同步到磁盘上,性能最好,但是安全性较低。
  • auto-aof-rewrite-percentageauto-aof-rewrite-min-size:这两个配置项用于设置 AOF 重写规则。当 AOF 文件大小超过 auto-aof-rewrite-min-size 设置的值,并且 AOF 文件增长率达到 auto-aof-rewrite-percentage 所定义的百分比时,Redis 会启动 AOF 重写操作。

    auto-aof-rewrite-percentage默认值为100,以及`auto-aof-rewrite-min-size默认值为64mb,也就是说默认Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发

  • aof-use-rdb-preamble:Redis 4版本新特性,混合持久化。AOF重写期间是否开启增量式同步,该配置项在AOF重写期间是否使用RDB文件内容。默认是no,如果设置为yes,在AOF文件头加入一个RDB文件的内容,可以尽可能的减小AOF文件大小,同时也方便恢复数据。

写后日志

我们比较熟悉的是数据库的写前日志(Write Ahead Log,WAL),也就是说,在实际写数据前,先把修改的数据记到日志文件中,以便故障时进行恢复。

不过,AOF 日志却正好相反,它是写后日志,“写后”的意思是 Redis 是先执行命令,把数据写入内存,然后才记录日志

为什么要这样设计?

其实为了避免额外的检查开销,Redis 在向 AOF 里面记录日志的时候,并不会先去对这些命令进行语法检查。所以,如果先记日志再执行命令的话,日志中就有可能记录了错误的命令,Redis 在使用日志恢复数据时,就可能会出错。

而写后日志这种方式,就是先让系统执行命令,只有命令能执行成功,才会被记录到日志中,否则,系统就会直接向客户端报错。所以,Redis 使用写后日志这一方式的一大好处是,可以避免出现记录错误命令的情况。

除此之外,AOF 写后日志还有一个好处:它是在命令执行后才记录日志,所以并不会阻塞当前的写操作

不过,写后日志也有两个潜在的风险:

  • 首先,如果刚执行完一个命令,还没有来得及记日志就宕机了,那么这个命令和相应的数据就有丢失的风险。如果此时 Redis 是用作缓存,还可以从后端数据库重新读入数据进行恢复,但是,如果 Redis 是直接用作数据库的话,此时,因为命令没有记入日志,所以就无法用日志进行恢复了。
  • 其次,AOF 虽然避免了对当前命令的阻塞,但可能会给下一个操作带来阻塞风险。这是因为,AOF 日志也是在主线程中执行的,如果在把日志文件写入磁盘时,磁盘写压力大,就会导致写盘很慢,进而导致后续的操作也无法执行了。

混合持久化

在过去, Redis 用户通常会因为 RDB 持久化和 AOF 持久化之间不同的优缺点而陷入两难的选择当中:

  • RDB 持久化能够快速地储存和恢复数据,但是在服务器停机时可能会丢失大量数据。
  • AOF 持久化能够有效地提高数据的安全性,但是在储存和恢复数据方面却要耗费大量的时间。

为了让用户能够同时拥有上述两种持久化的优点, Redis 4.0 推出了一个“鱼和熊掌兼得”的持久化方案 —— RDB-AOF 混合持久化

这种持久化能够通过 AOF 重写操作创建出一个同时包含 RDB 数据和 AOF 数据的 AOF 文件, 其中 RDB 数据位于 AOF 文件的开头, 它们储存了服务器开始执行重写操作时的数据库状态。至于那些在重写操作执行之后执行的 Redis 命令, 则会继续以 AOF 格式追加到 AOF 文件的末尾, 也即是 RDB 数据之后。

也就是说当开启混合持久化之后,AOF文件中的内容:前半部分是二进制的RDB内容,后面跟着AOF增加的数据,AOF位于两次RDB之间

格式会类似下面这样:

(二进制)RDB
 AOF
(二进制)RDB

在目前版本中, RDB-AOF 混合持久化功能默认是处于关闭状态的, 为了启用该功能, 用户不仅需要开启 AOF 持久化功能, 还需要将 aof-use-rdb-preamble 选项的值设置为 true。

appendonly yes
aof-use-rdb-preamble yes

如何选择合适的持久化方式

当你想选择适合你的应用程序的持久化方式时,你需要考虑以下两个因素:

  1. 数据的实时性和一致性:如果对数据的实时性和一致性有很高的要求,则AOF可能是更好的选择。

    如果对数据的实时性和一致性要求不太高,并且希望能快速地加载数据并减少磁盘空间的使用,那么RDB可能更适合你的应用程序。因为RDB文件是二进制格式的,结构非常紧凑,所以在Redis重启时可以迅速地加载数据。

  2. Redis的性能需求:如果对Redis的性能有很高的要求,那么关闭持久化功能也是一个选择。因为持久化功能可能会影响Redis的性能,但是一般不建议这么做。

本篇文章到这就结束了,最后我们来做个小总结:

我们要意识到Redis的持久化机制扮演着至关重要的角色。RDB和AOF两种主要的持久化方式各有其优势和使用场景

RDB通过提供特定时间点的数据快照,对于灾难恢复是非常有效的;而AOF则通过记录每个写入操作,提供了更好的数据持久性保证。然而,它们也有各自的局限性,这就需要根据实际需求来权衡选用哪种持久化方式。

最后,不可忽视的是,在选择合适的持久化策略时,我们还应考虑如何平衡内存使用、磁盘使用、性能与持久性等多个因素。只有对Redis持久化的深入理解,我们才能充分利用其强大的功能,以满足各种业务需求。

希望这篇文章能够给你带来收获和思考,谢谢。

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

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

相关文章

机器学习之自训练协同训练

前言 监督学习往往需要大量的标注数据, 而标注数据的成本比较高 . 因此 , 利用大量的无标注数据来提高监督学习的效果有着十分重要的意义. 这种利用少量标注数据和大量无标注数据进行学习的方式称为 半监督学习 ( Semi…

Java 序列化和反序列化为什么要实现 Serializable 接口?

序列化和反序列化 序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. 什么时候需要用到序列化和反序列化呢或者对象序列化的两种用途… : (1) 对象持久化:把对象的…

NSSCTF做题(8)

[SWPUCTF 2022 新生赛]js_sign 看到了js代码 有一个base64编码,解密 最后发现这是一个加密方式 去掉空格之后得到了flag NSSCTF{youfindflagbytapcode} [MoeCTF 2022]baby_file 提示说有一个秘密看看你能不能找到 输入?filesecret 出现报错 输入php伪协议读取i…

Simulink仿真之离散系统

最近,为了完成课程作业,需要用到Simulink验证数字控制器的合理性。题目如下所示。 其实这道题在胡寿松老师的《自动控制原理(第七版)》的364页有答案。 这里给出数字控制器的脉冲传递函数为 ​​​​​​​ ​​​​​​​…

【22】c++设计模式——>外观模式

外观模式定义 为复杂系统提供一个简化接口&#xff0c;它通过创建一个高层接口(外观)&#xff0c;将多个子系统的复杂操作封装起来&#xff0c;以便客户端更容易使用。 简单实现 #include<iostream>// 子系统类 class SubsystemA { public:void operationA() {std::co…

经典循环命题:百钱百鸡

翁五钱一只&#xff0c;母三钱&#xff0c;小鸡三只一钱&#xff1b;百钱百鸡百鸡花百钱。 (本笔记适合能熟练应用for循环、会使if条件分支语句、能格式化字符输出的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a…

自定义表单工具好用的优点是什么?

如果想提升办公效率&#xff0c;那么就离不开低代码技术平台了。它的轻量级、易掌握、易操作、简洁简便等优势特点深得很多领域客户朋友的喜爱。目前&#xff0c;IBPS开发平台在通信业、制造业、医疗、高校等很多行业中得到了客户的肯定和喜爱&#xff0c;推广价值高&#xff0…

懒人福利:不用动脑就能制作电子画册

对于很多企业来说&#xff0c;想要快速把自己的活动大面积的宣传出去&#xff0c;就要快人一步提前制作电子版画册&#xff0c;通过网络推送出去&#xff0c;让大众及时了解。如何制作电子版画册呢&#xff1f; 我发现了一个懒人福利&#xff01;就是FLBOOK &#xff0c;它简单…

学习函数式编程、可变参数及 defer - GO语言从入门到实战

函数是⼀等公⺠、学习函数式编程、可变参数及 defer - GO语言从入门到实战 函数是⼀等公⺠ 在Go语言中&#xff0c;函数可以分配给一个变量&#xff0c;可以作为函数的参数&#xff0c;也可以作为函数的返回值。这样的行为就可以理解为函数属于一等公民。 与其他主要编程语⾔…

Nodejs内置模块process

文章目录 内置模块process写在前面1. arch()2. cwd()3. argv4. memoryUsage()5. exit()6. kill()7. env【最常用】 内置模块process 写在前面 process是Nodejs操作当前进程和控制当前进程的API&#xff0c;并且是挂载到globalThis下面的全局API。 下面是process的一些常用AP…

linux开发板中的数据存储和读取操作

问题&#xff1a;MQTT远程下发的参数存储在本地linux开发板&#xff0c;开发板依据该参数执行相应功能&#xff0c;当开发板重新上电时依然能继续执行该功能 解决方式&#xff1a; 在linux板中写一个标识并存储为文件&#xff0c;依据读取的文件标识执行相应的功能 1)打开文…

【2023】M1/M2 Mac 导入Flac音频到Pr的终极解决方案

介绍 原作者链接&#xff1a;https://github.com/fnordware/AdobeOgg 很早之前就发现了这个插件&#xff0c;超级好用&#xff0c;在windows上完全没有问题&#xff0c;可惜移植到mac就不行了&#xff08;然后我给作者发了一个Issue&#xff0c;后来就有大佬把m1的编译出来了&…

Ai绘画描述词 关键词大全 真人美女 二次元卡通美女 国漫动漫效果

超好看的二次元动漫美少年 都是用Ai工具直接绘画生成出来的。 还有真人绘画&#xff0c;效果也很逼真 还有更多的场景效果 寂静天空素材 做抖音 短视频 精美的图片素材都是通过Ai绘画的 但是绘画需要关键词去描述场景&#xff0c;Ai才能自动根据场景描述词生成出来图片。 如何…

【Java学习之道】接口与抽象类

引言 现在我们来聊聊接口和抽象类。在Java中&#xff0c;接口和抽象类是实现OOP的重要工具&#xff0c;它们允许我们定义规范和行为&#xff0c;让代码更具灵活性和可扩展性。这一节&#xff0c;我们就来详细探讨一下这两个神奇的功能。 一、接口 接口是一个完全抽象的类&am…

【LeetCode高频SQL50题-基础版】打卡第6天:第31~35题

文章目录 【LeetCode高频SQL50题-基础版】打卡第6天&#xff1a;第31~35题⛅前言员工的直属部门&#x1f512;题目&#x1f511;题解 判断三角形&#x1f512;题目&#x1f511;题解 连续出现的数字&#x1f512;题目&#x1f511;题解 指定日期的产品价格&#x1f512;题目&am…

通讯网关软件021——利用CommGate X2OPC实现OPC客户端访问Modbus设备

本文介绍利用CommGate X2OPC实现OPC客户端连接Modbus设备。CommGate X2OPC是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;SCADA系统上位机、PLC、设备具备Modbus通讯接口&#xff0c;上位机…

工程物料管理信息化建设(十二)——关于工程物料管理系统最后的思考

目录 1 功能回顾1.1 MTO模块1.2 请购模块1.3 采购模块1.4 催交模块1.5 现场管理模块1.6 数据分析和看板模块1.7 其它模块 2 最后几个问题2.1 按管线发料和直接发料重叠2.2 YHA 材料编码的唯一性问题2.3 “合同量单-箱单-入库单” 数据映射 3 关于未来的思考3.1 三个专业之间的关…

单点接地、多点接地、混合接地

有三种基本的信号接地方式:浮地、单点接地、多点接地。 浮地&#xff1a;目的是使电路或设备与公共地线可能引起环流的公共导线隔离起来&#xff0c;浮地还使不同电位的电路之间配合变得容易。缺点&#xff1a;容易出现静电积累引起强烈的静电放电。折中方案&#xff1a;接入泄…

基于小波变换的分形信号r指数求解算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................... %通过功率谱密度曲线…

Java数据结构第十九章、手撕图+最小生成树

一、图的基本概念 图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E),其中:顶点集合V = {x|x属于某个数据对象集}是有穷非空集合;E = {(x,y)|x,y属于V}或者E = {<x, y>|x,y属于V && Path(x, y)}是顶点间关系的有穷集合,也叫做边的集合。(x, y)表…