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

高性能分布式缓存Redis-数据管理与性能提升之道

一、持久化原理

Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置

既然redis的数据可以保存在磁盘上,那么这个流程是什么样的呢?

(1)客户端向服务端发送写操作(数据在客户端的内存中)。

(2)数据库服务端接收到写请求的数据(数据在服务端的内存中)。

(3)服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。

(4)操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。

(5)磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。

前三步是由redis完成的,后两步是由OS完成的

这5个过程是在理想条件下一个正常的保存流程,但是在大多数情况下,我们的机器等等都会有各种各样的故障,这里划分了两种情况

(1)Redis数据库发生故障,只要在上面的第三步执行完毕,那么就可以持久化保存,剩下的两步由操作系统替我们完成。

(2)操作系统发生故障,必须上面5步都完成才可以。

为应对以上5步操作,redis提供了两种不同的持久化方式:RDB(Redis DataBase)和AOF(Append Only File)

RDB和AOF都可以在redis.conf进行相关配置

RDB详解

RDB是什么?

在指定的时间间隔能对你的数据进行快照存储。是将当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化),保存的文件后缀是rdb;当Redis重新启动时,可以读取快照文件恢复数据。

RDB的触发及其原理

既然RDB是在指定时间间隔进行快照存储,那么这个时间间隔到底是多久呢,多久触发一次RDB操作呢?这就要聊一聊他的触发原理了。

在Redis中RDB持久化的触发分为两种:指令手动触发和 redis.conf 配置自动触发

指令手动触发
主要有两个命令,save命令和bgsave命令都可以生成RDB文件

save:会阻塞当前Redis服务器,直到RDB文件创建完毕为止,线上应该禁止使用。

在接收到save命令后,redis服务器的主进程就会读取内存和生成RDB文件,这两件事合为RDB操作,由主进程实现,所以主进程干这个事去了,就无法处理新的redis客户端的请求了,就会阻塞住。

bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。

进行fork操作后,会利用操作系统的“写时复制”(Copy-On-Write,COW)机制:

(1)、执行bgsave命令的时候,会通过fork()创建子进程,此时子进程和父进程是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是同一个

这时候,共享同一片物理内存,然后直接读取,生成临时rdb文件,生成完毕,再覆盖之前的rdb文件,就结束bgsave的流程。但是你会有一个疑问, 都是共享一片内存,那父进程这时候收到别的redis客户端请求需要写数据,那么不同样会操作同一片内存空间吗,就会造成错误。

(2)、这时就有了写时复制,只有在修改内存数据的情况时,物理内存才会被复制一份。然后各个进程各自读各自的内存,互不影响

redis.conf配置自动触发

根据我们的 save m n 配置规则自动触发;redis.conf如下配置

# 时间策略
save 900 1 # 表示900 秒内如果至少有 1 个 key 的值变化,则触发RDB
save 300 10 # 表示300 秒内如果至少有 10 个 key 的值变化,则触发RDB
save 60 10000  # 表示60 秒内如果至少有 10000 个 key 的值变化,则触发RDB# 文件名称
dbfilename dump.rdb# 文件保存路径
dir /home/work/app/redis/data/# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes# 是否压缩
rdbcompression yes# 导入时是否检查
rdbchecksum yes

配置其实非常简单,这里说一下持久化的时间策略具体是什么意思。

  • save 900 1 表示900s内如果有1条是写入命令,就触发产生一次快照,可以理解为就进行一次备份
  • save 300 10 表示300s内有10条写入,就产生快照

其他一些自动触发机制:

  • 从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 bgsave;
  • 执行 debug reload 时;
  • 执行 shutdown时,如果没有开启aof,也会触发。

面试题:RDB有什么缺点?

  • 数据丢失风险:RDB 是周期性持久化,假设时间间隔为5s,第1s进行更新,第4s发送宕机,本来该第5s发送下一次快照更新,但是由于宕机,第1s和第4s之间的更新操作就丢失了,也就是说在上次快照和故障之间的数据会丢失。对于高可用需求的场景,AOF可能更合适。

  • 资源开销大:由于RDB是进行全量更新,所以时间间隔不能设置太短,否则导致频繁生成快照执行fork命令等等,RDB 持久化使用 fork 生成子进程,并且占用大量内存。对于大型数据集,频繁的 RDB 持久化可能对性能产生负面影响。

  • 执行时间较长:RDB 的生成需要将整个内存快照写入磁盘,对于大量数据会消耗较长时间。

AOF详解

AOF是什么

AOF通过记录每次对服务器写的操作(命令),当服务器重启的时候会重新执行这些命令来恢复原始的数据。

特点:

  • 1. 以日志的形式来记录用户请求的写操作,读操作不会记录,因为写操作才会存储
  • 2. 文件以追加的形式而不是修改的形式
  • 3. redis的aof恢复其实就是通过一个伪客户端把追加的文件从开始到结尾读取 执行 写操作

如何在redis.conf开启 AOF

# 可以通过修改redis.conf配置文件中的appendonly参数开启
appendonly yes# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的。 
dir .# 默认的文件名是appendonly.aof,可以通过appendfilename参数修改 
appendfilename appendonly.aof

AOF实现流程

如上图所示,AOF 持久化功能的实现可以分为命令追加( append )、文件写入( write )、文件同步( sync )、文件重写(rewrite)和重启加载(load)。其流程如下:

  • 所有的写命令会追加到 AOF 缓冲中。
  • AOF 缓冲区根据对应的策略向硬盘进行同步操作。
  • 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  • 当 Redis 重启时,可以加载 AOF 文件进行数据恢复。

接下来我们分别介绍这几个部分

命令追加

当 AOF 持久化功能处于打开状态时,Redis 在执行完一个写命令之后,会以协议格式(也就是RESP,即Redis 客户端和服务器交互的通信协议 )将被执行的写命令追加到 Redis 服务端维护的 AOF 缓冲区末尾。

文件写入&同步

Redis 每次结束一个事件循环之前(写事件),它都会调用 flushAppendOnlyFile 函数,判断是否需要将 AOF 缓冲区中的内容写入和同步到 AOF 文件中
flushAppendOnlyFile 函数的行为由 redis.conf 配置中的 appendfsync 选项的值来决定。该选项有
三个可选值,分别是 always everysec no
  • always :每执行一个命令保存一次 高消耗,最安全
  • everysec :每一秒钟保存一次
  • no :只写入 不保存, AOF Redis 关闭时执行,由操作系统触发刷新文件到磁盘

 三个配置项优缺点分析

大家根据自己的业务场景进行选择:

  • 如果想要高性能,就选No
  • 如果想要高可靠,就选always
  • 如果允许数据丢失一点,但又想性能高,就选择Everysec

重启加载(数据恢复)

本质就是读取aof文件,进行命令执行,数据恢复

以上是数据恢复的大致流程

详细流程剖析如下:

  • 创建一个不带网络连接的的伪客户端( fake client),因为 Redis 的命令只能在客户端上下文中执行,而载入 AOF 文件时所使用的的命令直接来源于 AOF 文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行 AOF 文件保存的写命令,伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样的。
  • 从 AOF 文件中分析并取出一条写命令。
  • 使用伪客户端执行被读出的写命令。
  • 一直执行步骤 2 和步骤3,直到 AOF 文件中的所有写命令都被处理完毕为止。

AOF文件重写(rewrite)

我们先来分析一下,AOF采用文件追加方式,随着Redis长时间运行,会产生什么问题?

只有重启才会进行数据恢复,那么恢复之后,才可以clear掉这个AOF文件,但是在重启之前,redis长时间运行,会导致这个AOF文件越来越大。

为了解决 AOF 文件体积膨胀的问题,Redis 提供了 AOF 文件重写( rewrite) 策略

AOF文件重写,并不是更新原来的AOF文件,而是创建新的AOF文件,替换旧的AOF文件

如上图所示,重写前要记录名为 list 的键的状态,AOF 文件要保存五条命令,而重写后,则只需要保存一条命令。
AOF 文件重写并不需要对现有的 AOF 文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的数据库状态来实现的。首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是 AOF 重写功能的实现原理。 

如何触发AOF文件重写

  • 手动调用 bgrewriteaof 命令,如果当前有正在运行的 rewrite 子进程,则本次rewrite 会推迟执行,否则,直接触发一次 rewrite
  • 自动触发 就是根据配置规则来触发
# 重写机制:避免文件越来越大,自动优化压缩指令,会fork一个新的进程去完成重写动作,新进程里的内存数据会被重写,此时旧的aof文件不会被读取使用
# 当前AOF文件的大小是上次AOF大小的100% 并且文件体积达到64m,满足两者则触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

接下来让我们探究一下AOF文件重写的原理吧!

文件重写原理

前面几步和我们RDB的流程差不多,我们不必多说,我们从fork完了之后开始讲起

fork会另开一个子进程,拷贝一份主进程的页表,然后就可以操作主进程对应的物理内存了,这时候子进程就开始进行重写操作(①扫描redis的内存数据②逐一的把内存数据的key-value转换成一条命令③再把命令记录到新的AOF文件中),如果说在子进程进行重写操作的期间,主进程又发生了数据的读写,那么子进程重写完了之后会向主进程发送一个信号,主进程把这个期间发生的数据读写命令添加到新的AOF文件中,最后再用新的AOF文件覆盖旧的AOF文件

在整个 AOF 后台重写过程中,只有信号处理函数执行时会对 Redis 主进程造成阻塞,在其他时候, AOF 后台重写都不会阻塞主进程。 

持久化优先级

思考一个问题:如果一台服务器上有既有RDB文件,又有AOF文件,该加载谁呢?

这里给出一个执行流程图

持久化原理总结

我们都知道RDB的快照、AOF的重写都需要fork,这是一个重量级操作,会对Redis造
成阻塞。因此为了不影响Redis主进程响应,我们需要尽可能降低阻塞。

  1. 降低fork的频率,比如可以手动来触发RDB生成快照、与AOF重写;
  2. 控制Redis最大使用内存,防止fork耗时过长;
  3. 使用更牛逼的硬件;
  4. 合理配置Linux的内存分配策略,避免因为物理内存不足导致fork失败

实际开发中该怎么做?

  • 1. 如果Redis中的数据并不是特别敏感或者可以通过其它方式重写生成数据,可以关闭持久化,如果
  • 丢失数据可以通过其它途径补回;
  • 2. 自己制定策略定期检查Redis的情况,然后可以手动触发备份、重写数据;
  • 3. 可以加入主从机器,利用一台从机器进行备份处理,其它机器正常响应客户端的命令;
  • 4. RDB持久化与AOF持久化可以同时存在,配合使用。

二、过期删除策略&内存淘汰策略

过期删除策略

如何设置过期时间

如何判定Key是否已经过期?(redis内部原理)

在redis内部,每当我们设置一个键的过期时间时,Redis就会将该键带上过期时间存放到一个过期字典中。过期字典的结构:

typedef struct redisDB {dict *dict;    //数据库键空间,存放着所有的键值对dict *expires; //键的过期时间
} redisDB;

当我们查询任意一个键时,Redis首先检查该键是否存在于过期字典(哈希表)中

  • 如果不在,则正常读取value
  • 如果存在,则会获取该key的过期时间,然后与当前系统时间进行比对,如果比系统时间大,那就没有过期,否则判定该key已过期

过期删除策略有哪些?

1、定时删除

在设置某个key 的过期时间同时,我们创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。

2、惰性删除

设置该key 过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

3、定期删除

每隔一段时间,我们就对一些key进行检查,删除里面过期的key。

面试题:那么redis当中是采取什么措施来进行过期删除的呢?

  • 惰性删除:每次访问一个键时,Redis 会检查该键是否过期(扫描过期字典,比对时间)。如果过期,则删除该键。删除了之后,再执行get命令肯定会报错呀

  • 定期删除:Redis 会定期以固定时间间隔扫描数据库中的一部分键,删除过期的键。它通常会检查每个数据库的 10% 键,并且随着时间推移,扫描比例会逐渐增大。

这样,Redis 既能保证键的过期及时清理,又能避免每次访问时都进行全量扫描。 

内存淘汰策略

Redis是基于内存的,所以肯定有上限,肯定也有瓶颈,当Redis的运行内存已经超过Redis设置的最大内存之后,则会使用内存淘汰策略删除符合条件的key,以此来保障Redis的继续运行

在redis.conf中,通过maxmemory <bytes>来设定最大内存

不设定该参数默认是无限制的,但是通常会设定其为物理内存的3/4

Redis内存淘汰策略有哪些?

1)noeviction(Redis3.0之后,默认的内存淘汰策略):
        它表示当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,则会触发 OOM,但是如果没用数据写入的话,只是单纯的查询或者删除操作的话,还是可以正常工作。

剩下7种:  LRU:最近最少使用     LFU:最不常用

  • allkeys-lru:对所有键使用 LRU 淘汰最近最少使用的键。
  • allkeys-lfu:对所有键使用 LFU 淘汰最不常用的键。
  • allkeys-random:随机淘汰任意键。
  • volatile-lru:对有过期时间的键使用 LRU。
  • volatile-lfu:对有过期时间的键使用 LFU。
  • volatile-random:随机淘汰有过期时间的键。
  • volatile-ttl:优先淘汰过期时间最接近的键。

LRU和LFU的区别 

LRU: 淘汰最久未使用的键。适合那些有时效性的数据,能让最近活跃的键优先保留。

Redis的 LRU 实现基于随机采样的近似 LRU 算法。在LRU的实现中,redis会给每个数据增加一个类似于时间戳的字段,Redis 并不记录每个键的访问顺序,而是通过定期从键空间中随机采样若干键,并根据其“上次使用时间”来淘汰其中最不常使用的键。这种方法能够在减少开销的前提下,接近实现 LRU 的效果。

LRU会导致缓存污染问题:特别是在访问模式中包含大量短时、随机访问的数据时。由于 LRU 会优先淘汰“最近最少使用”的数据,较少被访问的重要数据可能在频繁的短时访问数据引入时被替换掉。这样,重要的但低频率的数据可能被过早清除

LFU:淘汰使用频率最低的键。适用于访问频率具有稳定性的场景,因为它能识别出“冷”数据,并优先淘汰这些低频使用的键。所以能解决缓存污染问题:不会因像LRU算法的偶尔一次被访问被误认为是热点数据

在Redis中,实现LFU,是在LRU的基础上,将LRU的“时间戳字段(24bit)”拆分成两部分,前16bit表示数据的访问时间戳,后8bit表示数据的访问次数

当LFU策略筛选数据时,Redis会在候选集合中,根据数据LRU字段的后8bit选择访问次数最少的数据进行淘汰;当访问次数相同时,再根据LRU字段的前16bit值大小,选择访问时间最久远的数据进行淘汰。

三、性能压测

介绍一个工具,专门用来对redis进行压测,目前也是主流使用--------redis-benchmark

redis-benchmark工具来模拟 N 个客户端同时发出 M 个请求,可以便捷对服务器进行读写性能压测

以下是一些参数说明

序号选项描述默认值
1-h指定服务器主机名127.0.0.1
2-p指定服务器端口6379
3-s指定服务器 socket
4-c指定并发连接数50
5-n指定请求数10000
6-d以字节的形式指定 SET/GET 值的数据大小2
7-k1=keep alive 0=reconnect1
8-rSET/GET/INCR 使用随机 key, SADD 使用随机值
9-P通过管道传输 请求1
10-q仅显示 query/sec 值
11--csv以 CSV 格式输出
12*-l*(L 的小写字母)生成循环,永久执行测试
13-t仅运行以逗号分隔的测试命令列表。
14*-I*(i 的大写字母)Idle 模式。仅打开 N 个 idle 连接并等待。

示例:

相关文章:

高性能分布式缓存Redis-数据管理与性能提升之道

一、持久化原理 Redis是内存数据库&#xff0c;数据都是存储在内存中&#xff0c;为了避免进程退出导致数据的永久丢失&#xff0c;需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘&#xff1b;当下次Redis重启时&#xff0c;利用持久化文件实现数据恢复。除此…...

BO-CNN-LSTM回归预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多输入单输出回归预测

BO-CNN-LSTM回归预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多输入单输出回归预测 目录 BO-CNN-LSTM回归预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多输入单输出回归预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 …...

DataWind将字符串数组拆出多行的方法

摘要&#xff1a; 可视化建模中先将字符串split为array再用explode(array)即可 可视化建模 进入“可视化建模”页面 1.1 新建任务 如果团队内没有可视化建模任务。请点击“新建任务”&#xff0c;输入名称并确定。 1.2 建立数据连接 在左边栏中选择“数据连接”&#xff0c…...

try...catch 和then...catch的异同点分析

try…catch 和 then…catch 的异同点分析 在现代 JavaScript 编程中&#xff0c;异常处理和 Promise 的处理是非常常见的两种方式。try...catch 语句主要用于同步代码的异常处理&#xff0c;而 .then().catch() 是 Promise 中的异步处理方法。 1. 基础概念 1.1 try…catch …...

Mit6.S081-实验环境搭建

Mit6.S081-实验环境搭建 注&#xff1a;大家每次做一些操作的时候觉得不太保险就先把虚拟机克隆一份 前言 qemu&#xff08;quick emulator&#xff09;&#xff1a;这是一个模拟硬件环境的软件&#xff0c;利用它可以运行我们编译好的操作系统。 准备一个Linux系统&#xf…...

以太网交换安全:MAC地址漂移

一、什么是MAC地址漂移&#xff1f; MAC地址漂移是指设备上一个VLAN内有两个端口学习到同一个MAC地址&#xff0c;后学习到的MAC地址表项覆盖原MAC地址表项的现象。 MAC地址漂移的定义与现象 基本定义&#xff1a;MAC地址漂移发生在一个VLAN内的两个不同端口学习到相同的MAC地…...

STM32实现串口接收不定长数据

原理 STM32实现串口接收不定长数据&#xff0c;主要靠的就是串口空闲&#xff08;idle&#xff09;中断,此中断的触发条件与接收的字节数无关&#xff0c;只有当Rx引脚无后续数据进入时&#xff08;串口空闲时&#xff09;&#xff0c;认为这时候代表一个数据包接收完成了&…...

AAA 数据库事务隔离级别及死锁

目录 一、事务的四大特性&#xff08;ACID&#xff09; 1. 原子性(atomicity)&#xff1a; 2. 一致性(consistency)&#xff1a; 3. 隔离性(isolation)&#xff1a; 4. 持久性(durability)&#xff1a; 二、死锁的产生及解决方法 三、事务的四种隔离级别 0 .封锁协议 …...

外接数据库给streamlit等web APP带来的变化

之前我采用sreamlit制作了一个调查问卷的APP&#xff0c; 又使用MongoDB作为外部数据存储&#xff0c;隐约觉得外部数据库对于web APP具有多方面的意义&#xff0c;代表了web APP发展的趋势之一&#xff0c;似乎是作为对这种趋势的响应&#xff0c;streamlit官方近期开发了st.c…...

Gitpod: 我们正在离开 Kubernetes

原文&#xff1a;Christian Weichel - 2024.10.31 Kubernetes 似乎是构建远程、标准化和自动化开发环境的显而易见选择。我们也曾这样认为&#xff0c;并且花费了六年时间&#xff0c;致力于打造最受欢迎的云开发环境平台&#xff0c;并达到了互联网级的规模。我们的用户数量达…...

1.每日SQL----2024/11/7

题目&#xff1a; 计算用户次日留存率,即用户第二天继续登录的概率 表&#xff1a; iddevice_iddate121382024-05-03232142024-05-09332142024-06-15465432024-08-13523152024-08-13623152024-08-14723152024-08-15832142024-05-09932142024-08-151065432024-08-131123152024-…...

普通一本大二学生,软件工程,想考研985,想知道哪个大学的软件工程好,又不至于完全考不起的?

竞争难度适中&#xff1a;相较于顶尖985院校&#xff0c;重庆大学作为实力派985高校&#xff0c;其竞争烈度较为温和&#xff0c;考研难度适中偏易&#xff0c;为追求高性价比深造路径的考生提供了理想之选。 考试难度友好&#xff1a;重庆地区考研评分标准相对宽松&#xff0…...

「QT」几何数据类 之 QMatrix4x4 4x4矩阵类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…...

让Apache正确处理不同编码的文件避免中文乱码

安装了apache2.4.39以后&#xff0c;默认编码是UTF-8&#xff0c;不管你文件是什么编码&#xff0c;统统按这个来解析&#xff0c;因此 GB2312编码文件内的中文将显示为乱码。 <!doctype html> <html> <head><meta http-equiv"Content-Type" c…...

人员密集场所遇到突发火灾事故该如何应对

0引言 在繁华喧嚣的都市中&#xff0c;人员密集场所如购物中心、电影院、办公楼等&#xff0c;是人们日常生活不可或缺的一部分。然而&#xff0c;在这些看似繁华的背后&#xff0c;隐藏着不可忽视的安全隐患——火灾。火灾无情&#xff0c;往往在不经意间爆发&#xff0c;瞬间…...

使用QtWebEngine的Mac应用如何发布App Store

前言 因为QtWebEngine时第三方包,苹果并不直接支持进行App Store上签名和发布,所以构建和发布一个基于使用QtWebEngine的应用程序并不容易,这里我们对Qt 5.8稍微做一些修改,以便让我们的基于QtWeb引擎的应用程序并让签名能够得到苹果的许可。 QtWebEngine提供了C++和Qml的…...

微机原理与接口技术——中断系统与可编中断控制芯片8259A

目录 一、8259A 芯片介绍 二、8259A 的内部结构和引脚 三、8259A 的中断工作过程 四、8259A 的工作方式 五、8259A 的编程 六、外部中断服务程序 一、8259A 芯片介绍 Intel 8259A 是可编程中断控制器&#xff0c;可用于管理 Intel 8080/8085、8086/8088、80286/80386 的…...

【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期

目录 1. start() (1) start() 的性质 (2) start() 和 Thread类 的关系 2. 终止一个线程 (1)通过共享的标记结束线程 1. 通过共享的标记结束线程 2. 关于 lamda 表达式的“变量捕获” (2) 调用interrupt()方法 1. isInterrupted() 2. currentThread() …...

面试题分享11月7日

1、ThreadLocal 是什么 是 Java 中线程的本地方法变量&#xff0c;用来存储每个线程的私有数据&#xff0c;每个线程都有它的独立副本&#xff0c;相互隔离&#xff0c;互不影响 2、ThreadLocal 实现原理 每个 ThreadLocal 都有一个 ThreadLocalMap 对象&#xff0c;用来存储…...

数据结构_哈夫曼树及其应用

构造算法的例子 构造算法的实现 初始化&#xff0c;置权值 int i, m, s1, s2;m 2 * n - 1;for (i 1; i < m; i){HT[i].lch 0;HT[i].rch 0;HT[i].parent 0;}for (i 1; i < n; i){cin >> HT[i].weight;}合并结点 // 创建哈夫曼树for (i n 1; i < m; i){s1…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...