Redis之持久化、集群

1. Redis持久化

Redis为什么需要持久化?因为Redis的数据我们都知道是存放在内存中的,那么每次关闭或者机器断电,我们的数据旧丢失了。

因此,Redis如果想要被别人使用,这个问题就需要解决,怎么解决呢?就是说我们的数据要同步到磁盘,只有同步到磁盘中了,数据才不会丢失,然后我们启动的时候,内存从磁盘里再加载数据,这样就既能满足基于内存的操作,保证性能,同时也尽可能的防止了数据的丢失。

那么Redis做持久化的方式有哪些呢? RDB和AOF

1.1 RDB

RDB是Redis默认的持久化方案,当满足一定条件的时候,会把当前内存中的数据写入磁盘,生成一个快照文件dump.rdb(默认)

可配置RDB文件的文件名与路径:

# The filename where to dump the DB
dbfilename dump . rdb //dunmp.rdb 文件名
dir . / // 文件路径

那么RDB什么时候会触发呢?

  • 自动触发
    • 配置触发
save 900 1 900 s 检查一次,至少有 1 key 被修改就触发
save 300 10 300 s 检查一次,至少有 10 key 被修改就触发
save 60 10000 60 s 检查一次,至少有 10000 key 被修改
  • shutdown正常关闭;
任何组件,在正常关闭的时候,都会去完成该完成的事情,比如 Mysql中的Redolog 持久化 正常关闭的时候也会去持久化。
  •  flushall指令触发
数据清空指令会触发 RDB 操作,并且是触发一个空的 RDB 文件,所以, 如果在没有开启其他的持久化的时候,flushall 是可以删库跑路的,在 生产环境慎用。
  • 手工触发
    • save 主线程去进行备份,备份期间不会去处理其它的指令,其它指令必须等待
    • bgsave 子线程去进行备份,其它指令正常执行

操作实例演示:

a.我们首先添加一份数据并且备份到RDB

redis > set k1 1
redis > set k2 2
redis > set k3 3

 b.查看数据是否存在

redis > keys *

c.进行shutdown操作触发RDB快照

 redis> shutdown

 d.对现有RDB数据进行备份cp

redis > cp dump . rdb dump . rdb . bak

 e 启动redis

redis > src / redis - server & redis . conf

 发现数据都还在

f. 现在模拟数据丢失

redis > flushall

 g. 停服务器再启动

redis > shutdown
redis > src / redis - server & redis . conf

h. 此时发现数据已经丢失,现在就要从我们备份的数据恢复,先关闭

 redis> shutdown

 i.删除原RDB备份数据

redis > rm dump . rdb

j 将备份数据改名为bump.rdb

 mv dump.rdb.bak dump.rdb

k.  重启服务

src / redis - server & redis . conf

 我们发现数据已经恢复

思考:我们的数据是怎么备份到RDB中的呢?

1. 新起子线程,子线程会将当前 Redis 的数据写入一个临时文件
2. 当临时文件写完成后,会替换旧的 RDB 文件。
Redis 启动的时候,如果只开启了 RDB 持久化,会从 RDB 文件中加载数据。

 RDB的优势:

1. 是个非常紧凑型的文件,非常适合备份与灾难恢复。
2. 最大限度的提升了性能,会 fork 一个子进程,父进程永远不会产于磁盘IO或者类似操作。
3. 更快的重启。

简单总结一句话,RDB恢复与备份都非常的快

RDB的不足

 1.数据安全性不是很高,因为是根据配置的时间来备份,假如每5分钟备份 一次,也会有5分钟数据的丢失

2. 经常 fork 子进程,所以比较耗 CPU ,对 CPU 不是很友好。 

1.2 AOF

由于RDB的数据可靠性非常低,所以Redis又提供了另外一种持久化方案: Append Only File 简称 AOF

AOF默认是关闭的,你可以在配置文件中进行开启 (追加文件,即每次更改的命令都会附加到我的AOF文件中)

appendonly no // 默认关闭,可以进行开启
# The name of the append only file ( default : "appendonly.aof" )
appendfilename "appendonly.aof" //AOF 文件名

 1.2.1同步机制

AOF, 会记录每个写的操作,那么问题来了?我难道每次操作命令又得跟磁盘交互呢?不跟mysql 一样每次需要跟磁盘交互呢?
当然不行,所以, redis 支持几种策略,由你们自己来决定要不要每次都跟磁盘交互
# appendfsync always 表示每次写入都执行 fsync( 刷新 ) 函数 性能会非常非常慢 但是非常安全
appendfsync everysec 每秒执行一次 fsync 函数 可能丢失 1s 的数据
# appendfsync no 由操作系统保证数据同步到磁盘,速度最快 你的数据只需要交给操作系统就行
默认1s一次,最多有1s的数据丢失

1.2.2 重写机制

由于AOF是追加的形式,所以文件会越来越大,越大的话,数据加载越慢。所以我们需要对AOF文件进行重写。

那么什么是重写呢?

比如 我们的 incr 指令,假如我们 incr 100 次,现在数据是 100 ,但是我们的aof 文件中会有 100 incr 指令,但是我们发现这个 100 条指令用处不大,假如我们能把最新的内存里的数据保存下来的话。
所以,重写就是做了这么一件事情,把当前内存的数据重写下来,然后把
之前的追加的文件删除。

重写流程(Redis7之前)

1. Redis fork 一个子进程,在一个临时文件中写入新的 AOF (当前内存的数据生成的新的AOF
2. 那么在写入新的 AOF 的时候,主进程还会有指令进入,那么主进程会在内存缓存区中累计新的指令 (但是同时也会写在旧的AOF 文件中,就算重写失败,也不会导致AOF 损坏或者数据丢失)
3. 如果子进程重写完成,父进程会收到完成信号,并且把内存缓存中的指令追加到新的AOF 文件中
4. 替换旧的 AOF 文件 ,并且将新的指令附加到重写好的 AOF 文件中。

 什么时候进行重写(根据配置)

# 重写触发机制
auto - aof - rewrite - percentage 100
auto - aof - rewrite - min - size 64 mb 就算达到了第一个百分比的大小,也必须大于 64 M

 说明:在aof文件小于64mb的时候不进行重写,当到达64mb的时候,就重写一次。重写后的aof文件可能是40mb.上面配置了auto-aof-rewrite-percentage为100,即aof文件到了80mb的时候进行重写

1.2.3 AOF的优势与不足

优势

1. 安全性高,就算默认的持久化同步机制,也最多只会导致 1s 丢失。
2.AOF 由于某些原因,比如磁盘满了等导致追加失败,也能通过 redis
check-aof 工具来修复   ./redis-check-aof --fix append
3. 格式都是追加的日志,所以可读性更高

不足

1. 数据集一般比 RDB
2. 持久化跟数据加载比 RDB 更慢
3. 7.0 之前,重写的时候,因为重写的时候,新的指令会缓存在内存区,所以会导致大量的内存使用
4. 并且重写期间,会跟磁盘进行 2 IO ,一个是写入老的 AOF 文件,一个 是写入新的AOF 文件

2.Redis集群

2.1 Redis主从

为什么要有主从?

1. 故障恢复 主挂了或者数据丢失了,我从还会有数据冗余
2. 负载均衡,流量分发 我们可以主写,从库读,减少单实例的读写压力
3. 高可用 我们等下讲的集群 等等,都是基于主从去实现的

 安装教程后续会单独出文章

我们现在已经安装了一个主从,先看下基本信息

主:

127.0 . 0.1 : 6379 > info replication
# Replication
role : master // 角色
connected_slaves : 1 // 从节点数量
slave0 : ip = 192.168 . 8.127 , port = 6379 , state = online , offset = 7889
9 , lag = 1 // 从节点的信息 状态 偏移量
master_replid : 04f4969 ab63ce124e870fa1e4920942a5b3448e7
//# master 启动时生成的 40 16 进制的随机字符串,用来标识 master 节点
master_replid2 : 0000000000000000000000000000000000000000
master_repl_offset : 78899 //mater 已写入的偏移量
second_repl_offset : - 1
repl_backlog_active : 1
repl_backlog_size : 1048576 // 缓冲区大小
repl_backlog_first_byte_offset : 1
repl_backlog_histlen : 78899 // 缓冲区的数据已有大小(是个环形,跟RedoLog一样会覆盖)

从:

 127.0.0.1:6379> info replication

# Replication
role : slave // 角色
master_host : 192.168 . 8.129 // 主节点 IP
master_port : 6379 // 主节点端口
master_link_status : up // 连接状态 up 是正常同步连接状态 down
示复制端口
master_last_io_seconds_ago : 1 // 主库多少秒没有发送数据到从库 0-
10
master_sync_in_progress : 0 // 是否正在跟主服务同步
slave_repl_offset : 163 // 从节点偏移量
slave_priority : 100 // 选举时成为主节点的优先级 越大优先级越高 0不会成为主节点
slave_read_only : 1 // 是否为只读从库 如果不是只读,则能自己进行数据写入,默认是只读
connected_slaves : 0 // 连接的从库实例
master_replid : 04f4969 ab63ce124e870fa1e4920942a5b3448e7
//master 启动时生成的 40 16 进制的随机字符串,用来标识 master 节点
master_replid2 : 0000000000000000000000000000000000000000
//slave 切换 master 之后,会生成了自己的 master 标识,之前的 master 节点的标识存到了master_replid2 的位置
master_repl_offset : 163 // 已写入偏移量
second_repl_offset : - 1
repl_backlog_active : 1
repl_backlog_size : 1048576 // 复制积压的缓存区大小
repl_backlog_first_byte_offset : 1
repl_backlog_histlen : 163

 2.1.1 主从数据同步

我们发现,我们的信息中,有个slave_read_only,如果是1代表只读。也就是默认,当然也可以配置成写,但是写的数据不会同步到主库,需要自己去保证数据的一致性,可能从库写的数据会被主库的数据操作覆盖。出现从库set一个值后,获取到的是主库覆盖的数据。

举例:

127.0 . 0.1 : 6379 > set k1 2 // 从库设置 k1 2

 127.0.0.1:6379> set k1 3 //主库设置k13 并且会同步到从库

 127.0.0.1:6379> get k1

"3"     // 从库得到的是主库设置的值

 思考:  我们主库的数据是怎么同步到从库的呢?同步过程是怎么样的?或者主从数据是怎么保证一致性的。

a.建立连接

当首次成为主节点的从节点时,执行 replicaof ip port 命令的时候就会保存主服务器的IP 与端口
并且与主服务器建立连接,接收主节点返回的命令
判断主节点是否有密码 如果有 进行权限校验
保证主从之前保存了各自的信息,并正常连接。

b.slave发起同步master数据指令

在slave的serverCron方法调用replicationCron方法,里面会发起跟master的数据同步

run_with_period ( 1000 ) replicationCron ();

 b.1 全量同步

1. master 服务器收到 slave 的命令后( psync ),判断 slave 传给我的master_replid 是否跟我的 replid 一致,如果不一致或者传的是个空的,那么就需要全量同步。
2. slave 首次关联 master ,从主同步数据, slave 肯定是没有主的 replid, 所以需要进行全量同步。
3. 进行全量同步
        3.1. master开始执行 bgsave ,生成一个 RDB 文件,并且把 RDB 文件传输给我们的slave ,同时把 master replid 以及 offerset master 的数据进度,处理完命令后,都会写入自身的offerset
        3.2. slave接收到 rdb 文件后,清空 slave 自己内存中的数据,然后用 rdb来加载数据,这样保证了slave 拿到的数据是 master 生成 rdb 时候的最新数据。
        3.3. 由于 master 生成 RDB 文件是用的 bgsave 生成,所以,在生成文件的时候,是可以接收新的指令的。那么这些指令,我们需要找一个地方保存,等到slave 加载完 RDB 文件以后要同步给 slave
                3.2.1. 在master 生成 rdb 文件期间,会接收新的指令,这些新的指令会保存在一个内存区间,这个内存区间就是replication_buffer
                3.2.2. 这个空间不能太小,如果太小,为了数据安全,会关闭跟从库的网络连接。再次连接得重新全量同步,但是问题还在,会导致无限的在同步

 replication_buffer大小的设置

client - output - buffer - limit replica 256 mb 64 mb 60  256 mb 硬性限制,大于 256M 断开连接
64 mb 60 软限制 超过 64M 并且超过了 60s 还没进行同步 内存数据就会断开连接

 b.2 增量同步

为什么需要增量同步?

这是因为每个节点都会保存数据的偏移量,那么就有可能出现slave跟master网络断开一小会,然后发起数据同步的场景,如图所示:

 slave1由于网络断开了,偏移量跟master相差了3.

那么当slave1重新跟master连接后,同样的会去跟master连接触发数据同步。但是这个时候还需不需要全量同步了?我们肯定是尽可能的减少全量同步。

所以,当master收到slave的指令时:

1. 判断 slave1 传给我的 master_replid 是否跟 master replid 一致,由于之前已经连接过保过了master replid ,满足条件。
2. 所以我希望只同步断开连接后没有同步到的数据,必须,我 slave1 只差 了3 的数据。那么我需要找到这个 3 的数据。所以 master 中有个另外的积压缓(replication_backlog_buffer )。
我们也不可能无限制的往里面写数据, replication_backlog_buffer 的数据是会覆盖的。
3. 所以,我们 slave1 master 相差的 3 条数据可能会被覆盖,如果覆盖了,触发全量,如果没有覆盖,即能找到相差的3 条数据。增量即可。

 replication_backlog_buffer的配置

# The bigger the replication backlog , the longer the
time the replica can be 复制积压越大,复制副本的时间越长
# disconnected and later be able to perform a partial
resynchronization . 已断开连接,稍后可以执行部分重新同步。
#
# The backlog is only allocated once there is at least
a replica connected . 只有在至少连接了一个副本后,才会分配积压工 作。
#
# repl - backlog - size 1 mb

 b.3 指令同步

master写入的指令,异步同步给slave,如果有slave,写入replication_backlog

_buffer

整体主从数据同步流程图: Redis主从同步策略| ProcessOn免费在线作图,在线流程图,在线思维导图

2.2 Sentinel哨兵

主从,虽然解决了比如负载、数据备份等问题。但是我们发现如果master挂了,slave不会直接升级为主,必须手动把slave升级为主。这样肯定人为维护的成本比较高。所以我们希望能有一个技术帮我们实现这样的需求,于是就有了哨兵集群。

什么是哨兵集群?

Redis sentinel 在不适用 Cluster 集群的时候,为 Redis 提供了高可用性。
并且提供了监测、通知、自动故障转移、配置提供等功能。
监控 :能够监控我的 Redis 各实例是否正常工作
通知 :如果 Redis 的实例出现问题,能够通知给其他实例以及 sentinel
自动故障转移 :当我的 master 宕机, slave 可以自动升级为 master
配置提供 sentinel 可以提供 Redis master 实例地址,那么客户端只需要跟sentinel 进行连接, master 挂了后会提供新的 master

其实sentinel是独立于Redis服务的单独的服务,并且它们之间是相互通信的。

2.2.1 哨兵故障转移流程

我们的哨兵到底是怎么去发现我们的master挂了的呢?挂了后让slave变成Master的整个流程是咋样的呢?

a。发现master故障

1. 当我们某个 sentinel master 通信时(默认 1s 发送 ping ),发现我在 一定时间内(down-after-milliseconds ) 没有收到 master 的有效的回复。这个时候这个sentinel 就会人为 master 是不可用,但是有多个sentinel,它现在只有 1个人觉得宕机了,这个时候不会触发故障转移,
只会标记一个状态,这个状态就是 SDOWN Subjectively Down condition ),也就是我们讲的主观下线
2. SDOWN 时,不会触发故障转移,会去询问其他的 sentinel ,其他的sentinel是否能连上 master ,如果超过 Quorum( 法定人数 ) sentinel 都认为master 不可用,都标记 SDOWN 状态,这个时候, master 可能就真的是down 了。那么就会将 master 标为 ODOWN Objectively Down condition 客观下线)

b. 进行故障转移

1. 当状态为 ODWON 的时候,我们就需要去触发故障转移,但是有这么多 的sentinel ,我们需要选一个 sentinel 去做故障转移这件事情,并且这 个sentinel 在做故障转移的时候,其他 sentinel 不能进行故障转移
2. 所以,我们需要选举一个 sentinel 来做这件事情 : 其中这个选举过程有 2个因素。
        2.1  Quorum 如果小于等于一半,那么必须超过半数的 sentinel 授权,你才能去做故障迁移,比如5 sentinel ,你配置的 Quorum=2 ,那么选举的时候必须有3 5 台的一半以上)人同意
        2.2. Quorum如果大于一半,那么必须 Quorum sentinel 授权,故障迁移才能启动。

 c.选哪个slave来变成master

1. master 的断开连接时间
如果 slave 与主服务器断开的连接时间超过主服务器配置的超时时间 (down-after-milliseconds )的十倍,被认为不适合成为 master 。直接去除资格
2. 优先级
配置 replica-priority replica-priority 越小,优先级越高,但是配置为0的时候,永远没有资格升为 master
3. 已复制的偏移量
比较 slave 的赋值的数据偏移量,数据最新的优先升级为 master
4. Run ID (每个实例启动都会有个 Run ID
通过 info server 可以查看。

2.2.2 Sentinel导致的数据一致性问题

官方建议配置至少3个sentinel

原因如下:

1. 如果只有 1 sentinel 实例,则这个实例挂了就不能保证 sentinel 的高可用性。
2. 如果,我配置了 2 sentinel ,分别在 127 跟128.n并且我配置的quorum=1 ;就可能发生
        2.1.sentinel2检测到 master 不可用,因为 127 128 网络断开,这个时候会触发主观下线,同时,sentinel2 只能连接到 1 sentinel ,也满足半数以上原则(只有1 sentinel2
        2.2.sentinel2开启故障转移,将 128 slave 升级为 master, 就出现了 2 个master,这个情况也叫作脑裂。并且客户端会连接到 2 master 。 (客户端连的是sentinel 集群,所以 sentinel1 连到 127.sentinel2 连到 128
        2.3  2 master 都会写入数据,当网络恢复后, 127 会变成从, 127 的数据会
128 去拿取,这个时候 127 的数据就会丢失

2.2.3 脑裂问题

脑裂问题其实就是我会有2个master,client会从不同的master写数据,从而在master恢复的时候会导致数据丢失。

所以只要发生分区容错性,不管多少节点都会出现,比如3个节点。

初始 129 master, 假如 129 网络断开,跟 127.128 连接断开后, 128sentinel发起故障转移。发现 sentinel 的个数超过一半,能够发起故障 转移。将128 升级为 master ,导致 128.129 同时 2 master 并可用

解决方案:

在Redis.cfgt文件中有2个配置:

min - replicas - to - write 1 至少有 1 个从节点同步到我主节点的数据,但是由于是异步同步,所以是最终一致性 不会确保有数据写入
min - replicas - max - lag 10 判断上面 1 个的延迟时间必须小于等于 10s

 按上述场景

129由于没有slave同步,不满足我配置的要求,不能进行数据写入。尽量减少数据一致性问题。

思考,为什么部署奇数台?一因为4跟3 能容许挂掉的机器数量是一样的,都是1台

2.3 Redis Cluster

我们发现sentinel提供了比如监控、自动故障转移、客户端配置等高可用的方案,但是没有分片功能。

何为分片:就是我希望把数据分别到不同的节点。这样如果某些节点异常,其它数据能正常提供服务,跟我们微服务的思想很相似。

所以我们cluster就提供了这样的解决方案

1. 多个节点之间的数据拆分,也就是我们的数据分片
2. 当某些节点遇到故障的时候,其他的节点还能继续服务。

 2.3.1 hash slot(虚拟槽)

那么如何进行分片?分片要做的事情就是把不同的数据放到不同的实例里面去。就相当于我们分表,不同的数据放到不同的表里。

普通取模问题

取模 直接取模实例数,得到 key hash 值,取模实例数,假如实例是 3 ,那么取模后得到0-2 的值,每个值代表一个实例。
但是这种取模有一个问题,假如我做了实例的扩容与缩容,那么全部数据要进行迁移。
假如我之前是 3 台,扩容到 4 台,那么所有的数据都必须重新 rehash
所以, Redis 里面提出了一个 Hash 槽,也叫作虚拟槽的概念。什么是虚拟槽,其实就是虚拟节点。
Redis cluster 中有 16384 个虚拟槽

我们的key会跟槽对应,怎么对应?

根据key通过CRC16取模16383得到一个0到16383的值,计算公式:slot=CRC16(key)&16383,得到的值,就代表这个key在哪个虚拟槽。

举例:

假如
set k1 1 :
CRC16 ( k1 ) & 16383 = 11901
set k2 1 :
CRC16 ( k2 ) & 16383 = 10
set k3 1 :
CRC16 ( k3 ) & 16383 = 6666
那么我们 k1 对应的槽是 11901 k2 对应的槽是 10 k3 对应的槽是 6666

key跟槽的关系是根据key算出来的,后续不能变动。

如果想把相关keu放入一个虚拟槽,也就是一个实例节点,我们可以采用{},那么就只会根据{}里面的内容计算hash槽!

比如: zsc{18}跟james{18}就会在一个虚拟槽

那么key怎么去放到我们的真实节点?

假设我们现在有6台实例,三主三从。主跟槽的对应关系如下:
master1 0-5460 虚拟槽
master2 5461-10922 虚拟槽
master3 10923-16383 虚拟槽

 我们知道,k1的虚拟槽是10001,所以放到master3,依次类推,k2放到master1,k3放到mster2

从节点的数据全部来源于主,所以k1放入master3的从,以此对应。

127.0.0.1:6380> cluster nodes 查看当前节点的虚拟槽信息

这样,每次节点的扩容与缩容,只需要改变节点跟虚拟槽的关系即可,不需要全部变动。

3. 总结

        redis是内存型数据库,因此每次机器关机都会清理内存,因此,要想保证redis的可用性,就需要持久化技术,redis持久化分为RDB快照和AOF追加两种形式; 但是为了高可用,流量的分发以及为了应对redis挂了之后的可用性,引入了主从,主从之间就又设计到了数据的全量同步和增量同步;随后,为了更进一步的将主从切换智能化,提出了sentinel哨兵模式,可用监控主的状态,采用一定的策略,保证主挂了以后从可以升级为主;最后是为了更进一步提升redis的高可用,采用集群的方案,将redis数据分布到不同的节点进行管理。

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

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

相关文章

Windows通过cmd运行快速启动应用

Windows如何通过cmd运行快速启动应用? 在Windows操作系统中,可以通过配置环境变量的方式将文件的路径配置到环境变量的path中,配置完成后可以在cmd中输入对应的应用名称即可启动应用,具体操作如下: 1. 添加应用程序路径…

力扣62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径? 示例 1&…

FJSP:蛇鹫优化算法(SBOA)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

详细介绍 FJSP:蛇鹫优化算法(Secretary bird optimization algorithm,SBOA)求解柔性作业车间调度问题(FJSP),提供MATLAB代码-CSDN博客 完整MATLAB代码 FJSP:蛇鹫优化算法&#xff…

spoon工具的常用基础操作

一些常用转换工具 1、emp表输入->excel表输出 emp表输入,可以进行预览查看数据有没有过来excel表输出 成功执行后,可以到保存的excel位置进行查看。 2、excel输入->表输出 运行转换后可以在oracle进行查看是否有成功创建这个表 3、对部门最高…

Java 22的FFM API,比起Java 21的虚拟线程

哪个对Java未来的发展影响更大?两个 Java 版本中的重要特性:Java 21 的虚拟线程和 Java 22 的 FFM API。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给…

原生APP开发和Flutter开发的比较

原生APP开发和Flutter开发各有优缺点,适用于不同的场景和需求。下面是两者的详细比较,从开发语言、性能、开发效率、维护和更新、社区和支持等多个方面进行分析。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。…

【康耐视国产案例】智能AI相机机器视觉精准快速实现包裹标签的智能粘贴

康耐视推出的3D-A1000是专业的、匹配物流行业各类分拣机及包裹检测应用的全功能视觉检测系统,其能够准确检测分拣机上是否有包裹、包裹是否超出边界、空车检测、是否有遗留物品等。由于搭载了专利的三维结构光技术,产品具有更强大的创新性以满足持续更新…

综合交易模型--雪球跟单参数说明支持qmt,同花顺

经过测试,目前完成了这个策略。支持多策略,支持全市场,包括股票,etf,可转债 全部的参数 { "雪球跟单":"跟单原理", "原理":"比重变大默认买入,变小默认卖出,持股…

fintuning chatglm3

chatglm3介绍 ChatGLM3-6B 是 ChatGLM 系列最新一代的开源模型,在保留了前两代模型对话流畅、部署门槛低等众多优秀特性的基础上,ChatGLM3-6B 引入了如下特性: 更强大的基础模型: ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用…

【uni-app】Pinia 持久化

小程序端 Pinia 持久化 说明:Pinia 用法与 Vue3 项目完全一致,uni-app 项目仅需解决持久化插件兼容性问题。 持久化存储插件 安装持久化存储插件: pinia-plugin-persistedstate pnpm i pinia-plugin-persistedstate插件默认使用 localStor…

Anaconda创建python环境默认C盘,如何修改路径

文章目录 前言解决方案1.找到Anaconda的根目录2. 找到根目录文件夹,右键-属性-安全 测试-重新创建新的python环境 前言 使用 Anaconda创建python环境,默认在C盘。 如何修改到别的路径呢? base环境 是安装 Anaconda是安装的默认环境&#x…

西瓜播放器xgplayer设置自动播放踩坑

上图是官网(西瓜视频播放器官方中文文档)的介绍,相信大家都是按照官网配置去做的,但是并没有什么用,插件很好用,但是属性不全,真的很悔恨,找遍 api 都没有找到自动播放的属性&#x…

LLM——深入探索 ChatGPT在代码解释方面的应用研究

1.概述 OpenAI在自然语言处理(NLP)的征途上取得了令人瞩目的进展,这一切得益于大型语言模型(LLM)的诞生与成长。这些先进的模型不仅是技术创新的典范,更是驱动着如GitHub Copilot编程助手和Bing搜索引擎等广…

linux磁盘阵列

磁盘阵列 可以用不同的磁盘,组成一个逻辑上的硬盘。高可用,冗余 lvm 扩容 raid 高可用 磁盘的组成方式不同,也就是不同的raid级别 raid级别 使用硬盘数量 磁盘利用率 冗余能力 读写性能 raid0 N 100% 0 读写最好 raid1 N(偶数) 50% 坏…

电商推荐系统+电影推荐系统【虚拟机镜像分享】

电商推荐系统电影推荐系统【虚拟机镜像分享】 所有组件部署好的镜像下载(在下面),仅供参考学习。(百度网盘,阿里云盘…) 博主通过学习尚硅谷电商推荐电影推荐项目,将部署好的虚拟机打包成ovf文…

通用代码生成器应用场景三,遗留项目反向工程

通用代码生成器应用场景三,遗留项目反向工程 如果您有一个遗留项目,要重新开发,或者源代码遗失,或者需要重新开发,但是希望复用原来的数据,并加快开发。 如果您的项目是通用代码生成器生成的,…

Leecode---技巧---只出现一次的数字 / 多数元素

题解&#xff1a; 利用异或运算 a⊕a 0 的性质&#xff0c;可用来消除所有出现了两次的元素&#xff0c;最后剩余的即为所得。 class Solution { public:int singleNumber(vector<int>& nums){// 初始化为0int ans 0;for(int x: nums){// 异或操作ans ^ x;}retur…

上网是不是必须路由器和光猫之一负责拨号?

链接&#xff1a;https://www.zhihu.com/question/624856022/answer/3245182557 上网并非一定要“拨号”&#xff0c;使用固定IP地址可以直接上网&#xff0c;不需要拨号。你们公司的宽带属于商用宽带&#xff0c;运营商&#xff08;电信&#xff09;给配置了固定的IP&#…

【计算机毕业设计】基于SSM++jsp的校园驿站管理系统【源码+lw+部署文档】

目录 第1章 绪论 1.1 课题背景 1.2 课题意义 1.3 研究内容 第2章 开发环境与技术 2.1 MYSQL数据库 2.2 JSP技术 2.3 SSM框架 第3章 系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 系统流程 3.2.1 操作流程 3.2.2 登录流程 3.2.3 删除信息流…

vue-标签选择

效果 选中后 代码 <span :class"[item.bealtrue?p_yx_span span_active :span p_yx]" click"onTagSelect(index)" v-for"(item,index) in tagList" :key"index" >{{item.name}} </span> // 列表值 tagList:[ {id: 1, na…