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

Redis解析

Redis解析

一、单线程模型

redis在io层面是多线程的,在数据处理层面是单线程的。
多线程一般用于:

  • 关闭连接
  • 删除/淘汰内存
  • 网络IO

1.1 io多路复用

redis使用nio(select、poll、epoll)的方式处理socket

  1. 主线程负责接收建立连接请求,获取socket,并放入等待队列中
  2. 主线程轮询将可读的socket分配给io线程
  3. 主线程阻塞等待io线程读取socket完成
  4. 主线程指向io线程读取和解析出来的redis请求命令
  5. 主线程阻塞等待io线程将指令执行结果回写回socket
  6. 主线程清空队列,等待客户端后续请求

Redis线程模型(接收请求并返回数据流程)

  1. 主线程接收请求,获取socket,放入队列
  2. 主线程通过nio获取可读的socket,分配给io线程 (1、2涉及到nio(select、poll、epoll,主流是epoll))
  3. io线程解析socket(读取数据并解析为redis命令),将解析后的请求放入请求队列
  4. 主线程从请求队列中读取请求,执行操作
  5. 主线程将执行结果放入特定的结果队列(每个IO线程对应一个队列)
  6. io线程将数据写入客户端socket的内核发送缓冲区,然后通过网卡发送给用户。

二、Redis的过期删除和淘汰策略

Redis如何判断key已经过期?

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

将key设置过期时间时,redis会把该key带上过期时间存储到一个过期字典中,过期字典的key是设置的key,value是long long类型,存储key的过期时间
在这里插入图片描述
由图中可以看到redis存储数据就是一个大的dict,实际就是hash表

  • 读取数据的时候如果key存在,还需要读取过期字典(如果没有设置过期时间不会存储在过期字典中,直接正常返回结果即可),获取key的过期时间,然后与当前系统时间比对

2.1 过期删除策略

  • 定时删除
  • 惰性删除
  • 定期删除
定时删除

在设置 key 的过期时间时,同时创建一个定时事件,当时间到达时,由事件处理器自动执行 key 的删除操作。

优点:

​ 可以保证过期 key 会被尽快删除,也就是内存可以被尽快地释放。因此,定时删除对内存是最友好的。

缺点:

​ 在过期 key 比较多的情况下,删除过期 key 可能会占用相当一部分 CPU 时间,在内存不紧张但 CPU 时间紧张的情况下,将 CPU 时间用于删除和当前任务无关的过期键上,无疑会对服务器的响应时间和吞吐量造成影响。所以,定时删除策略对 CPU 不友好。

惰性删除

不主动删除过期键,每次从数据库访问 key 时,都检测 key 是否过期,如果过期则删除该 key。

优点:

​ 对CPU友好

缺点:

​ 如果有些过期的数据后面再也没有被访问,就不会被删除,这样就会造成内存泄漏

定期删除

每隔一段时间随机从数据库中取出一定数量的key进行检查,如果过期就删除

例如:抽查20个,如果删除数量大于阙值(例如是4),则继续抽查,时间最大为25ms,超过25ms就结束

优点:

​ 限制删除频率,缓解CPU压力,也能在一定程度上释放内存

缺点:

​ 需要调整删除间隔和随机抽查策略,如果间隔过短,对CPU不友好,如果随机抽查效果不好,对内存不友好。

Redis使用策略:惰性删除+定期删除

2.2 内存淘汰策略

当redis内存达到最大设定的运行内存的时候,也就是说redis满了的时候,使用内存淘汰策略,删除一些key

八大淘汰策略

  • noeviction:如果redis执行增/改,会报错,如果执行查询或删除,可以正常执行

  • volatile-random:随机淘汰设置了过期时间的key-value

  • volatile-ttl:优先淘汰更早过期的k-v

  • volatile-lru:淘汰设置了过期时间的k-v中最久未使用的

  • volatile-lfu:淘汰设置过期的k-v中最少使用的

  • allkeys-random:随机淘汰任意kv

  • allkeys-lru:淘汰所有kv中最久未使用的

  • allkeys-lfu:淘汰所有kv中最少使用的

LRU算法内存污染问题:
redis处理:使用lfu算法(最多使用指的是频率高

img

  • ldt 是用来记录 key 的访问时间戳;
  • logc 是用来记录 key 的访问频次,它的值越小表示使用频率越低,越容易淘汰,每个新加入的 key 的logc 初始值为 5。

每次访问会修改logc的值,根据当前时间的时间戳和记录的时间戳,也就是数据访问的时间差,来增加或减少logc的值

mysql处理:设置访问时间阈值

三、 持久化

RDB和AOF

AOF和RDB同时开启,只会用AOF,即使此时AOF文件因为异常原因不存在,也不会用RDB,原因就是既然开启了AOF就是说明你想要AOF少丢数据的能力,所以即使没有AOF文件也不会用RDB,这样异常你也能发现及时处理,不然后者丢了数据就是潜在风险

bgsave:是通过子进程执行而不是子线程

3.1 RDB

写入RDB文件:

  1. save
  2. bgsave
  3. 多少秒内执行写文件的次数超过多少
  4. 程序正常关闭前会执行一次持久化写入

写入RDB文件流程

  1. fork一个子进程
  2. 子进程写数据到临时的RDB文件
  3. 写完之后用新的RDB替换旧的RDB文件

fork创建子进程之后,通过写时复制技术,子进程和父进程是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是一个。
在这里插入图片描述
所以刚开始的时候,主子进程共享同一个物理内存,但是如果主进程需要修改数据,会copy一个新的物理内存,旧的留给子进程使用,当子进程使用完之后会删除旧的那部分内存,在RDB写入过程中,这片内存存储的就是此刻Redis数据库中的数据
在这里插入图片描述

3.2 AOF

AOF开启后,在重启的时候会使用AOF恢复。

如果设置了过期时间的key ttl 只能是最新的了嘛?

答:不会,AOF在写入的时候会将过期时间转换成具体的事件,所以在恢复的时候会设置成具体的过期事件,但是恢复的时间点,如果过期了的键不会被删除。

3.2.1 AOF写入方式
  1. always:每次请求都刷入AOF,性能低,数据丢失小
  2. everysec:每秒刷入一次,性能数据丢失折中
  3. no:不主动刷盘,将刷盘操作交给操作系统,Linux一般每30秒刷一次,性能高,丢失数据风险大
3.2.2 写入AOF流程
  1. 写入aof_buff(aof缓冲区)
  2. write到内核缓冲区
  3. fsync到磁盘
3.2.3 AOF重写机制
  • 当AOF文件超过设定阈值的时候,就需要对文件进行重写。

  • AOF 重写机制是在重写时,读取当前Redis中的所有键值对,然后将每一个键值对用一条命令记录到「新的 AOF 文件」,等到全部记录完后,就将新的 AOF 文件替换掉现有的 AOF 文件。

  • 为什么写到新的AOF文件:因为如果写到就得AOF文件,且在过程中出错了,那就造成了AOF文件污染了。

  • Redis写入AOF是在主进程完成的,重写AOF是在子进程中完成的(fork子进程bgrewriteaof),原理和子进程写RDB文件一样,写时复制

  • 在子进程重写时,主进程会将后续操作写入aof重写缓冲区,当子进程完成重写后,主进程再将缓冲区的指令写入新的aof中

注:AOF重写和RDB写入都涉及到子进程,所以在写时复制会对主进程造成阻塞,此外在子进程完成操作通知主进程的时候也会发生阻塞

3.3 混合持久化

本质就是AOF重写。

发生在AOF重写阶段,将当前状态保存为RDB二进制内容,写入新的AOF文件,再将重写缓冲区的内容追加到新的AOF文件,最后替代原有的AOF文件。

四、事务

4.1 ACID

redis提供了四个命令支持事务机制:

  • MULTI:开启事务
  • EXEC:提交事务
  • DISCARD:放弃事务,情况命令队列
  • WATCH:检测一个或多个键的值在事务执行期间是否发生变化,如果发生变化,就放弃当前事务

Redis使用multi命令开启事务,exec提交事务,中间的指令存在一个队列中,在提交时:

  1. 命令入队时报错(语法错误),会放弃事务执行,保证原子性
  2. 命令入队时没有报错但是执行时报错,如果开启了AOF,保证原子性,如果没有开启则不会保证原子性

4.2 Lua

  • 会被redis当作事务执行
  • 如果出错,后续指令不会再执行,但是前面执行成功的指令不会回滚

为什么multi需要watch而Lua不需要?
答:因为multi是命令存储,从指定命令到开始执行会存在时间差,那么这段时间就可能数据被修改,而Lua是直接将命令交给Redis并开始执行,因为是单线程,所以不会存在数据被其他线程修改。

五、主从复制

  1. 全量复制
  2. 增量复制
  • 全量复制:从服务器使用psync runid offset,向主服务器发送同步请求,主服务器接收到之后发送rdb文件给从服务器,并在主服务器产生rdb文件、从服务器加载RDB文件的过程中,将新的指令写入replication buffer中,从服务器完成之后,再将缓冲区中的指令发送给从服务器。

  • 增量复制:主从服务器在完成第一次同步后,双方之间就会维护一个 TCP 连接。是一个长连接,后续主服务器可以通过这个连接继续将写操作命令传播给从服务器,然后从服务器执行该命令。

增量复制过程中,如果网络断开,网络恢复后,如何处理

  1. 再进行一次全量复制
  2. 根据offset进行增量复制

具体选择:主服务器中有一个环形缓冲区,记录主服务器写指令的顺序。主服务器在开始网络正常的时候,会将写指令发送给从服务器,并将写指令存入环形缓冲区中,此外更新对应的offet。当从服务器发送offset时,判断从服务器要读取的数据是否在环形缓冲区,如果在就进行增量复制,如果不再就进行全量复制。

从机不是越多越好:

  1. 在全量复制的时候,主服务器需要生成rdb文件,fork子进程,会阻塞主进程,如果内存数据很大,会阻塞很久
  2. 主服务器向从服务器发送rdb文件会占用网络带宽,会对主服务器响应命令请求产生影响。

所以可以使用一个中间的从服务器,减轻主服务器的压力
在这里插入图片描述

六、哨兵模式

主观下线:某个哨兵判断主节点下线
客观下线:对于主节点,由于网络压力或系统压力,导致主节点没有及时给哨兵响应,经过多个哨兵决断后判断确实下线。

为了减少误判的情况,哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成哨兵集群(最少需要三台机器来部署哨兵集群),通过多个哨兵节点一起判断(投票机制),就可以就可以避免单个哨兵因为自身网络状况不好,而误判主节点下线的情况。

为什么哨兵节点至少要有 3 个?

成为Leader必须获得一半的票数+1,如果是2个哨兵,则需要两票,挂了一个,最多只能获得一票,无法进行主从节点切换。如果 3 个哨兵节点,挂了 2 个怎么办?人为介入或增加哨兵节点数

哨兵的数量建议为奇数,quorum值(判断主节点是否单机的投票数)建议为哨兵节点数/2+1

两个投票:

  • quorum值决定的主节点是否宕机的投票:如果投票结果大于等于quorum值,则判定宕机
  • leader投票:判定主节点宕机后,选举leader哨兵,候选人是最先发现主节点宕机的哨兵(可能同一时刻有多个哨兵同时发现哨兵宕机),如果某个哨兵获取到大于等于一半加一的票数,且票数大于等于quorum值,则升级为leader。

主从故障转移

步骤:

  1. 在原主节点的从节点中选出一个作为新的主节点
  2. 修改其他的从节点的复制对象为新的主节点
  3. 将新的主节点的ip地址和信息通知给客户端
  4. 继续监视原主节点,当其恢复时设置为新主节点的从节点
  • 选出新主节点:先过滤掉网络状态不好的节点,然后根据优先级、复制进度、ID号选择。
    • 优先级:例如配置高的机器可以设置高优先级
    • 复制进度:比较offset(选offset偏移量大的从节点,与原主节点offset偏移量差值小
    • ID号选择:选择id小的从节点

主节点故障并转移的步骤总结

判断主节点故障 ——> 选举哨兵Leader ——> Leader选择新的主节点(优先级、复制量、id号) && 修改其他节点 && 通知客户端 && 监听原主节点

哨兵集群的组成

  1. 哨兵之间是如何连接的:通过 Redis 的发布者/订阅者机制来相互发现的。哨兵把自己的信息发送到_sentinel_: hello 频道,然后可以互相连接

  2. 哨兵在配置时候会指定主节点ip,通过向主节点发送info信息,获取从节点信息,并和从节点建立连接。

脑裂问题

脑裂就是指在同一时间主从集群中出现了两个主节点,会导致数据丢失。

  1. 网络问题:由于主节点和哨兵节点之间的网络问题,使得哨兵节点判断主节点客观下线,设置新的主节点,此时存在两个节点

  2. 负载问题:由于负载过高,主节点无法及时响应哨兵的心跳

数据丢失:新主节点发起全量复制,导致原主节点写数据丢失

解决:

  1. 与主节点连接的从节点数要尽可能多,建议配置为从节点一半加1
  2. 主节点与从节点的网络延迟要尽可能低,配置一个阙值。

七、集群

当redis内存使用很大的时候,虽然服务器配置的内存足够,但是在使用过程中,持久化fork操作由于内存很大(写时复制),需要阻塞主线程很长时间,所以内存很大时,需要使用集群,将大内存分散成多个小内存,这样就使得持久化操作不会阻塞很长时间

切片和实例(Redis节点)的对应关系

Redis集群使用hash槽(slot)根据key映射关系确定存储,一个切片集群共16384个hash槽,每个key会被映射到一个hash槽,集群中每个节点负责一部分hash槽。在手动分配哈希槽时,需要把 16384 个槽都分配完,否则 Redis 集群无法正常工作。

客户端如何定位数据

  • 实例-实例:实例之间会相互连接,组成集群,连接的时候会发送自己的hash槽信息,完成hash槽的分配信息扩散,实例之间通过Gossip协议进行交互,每个实例不需要和其他所有实例都建立连接

  • 客户端-实例:客户端连接任意实例的时候,实例就会把所有哈希槽的分配信息发送给客户端,这样客户端就知道所有实例的映射关系了。

重定向机制:

在集群中,实例有新增或删除,Redis 需要重新分配哈希槽;为了负载均衡,Redis 需要把哈希槽在所有实例上重新分布一遍,客户端访问新数据需要借助moved/ask命令。

  • moved:当客户端访问实例中的hash槽时,由于hash槽已经迁移至其他实例,该实例会使用moved命令,客户端会修改hash槽的映射关系
  • ask:hash槽在迁移过程中被访问(还未迁移完成),使用ask命令,不会修改客户端hash槽的映射。只针对已经迁移过去的key,如果key还未被迁移,则直接返回结果

八、Redis应用场景

8.1 缓存异常问题

缓存击穿、缓存穿透、缓存雪崩

解决:

  • 缓存穿透:

    1. 设置不存在的k,v设置为null,放置在缓存中,并设置过期时间(建议30秒,太长可能导致后面增加这条数据缓存出现不一致问题,太短不能有效避免穿透)
    2. 接口层校验,对于异常信息直接拦截,例如id<0
    3. 布隆过滤器
  • 缓存雪崩:

    1. 设置随机数,使得kv在一段时间内随机过期
    2. 互斥锁:使用互斥锁,使得允许只有一个线程能获取锁去查数据库,从而更新缓存。(需要设置过期时间)可以多设置几把锁,但是数量不能太多,以免db崩溃
    3. 后台更新缓存
    4. redis宕机引起的宕机:使用服务熔断或请求限流;构建主从集群
  • 缓存击穿:

    1. 互斥锁
    2. 设置热点数据永不过期,或者在数据快要过期时通知后台线程重新设置过期时间

8.2 缓存一致问题

  • 先修改数据库,再删除缓存
    (如果由于网络原因,导致删除缓存请求再回写缓存之前,会出现数据不一致问题(如图所示);或者删除缓存时redis宕机,恢复之后也会出现数据不一致问题)
    在这里插入图片描述
  • 延迟双删

8.3 分布式锁

  1. 过期时间和存kv原子操作(set key v ex xx nx)
  2. owner
  3. 检查是否是owner和delete要原子操作,lua脚本

红锁和锁丢失

8.3.1 NPC问题(没有完全可靠的分布式锁):

N:Network Delay(网络延迟),锁在redis中设置的时间,到客户端认为自己获取到锁的时间,中间存在网络延迟差。

P:Process Pause(进程暂停),进程运行过程中发送GC,使得redis中实际锁已经过期,但是线程还认为自己持有锁(GC导致时间差)

C:Clock Drift(时钟漂移),由于原来线程时钟漂移,使得实际已经锁过期,原来线程还是认为自己持有锁,则此时会发生多个线程获取锁。

总结:NPC问题本质就是由于时间差导致原线程仍然认为自身持有锁,但是实际上锁已经过期

8.3.2 Redisson
可重入:

使用hash结构,记录锁的重入次数,每次释放,重入次数减一,减到0的时候将锁删除

重试机制:

tryLock(获取锁的最大等待时间,过期时间,过期时间的单位)

WatchDog机制:

如果设置了过期时间,则不会使用看门狗机制,如果没有设置过期时间,则默认看门狗机制是30秒一次,且会一直续期。

8.4 Hot key、Big key(数据倾斜):

Hot Key处理:

  1. 读写分离(多级缓存)
  2. 拆分

Big Key处理:

  1. 拆分
  2. 压缩

8.5 秒杀

在这里插入图片描述
处理超卖

使用lua脚本,使得redis判断是否有库存和更新库存是原子操作

处理少卖

少卖出现场景:

  1. 图中第2步,实际是更新成功的,但是由于redis返回结果(可能由于网络原因)超时
  2. 第3步发送给消息队列生成订单失败

第二种情况出现解决方案:

  1. kafka的渐进式重试(先1s后重试一次,再2s、4s、8s…)
  2. 第一种方案的基础上,将这条消息记录在磁盘上,慢慢重试;

相关文章:

Redis解析

Redis解析 一、单线程模型 redis在io层面是多线程的&#xff0c;在数据处理层面是单线程的。 多线程一般用于&#xff1a; 关闭连接删除/淘汰内存网络IO 1.1 io多路复用 redis使用nio&#xff08;select、poll、epoll&#xff09;的方式处理socket 主线程负责接收建立连接…...

轨迹误差评估完整流程总结(使用 evo 工具)

roslaunch .launch rosbag play your_dataset.bag -r 2.0 ✅ 第二步&#xff1a;录制估计轨迹 bash 复制编辑 rosbag record -O traj_only.bag /aft_mapped_to_init 运行一段时间后 CtrlC 停止&#xff0c;生成 traj_only.bag 第三步&#xff1a;提取估计轨迹和真值轨迹为…...

服务器死机了需要检查哪些问题

在这个数字化的时代&#xff0c;服务器就像是我们信息世界的“大管家”&#xff0c;可要是它突然死机了&#xff0c;那可真是让人头疼。今天咱们就来聊聊&#xff0c;服务器死机了&#xff0c;到底需要检查哪些问题。 一、硬件问题 电源供应&#xff1a;检查电源是否稳定&…...

秒杀案例讲解

技术择型 Springboot 接收请求并操作 redis 和 mysqlRedis 用于缓存分布式锁Rocketmq 用于解耦 削峰&#xff0c;异步Mysql 用于存放真实的商品信息Mybatis 用于操作数据库的 orm 框架 架构图 spike-web&#xff08;接受用户秒杀请求&#xff09; pom.xml <?xml versio…...

Qt图表绘制(QtCharts)- 性能优化(13)

文章目录 1 批量替换代替追加1.1 测试11.2 测试21.3 测试3 2 开启OpenGL2.1 测试12.2 测试22.3 测试32.4 测试4 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;QtCharts绘图 &#x1f448;&#x1f449;python开发 &#x1f…...

[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)

[逆向工程]DebugView捕获WPS日志&#xff1f;解析未运行WPS时Shell扩展加载的原因与解决方案&#xff08;二十五&#xff09; 引言&#xff1a;一个“幽灵”般的日志问题 你是否在使用 DebugView 排查系统问题时&#xff0c;发现日志中频繁出现 WPS 相关模块&#xff08;如 k…...

【打破信息差】萌新认识与入门算法竞赛

阅前须知 XCPC萌新互助进步群2️⃣&#xff1a;174495261 博客主页&#xff1a;resot (关注resot谢谢喵) 针对具体问题&#xff0c;应当进行具体分析&#xff1b;并无放之四海而皆准的方法可适用于所有人。本人尊重并支持每位学习者对最佳学习路径的自主选择。本篇所列训练方…...

Ai Agent革命:不是流程驱动,而是模型为魂

前言&#xff1a;AI 智能体的未来&#xff1a;模型才是“主旋律”&#xff0c;工作流只是“插曲” 在 AI 智能体的未来舞台上&#xff0c;模型本身才是永恒的“主旋律”&#xff0c;而工作流不过是短暂的“插曲”。以 Manus 为例&#xff0c;其基于“预先编排好的提示词与工具…...

使用CherryStudio +SiliconFlow 部署独立的deepseek+知识库

deepseek知识库&#xff0c;独立的deepseek 首先我们先了解 CherryStudio&#xff1f;SiliconFlow&#xff1f; CherryStudio是一个支持多平台的AI客户端&#xff0c;我们致力于让更多人能够享受到AI带来的便利。 简单来说&#xff0c;它是一个能让普通人轻松用上AI 的「万能工…...

【leetcode】94. 二叉树的中序遍历

给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1a;root [1] 输出…...

OpenCV阈值处理完全指南:从基础到高级应用

引言 阈值处理是图像处理中最基础、最常用的技术之一&#xff0c;它能够将灰度图像转换为二值图像&#xff0c;为后续的图像分析和处理奠定基础。本文将全面介绍OpenCV中的各种阈值处理方法&#xff0c;包括原理讲解、代码实现和实际应用场景。 一、什么是阈值处理&#xff1…...

源码与二进制包区别

文章目录 源码包与二进制包的区别及选择建议概述核心区别对比1. 内容组成2. 安装复杂度3. 灵活性4. 依赖管理5. 安全性 选择建议适合使用**源码包**的场景&#xff1a;适合使用**二进制包**的场景&#xff1a; 总结 源码包与二进制包的区别及选择建议 概述 在常见的Linux安装…...

NAT转换和ICMP

NAT nat原理示意 nat实现 ICMP ICMP支持主机或路由器&#xff1a; 差错或异常报告网络探寻 2类icmp报文&#xff1a; 差错报告报文&#xff08;5种&#xff09; 目的不可达源抑制--拥塞控制超时&超期--TTL超时参数问题--问题报文丢弃重定向--不应该由这个路由器转发&a…...

No module named‘serial‘解决办法

jksjks-VMware-Virtual-Platform:~/gx$ sudopython3py.py Traceback (most recent call last): File "py.py",line 1, in <module> import serial.tools.list_ports ModuleNotFoundError: No module namedserial 这个报错意思是缺少serial模块 解决方法也很简…...

用 Gensim 实现 Word2Vec 古诗生成

向量操作。我们将借助它完成从语料处理到古诗生成的全流程。 6.1 环境搭建与库导入 首先安装 Gensim 及依赖库&#xff1a; bash pip install gensim numpy pandas 导入必要模块&#xff1a; python 运行 from gensim.models import Word2Vec # 核心词向量模型 from r…...

【图像生成1】Latent Diffusion Models 论文学习笔记

一、背景 本文主要记录一下使用 LDMs 之前&#xff0c;学习 LDMs 的过程。 二、论文解读 Paper&#xff1a;[2112.10752] High-Resolution Image Synthesis with Latent Diffusion Models 1. 总体描述 LDMs 将传统 DMs 在高维图像像素空间&#xff08;Pixel Space&#x…...

MapReduce Shuffle 全解析:从 Map 端到 Reduce 端的核心数据流​

一、Shuffle 的本质定位&#xff1a;MapReduce 的核心枢纽​ Shuffle 过程涵盖 MapTask 的后半程与 ReduceTask 的前半程&#xff0c;具体指从 map 方法输出到 reduce 方法输入之间的整个数据处理链路。它承担着三大核心使命&#xff1a;​ 数据分区&#xff1a;决定数据归属…...

架构与UML4+1视图

简单对比分析 架构41视图 架构41视图是由Philippe Kruchten提出的&#xff0c;用于描述软件系统的架构。它包括以下五个视图&#xff1a; 逻辑视图&#xff1a;描述系统的功能需求&#xff0c;展示系统的静态结构&#xff0c;通常使用类图、对象图等。开发视图&#xff1a;…...

nosqlbooster pojie NoSQLBooster for MongoDB

测过可用&#xff0c;注意 asar的安装使用报错改用 npx asar extract app.asar app 路径 C:\Users{computerName}\AppData\Local\Programs\nosqlbooster4mongo\resources npm install asar -g asar extract app.asar app 打开shared\lmCore.js 修改MAX_TRIAL_DAYS3000 修改…...

UI自动化测试中,一个完整的断言应所需要考虑的问题

在UI自动化测试中,一个完整的断言应全面覆盖用户界面(UI)的功能性、交互性和视觉正确性。以下是断言需要包含的核心内容及详细说明: 一、基础元素验证 存在性断言 验证元素存在于DOM中示例代码(Python + Selenium):assert driver.find_element(By.ID, "submit_btn&…...

电脑出故障驱动装不上?试试驱动人生的远程服务支持

在日常工作或学习中&#xff0c;驱动问题时常成为电脑用户的一大困扰。尤其是在更换硬件、重装系统、驱动冲突等情况下&#xff0c;许多用户往往手足无措&#xff0c;不知道从何下手。而“驱动人生”作为国内领先的驱动管理工具&#xff0c;一直以高效、便捷、智能著称。现在&a…...

机器学习第十五讲:决策树全面讲解:像玩“20个问题“游戏猜身份[特殊字符]

机器学习第十五讲&#xff1a;决策树全面讲解&#xff1a;像玩"20个问题"游戏猜身份&#x1f3ae; 资料取自《零基础学机器学习》。 查看总目录&#xff1a;学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章&#xff1a;DeepSeek R1本地与线上满血版部署&…...

基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)

参数结构体模块 在src目录下新建params文件夹 在params文件夹下依次新建req.rs、resp.rs、result_parse.rs、mod.rs 目录结构如下&#xff1a; project |—src |—params //封装参数结构体模块 |—req.rs //封装请求参数结构体 |—resp.rs //封装返回数据结构体 |—resu…...

Centos7系统(最小化安装)安装zabbix7版本详细文章、nginx源代码配置、php源代码、mysql-yum安装

zabbix官网链接下载zabbix源代码安装包 选择zabbix版本&#xff08;此文章使用zabbix7.0版本&#xff09; 安装之前由于是最小化安装centos7安装一些开发环境和工具包 文章使用国内阿里源 cd /etc/yum.repos.d/;curl -O https://mirrors.aliyun.com/repo/epel-7.repo;curl -…...

rocketmq 环境配置[python]

因本人是 python 开发&#xff0c;macbook 开发。windows 可以采取配置远程 linux 解释器或者 pycharm 专业版的 docker 解释器进行开发 M1 芯片 本地运行 rocketmq rocketmq Python 开源地址&#xff1a; https://github.com/apache/rocketmq-client-python 因为需要 linu…...

前端学习(4)—— JavaScript(基础语法)

目录 一&#xff0c;介绍 1.1 是什么 1.2 组成 1.3 书写形式 1.4 输入输出 二&#xff0c;变量的使用 2.1 基本用法 2.2 动态类型 三&#xff0c;基本数据类型 3.1 数字类型 3.2 字符串类型 3.3 布尔类型 3.4 未定义数据类型 3.5 空值类型 四&#xff0c;运算符…...

简单介绍C++中线性代数运算库Eigen

Eigen 是一个高性能的 C 模板库&#xff0c;专注于线性代数、矩阵和向量运算&#xff0c;广泛应用于科学计算、机器学习和计算机视觉等领域。以下是对 Eigen 库的详细介绍&#xff1a; 1. 概述 核心功能&#xff1a;支持矩阵、向量运算&#xff0c;包括基本算术、矩阵分解&…...

原生小程序+springboot+vue+协同过滤算法的音乐推荐系统(源码+论文+讲解+安装+部署+调试)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统背景 在数字音乐产业迅猛发展的当下&#xff0c;Spotify、QQ 音乐、网易云音乐等音乐平台的曲…...

[特殊字符] 如何优雅地避免 SQL 多表 LEFT JOIN 造成的笛卡尔积放大问题?

在实际项目开发中&#xff0c;我们经常需要从多个数据表中统计和聚合项目相关数据。但如果处理不当&#xff0c;多表 LEFT JOIN 容易造成 数据行数异常放大 的问题&#xff0c;也就是我们常说的“笛卡尔积放大”。 本文通过一个简单示例&#xff0c;直观讲清问题产生的原因&am…...

哈希表实现(1):

1. 哈希&#xff1a; 之前我们的红黑数的查找是由于左边小右边大的原则可以快速的查找&#xff0c;我们这里的哈希表呢&#xff1f; 这里是用过哈希函数把关键字key和存储位置建立一个关联的映射。 直接定址法&#xff08;函数函数定义的其中一种&#xff09;&#xff1a; 直…...

【流程控制结构】

流程控制结构 流程控制结构1、顺序结构2、选择结构if基本选择结构if else语法多重if语法嵌套if语法switch选择结构 3、循环结构循环结构while循环结构程序调试for循环跳转语句区别 流程控制结构 1、顺序结构 流程图 优先级 2、选择结构 if基本选择结构 单if 语法 if&…...

敏捷-第二章 敏捷宣言与原则

敏捷宣言与原则之间的关系 将敏捷明确表述为一种思维模式&#xff0c;它由《敏 捷宣言》的价值观所界定&#xff0c;受敏捷原则指导&#xff0c; 4通过各种实践实现敏捷不是指某一种具体的方法论、过程或框架&#xff0c;而是一组价值观和原则。 敏捷宣言(Manifesto)的4大价值…...

UAI 2025重磅揭晓:录取数据公布(附往届数据)

近日&#xff0c;第41届UAI公布了论文录用结果。本次大会共收到 750篇有效论文投稿&#xff0c;最终录用230篇&#xff0c;录用率为30.7%。录取率较去年&#xff08;UAI 2024&#xff09;相比有所上升&#xff08;录取率&#xff1a;26.88%&#xff09;。 会议概览 人工智能不…...

京东方10.1寸工业液晶屏GV101WXM-N80

第一篇&#xff1a;规格参数总览 产品标称 京东方(BOE) GV101WXM-N85 工业级显示单元 核心应用方向 教学终端设备&#xff5c;工业便携装置&#xff5c;车载控制系统 面板属性 非晶硅TFT液晶技术&#xff5c;全视角显示模式联合常暗配置 物理规格 对角线长度25.7cm&…...

实例分割AI数据标注 ISAT自动标注工具使用方法

文章目录 🌕ISAT安装和启动方法🌕下载和使用AI分割模型🌙SAM模型性能排行🌙手动下载sam模型 & sam模型下载路径🌕使用方法🌙从file中导入图片🌙点击左上角的图标进入分割模式🌙鼠标左键点击画面中的人则自动标注🌙点击右键该区域不标注🌙一个人一个人的…...

软件架构风格系列(4):事件驱动架构

文章目录 前言一、从“用户下单”场景看懂事件驱动核心概念&#xff08;一&#xff09;什么是事件驱动架构&#xff1f;&#xff08;二&#xff09;核心优势&#xff1a;解耦与异步的双重魔法 二、架构设计图&#xff1a;三要素构建事件流转闭环三、Java实战&#xff1a;从简单…...

软件架构风格系列(2):面向对象架构

文章目录 引言一、什么是面向对象架构风格1. 定义与核心概念2. 优点与局限性二、业务建模&#xff1a;用对象映射现实世界&#xff08;一&#xff09;核心实体抽象1. 员工体系2. 菜品体系 &#xff08;二&#xff09;封装&#xff1a;隐藏实现细节 三、继承实战&#xff1a;构建…...

python打卡day27

函数装饰器 知识点回顾&#xff1a; 装饰器的思想&#xff1a;进一步复用函数的装饰器写法注意内部函数的返回值 日常ctrl点进某个复杂的项目&#xff0c;发现函数定义上方有一个xxx,它就是装饰器。装饰器本质上是一个 Python 函数&#xff0c;可以在不修改原函数代码的情况下&…...

智能AI构建工地安全网:跌倒、抽搐、区域入侵多场景覆盖

智能AI在工地安全中的应用&#xff1a;从监测到救援的全流程实践 一、背景&#xff1a;高温作业下的工地安全挑战 随着夏季高温持续&#xff0c;工地户外作业环境面临严峻考验。工人因高温疲劳、脱水或突发疾病引发的行为异常&#xff08;如晕厥、抽搐、跌倒&#xff09;频发…...

gflags 安装及使用

目录 引言 安装 如何用 gflags 库写代码 如何用命令行使用 gflags 库 gflags 库的其他命令行参数 引言 gflags 是 Google 开发的一个开源库&#xff0c;用于 C 应用程序中命令行参数的声明、定义 和解析。 gflags 库提供了一种简单的方式来添加、解析和文档化命令行标…...

金融问答系统:如何用大语言模型打造高精度合规的金融知识引擎

假如我现在向大模型提问&#xff0c;我的问题是&#xff1a;请查询在2021年度&#xff0c;68**38股票涨停天数&#xff1f; 或者我问&#xff1a;湖南*****科股份有限公司变更设立时作为发起人的法人有哪些&#xff1f; 大模型巴拉巴拉给我一个答案&#xff0c;那怎么让我信任大…...

Spring WebFlux与Quarkus实战:云原生微服务开发的两大主流框架深度解析

简介 云原生与微服务架构已成为企业数字化转型的核心驱动力,而Spring WebFlux和Quarkus作为两大主流框架,各自提供了独特的解决方案来应对高并发、低延迟和快速启动的挑战。本文将从零开始,详细讲解如何使用这两个框架构建高性能的云原生微服务,并通过实际案例展示它们在企…...

成功案例丨从草图到鞍座:用先进的发泡成型仿真技术变革鞍座制造

案例简介 在鞍座制造中&#xff0c;聚氨酯泡沫成型工艺是关键环节&#xff0c;传统依赖实验测试的方法耗时且成本高昂。为解决这一问题&#xff0c;意大利自行车鞍座制造商 Selle Royal与Altair合作&#xff0c;采用Altair Inspire PolyFoam软件进行发泡成型仿真。 该工具帮助团…...

学习日志09 java

我要(ง •_•)ง&#xff01;&#xff01; 1 面向对象里面的编程的属性&#xff0c;其实就是变量啦 在面向对象编程里&#xff0c;“属性”&#xff08;Attribute&#xff09;也被叫做 “成员变量” 或者 “字段”&#xff08;Field&#xff09;&#xff0c;指的是类中用来存…...

深入解析Spring Boot与微服务架构:从入门到实践

深入解析Spring Boot与微服务架构&#xff1a;从入门到实践 引言 随着云计算和分布式系统的普及&#xff0c;微服务架构已成为现代软件开发的主流模式。Spring Boot作为Java生态中最受欢迎的框架之一&#xff0c;为开发者提供了快速构建微服务的强大工具。本文将深入探讨Spri…...

25考研经验贴(11408)

声明&#xff1a;以下内容都仅代表个人观点 数学一&#xff08;130&#xff09; 25考研数学一难度介绍&#xff1a;今年数学一整体不难&#xff0c;尤其是选填部分&#xff0c;大题的二型线面和概率论大题个人感觉比较奇怪&#xff0c;其他大题还是比较容易的。.26如何准备&a…...

Linux运行时的参数、命令、网络、磁盘参数和日志监控

一、监控 1. free 功能&#xff1a;用于查看系统内存使用情况&#xff0c;包括物理内存总量、已用内存、空闲内存、缓冲区&#xff08;buffer&#xff09;和缓存&#xff08;cache&#xff09;占用&#xff0c;以及交换内存&#xff08;swap&#xff09;的使用与剩余情况。常…...

Spring Boot循环依赖的陷阱与解决方案:如何打破“Bean创建死循环”?

引言 在Spring Boot开发中&#xff0c;你是否遇到过这样的错误信息&#xff1f; The dependencies of some of the beans in the application context form a cycle 这表示你的应用出现了循环依赖。尽管Spring框架通过巧妙的机制解决了部分循环依赖问题&#xff0c;但在实际开…...

如何打造MVP(最小可行性产品)(MVP=核心功能+快速验证+用户反馈+持续迭代)

文章目录 **一、MVP的核心原则**1. **聚焦核心价值**2. **快速迭代**3. **低成本验证** **二、MVP的打造步骤****1. 定义目标用户和核心需求****2. 确定MVP的核心功能**- **筛选关键功能**&#xff1a;1. 用户是否愿意为这个功能付费&#xff1f;2. 实现该功能的技术难度和成本…...

conda init执行了还是不好用

按照gpt的方法&#xff0c;还是方法一&#xff1a;以管理员身份运行 PowerShell 并设置执行策略 好用 你遇到的问题是典型的 Conda 环境激活失败 错误&#xff0c;提示如下&#xff1a; CondaError: Run conda init before conda activate但你已经运行了 conda init&#xff…...