redis-Redis主从,哨兵和集群模式

一,Redis的主从复制

​ 主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。这样做的好处是读写分离,性能扩展,容灾快速恢复。

1.1 环境搭建

如果你的redis在不同的服务器上,可以不看同一台服务器上启动多个redis的实现步骤:

将redis的配置文件redis.conf到/myredis文件夹中:

cp redis.conf /myredis/redis.conf

编辑拷贝后的redis.conf文件,查找bing 127.0.0.1配置有没有注释掉,没有的话,自己注释了

vi /myredis/redis.conf

在/myredis文件夹中,新建redis6379.conf,填写以下内容:

include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
daemonize yes
port 6379
logfile "6379.log"
dir ./6379

解释:

  • daemonize yes:daemonize守护线程,默认是NO、daemonize是用来指定redis是否要用守护线程的方式启动,
  • include:表示引入redis.conf的配置。
  • pidfile :使用该配置文件启动后,redis的线程id。
  • port: 使用该配置文件启动后,redis的端口。
  • logfile:使用该配置文件启动后,日志生成文件名称。
  • dir:使用该配置文件启动后,RDB和AOF数据持久化生成的文件路径。

同样的方式在/myredis文件夹中,新建redis6380.conf,填写以下内容:

include /myredis/redis.conf
pidfile /var/run/redis_6380.pid
daemonize yes
port 6380
logfile "6379.log"
dir ./6379

在/myredis文件夹中,新建redis6381.conf,填写以下内容:

include /myredis/redis.conf
pidfile /var/run/redis_6381.pid
daemonize yes
port 6381
logfile "6381.log"
dir ./6381

启动三台redis服务器在/myredis文件夹中,输入如下命令:

redis-server redis6379.conf 
redis-server redis6380.conf 
redis-server redis6381.conf 

查看系统进程,看看三台服务器是否启动:

ps -ef | grep redis

到这就通过生成三个不同的redis.conf文件启动了,三台不同的redis。

配置主从关系

在配置主从关系之前,先查看三台主机运行情况,通过如下命令连接三台主机:

redis-cli -p 端口   

连接成功后,通过如下命令查看当前redis的主从复制的相关信息:

info replication

在这里插入图片描述

可以看出在没有配置,主从关系前,上图中role:master都是主库.

配置主从关系,只需要配置从库不需要主库,也就是说从库只需要认主即可,认主的命令是:

-- 5.0之前命令
slaveof <ip> <port>
-- 5.0之后命令
replicaof <ip> <port>

通过命令的方式,只是在当前链接有效,重启redis后就不行了,如果想要一直生效,可以在对应的配置文件中添加如下内容:

# 5.0之前
slaveof <ip> <port>
# 5.0之后
replicaof <ip> <port> 
replica-read-only yes  

假设在6380和6381上执行命令或者在redis6380.conf和redis6381.conf文件中添加了内容后:

在这里插入图片描述

从上截图可以看到6380和6381的角色变成了slave。

1.2 原理解析

​ 如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC命令给master请求复制数据。master收到PSYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。

​ 当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。

全量复制:

​ 当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,redis改用可以支持部分数据复制的命令PSYNC去master同步数据,slave与master能够在网络连接断开重连后只进行部分数据复制(断点续传)。

​ master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复制。

部分复制,断点续传流程图:

​ 如果有很多从节点,为了缓解主从复制风暴(多个从节点同时复制主节点导致主节点压力过大),可以做如下架构,上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风
在这里插入图片描述

二,Redis的哨兵模式

​ 主从复制的好处是读写分离,性能扩展,容灾快速恢复,但是只有一个Master,也只有它能够写数据,当这个Master不能工作时,主从复制的集群就不能工作了,为了解决这个问题,redis引入了哨兵模式。

在这里插入图片描述

​ sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)

2.1 环境搭建

在/myredis目录下新建多个sentinel.conf文件:

vim /myredis/sentinel-26379.conf

添加如下内容:

port 26379
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir "./26379"
sentinel monitor mymaster 166.66.66.66 6379 2 
  • daemonize yes:daemonize守护线程,默认是NO、daemonize是用来指定redis是否要用守护线程的方式启动,可以查看redis.conf是如何配置的如果是NO,改为yes。
  • pidfile :使用该配置文件启动后,redis的线程id。
  • port: 使用该配置文件启动后,redis的端口。
  • logfile:使用该配置文件启动后,日志生成文件名称。
  • dir:使用该配置文件启动后,RDB和AOF数据持久化生成的文件路径。
  • sentinel monitor:表示当前redis是哨兵、mymaster是随便起的名字,136.66.66.66是监视的Master的ip,6379是监视的Master的port,2代表2位哨兵同意才可以。

启动sentinel哨兵实例

src/redis-sentinel sentinel-26379.conf 

同样的流程,可以自己再配置两个sentinel,端口26380和26381,只需要将上述配置文件名和文件内容里的对应数字都修改即可。

同样可以通过如下命令查看sentinel的info信息

> src/redis-cli -p 26379
127.0.0.1:26379>info replication

​ sentinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的最下面) 我们查看下如下配置文件sentinel-26379.conf,如下所示:

sentinel known-replica mymaster 166.66.66.66 6380 #代表主节点的从节点信息
sentinel known-replica mymaster 166.66.66.66 6381 #代表主节点的从节点信息
sentinel known-sentinel mymaster 166.66.66.66 26380 52d0a5d70c1f9043c56935760f  #代表感知到的其它哨兵节点
sentinel known-sentinel mymaster 166.66.66.66 26381 e9f53ebb8e1686438ba8bd5ca6  #代表感知到的其它哨兵节点

​ 当redis主节点如果挂了,哨兵集群会重新选举出新的redis主节点,同时会修改所有sentinel节点配置文件的集群元数据信息,比如6379的redis如果挂了,假设选举出的新主节点是6380,则sentinel文件里的集群元数据信息会变成如下所示:

sentinel known-replica mymaster 166.66.66.66 6381 #代表主节点的从节点信息
sentinel known-sentinel mymaster 166.66.66.66 26380 52d0a5d70c1f9043c56935760f  #代表感知到的其它哨兵节点
sentinel known-sentinel mymaster 166.66.66.66 26381 e9f53ebb8e1686438ba8bd5ca6  #代表感知到的其它哨兵节点

同时还会修改sentinel文件里之前配置的mymaster对应的6379端口,改为6380

sentinel monitor mymaster 166.66.66.66 6380 2 

​ 原主机重启后会变为从机,当6379的redis实例再次启动时,哨兵集群根据集群元数据信息就可以将6379端口的redis节点作为从节点加入集群,则sentinel文件里的集群元数据信息会变成如下所示:

sentinel known-replica mymaster 166.66.66.66 6379 #代表主节点的从节点信息
sentinel known-replica mymaster 166.66.66.66 6381 #代表主节点的从节点信息
sentinel known-sentinel mymaster 166.66.66.66 26380 52d0a5d70c1f9043c56935760f  #代表感知到的其它哨兵节点
sentinel known-sentinel mymaster 166.66.66.66 26381 e9f53ebb8e1686438ba8bd5ca6  #代表感知到的其它哨兵节点
2.3 原理解析

​ 哨兵的leader选举流程:当一个master服务器被某哨兵视为下线状态后,该哨兵会与其他哨兵协商选出哨兵的leader进行故障转移工作。每个发现master服务器进入下线的哨兵都可以要求其他哨兵选自己成为哨兵的leader,选举是先到先得。同时每个哨兵每次选举都会自增配置纪元(选举周期),每个纪元中只会选择一个哨兵(包含自己)成为leader。如果所有超过一半的哨兵选举某哨兵作为leader,那么之后该哨兵负责进行故障转移操作,从存活的slave中选举出新的master,这个选举过程跟集群的master选举很类似。 哨兵集群只有一个哨兵节点,redis的主从也能正常运行以及选举master,如果master挂了,那唯一的那个哨兵节点就是哨兵leader了,可以正常选举新master。 不过为了高可用一般都推荐至少部署三个哨兵节点。

​ 至于为什么要部署三个哨兵节点:主要是为了满足超过半数的原则又能节约资源,假设有2个哨兵节点,当有一个节点挂了时候,就算另一个节点参加选举,选了自己,也没有超过1不可能成为哨兵leader。假设有4个哨兵节点,当有一个节点挂了时候,还有三个哨兵节点,都选择某一个哨兵有机会超过半数的2的,可以成为哨兵leader,但是这个时候用了4个哨兵节点有点浪费资源。

三,集群模式

​ 在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异 常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现 一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持 很高的并发,且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率。

在这里插入图片描述

redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需 要sentinel哨兵∙也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中 心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的 性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。

3.1 环境搭建
3.1.1 准备多台redis

将redis的配置文件redis.conf到/myredis文件夹中:

cp redis.conf /myredis/redis.conf

编辑拷贝后的redis.conf文件,查找bing 127.0.0.1配置有没有注释掉,没有的话,自己注释了

vi /myredis/redis.conf

在/myredis文件夹中,新建redis6379.conf,填写以下内容:

include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
daemonize yes
port 6379
logfile "6379.log"
dir ./6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
# 如果要设置密码需要增加如下配置:
#设置redis访问密码
requirepass zyh
# 设置集群节点间访问密码,
masterauth zyh

解释:

  • daemonize yes:daemonize守护线程,默认是NO、daemonize是用来指定redis是否要用守护线程的方式启动,
  • include:表示引入redis.conf的配置。
  • pidfile :使用该配置文件启动后,redis的线程id。
  • port: 使用该配置文件启动后,redis的端口。
  • logfile:使用该配置文件启动后,日志生成文件名称。
  • dir:使用该配置文件启动后,RDB和AOF数据持久化生成的文件路径
  • cluster-enabled yes: 打开集群模式
  • cluster-config-file nodes-6379.conf: 设定节点配置文件名
  • cluster-node-timeout 15000: 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换

同样的流程,可以再新增几个端口6380,6381,6382,6383,6384等等,只需要将上述配置文件名和文件内容里的对应数字都修改即可,在vi命令行模式下使用%s/6379/6380命令替换更快 。

都准备好后,启动redis服务器在/myredis文件夹中,输入如下命令:

redis-server redis6379.conf 
redis-server redis6380.conf 
redis-server redis6381.conf 
redis-server redis6382.conf 
redis-server redis6383.conf 
redis-server redis6384.conf 

查看系统进程,看看服务器是否启动:

ps -ef | grep redis

到这就实现了,在一台服务器中启动多台redis。

3.1.2 构建集群

在前面我们已经启动了6台redis服务,现在我们要将这6台redis组成一个集群,redis5以前的版本集群是依靠ruby脚本redis‐trib.rb实现,这里我们使用的是redis5,可以直接使用 redis-cli命令就可以:

redis-cli --cluster create --cluster-replicas 1 166.66.66.66:6379 166.66.66.66:6380 166.66.66.66:6381 166.66.66.66:6382 166.66.66.66:6383 166.66.66.66:6384               

解析命令:

  • redis-cli --cluster create:表示构建集群。

  • --cluster-replicas 1:集群是由主从节点构成的,--cluster-replicas 1表示每个主从节点中,从节点的个数,例如上面的命令表示,一台主机,一台从机,正好三组主从节点。

  • 166.66.66.66:637*:表示参与构建集群的redis服务器。

验证集群是否构建成功:

连接任意一个客户端:

-- ‐a访问服务端密码,‐c表示集群模式,指定ip地址和端口号
./redis‐cli ‐c ‐h ‐p 

执行如下信息:

-- 查看集群信息
cluster info
-- 查看节点列表
cluster nodes
3.2 原理解析
3.2.1 插槽

​ 一个 Redis 集群包含 16384 个插槽(hash slot),数据库中的每个键都属于这16384个插槽的其中一个,当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不 一致的情况,还需要纠正机制来实现槽位信息的校验调整。

槽位定位算法:Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。 HASH_SLOT = CRC16(key) mod 16384

跳转重定位:因为槽位的信息可能会存在客户端与服务器不 一致的情况,当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令同时携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽 位映射表。例如:

166.66.66.66:6879> set name abc
-> Redirected to slot [5798] located at 166.66.66.66:6880 OK
166.66.66.66:6880>
3.2.2 通信

redis cluster节点间采取gossip协议进行通信,gossip协议包含多种消息,包括ping,pong,meet,fail等等。

  • meet:某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通 信;
  • ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping交换元数据(类似自己感知到的集群节点增加和移除,hash slot信息等);
  • pong: 对ping和meet消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新;
  • fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。 gossip协议的优点在于元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,降低了压力;缺点在于元数据更新有延时可能导致集群的一些操作会有一些滞后

gossip协议的优点在于元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上 去更新,有一定的延时,降低了压力;缺点在于元数据更新有延时可能导致集群的一些操作会有一些滞后。

​ 每个节点都有一个专门用于节点间gossip通信的端口,就是自己提供服务的端口号+10000,比如6379,那么用于节点间通信的就是16379端口。 每个节点每隔一段时间都会往另外几个节点发送ping消息,同时其他几点接收到ping消息之后返回pong消息。

网络抖动:真实世界的机房网络往往并不是风平浪静的,它们经常会发生各种各样的小问题。比如网络抖动就是非常常见 的一种现象,突然之间部分连接变得不可访问,然后很快又恢复正常。 为解决这种问题,Redis Cluster 提供了一种选项cluster-node-timeout,表示当某个节点持续 timeout 的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频繁切换 (数据的重新复制)

3.2.3 Redis集群选举原理分析

当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下:

  • slave发现自己的master变为FAIL
  • 将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST信息
  • 其他节点收到该信息,只有master会响应,会判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个 epoch只发送一次ack
  • 尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
  • slave收到超过半数master的ack后变成新Master
  • slave广播Pong消息通知其他集群节点

注意:从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待 FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票。延迟计算公式:DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms,SLAVE_RANK表示此slave已经从master复制数据的总量的rank。rank越小代表已复制的数据越新。这种方式下持有最新数据的slave将会首先发起选举(理论上)。

3.2.4 集群脑裂数据丢失问题

redis集群没有过半机制会有脑裂问题,网络波动导致新选出的master和以前由于网络波动以为死亡的master节点都能对外提供写服务,一旦网络恢复,其中一个主节点将变为从节点,但是,这个主节点也对外提供了写服务,如果变成从节点会有大量数据丢失。 规避方法可以在redis配置里加上参数

 # 写数据成功最少同步的slave数量,这个数量可以模仿大于半数机制配置,# 比如主从集群总共三个节点,那就可以配置1,这时只要一个slave节点同步了数据,加上master节点,超过了半数 min‐replicas‐to‐write 1

注意:

  • 这种方法不可能百分百避免数据丢失,因为虽然保证了由一半的slave节点同步了数据,但是并不能保证,master节点是从这一半的slave节点中选出的。
  • 这个配置在一定程度上会影响集群的可用性,比如slave要是少于1个,这个主从集群就算master正常也不能提供服务了,所以需要具体场景权衡选择。
3.2.5 集群是否完整才能对外提供服务

当redis.conf的配置cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用(插槽值不落在故障插槽库可用),如果为yes则集群不可用,不管插槽值落不落在故障插槽库都不可用。

3.3.5 Redis集群对批量操作命令的支持

对于类似mset,mget这样的多个key的原生批量操作命令,redis集群只支持所有key落在同一slot的情况,如果有多个key一定要用mset命令在redis集群上操作,则可以在key的前面加上{XX},这样参数数据分片hash计算的只会是大括号里的值,这样能确保不同的key能落到同一slot里去,示例如下:

mset {user}:name zyh {user}:age 18 

假设{user}:name{user}:age计算的hash slot值不一样,但是这条命令在集群下执行,redis只会对大括号里的user做hash slot计算,所以算出来的slot值肯定相同,最后都能落在同一slot。

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

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

相关文章

ModStartCMS v8.1.0 图片前端压缩,抖音授权登录

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

手机AI摄影时代开启,传音引领行业标准化建设

今年春节&#xff0c;AI摄影可谓大出风头。人们在社交平台晒出自己在龙年的AI写真&#xff0c;极大地增添了节日的氛围感&#xff0c;也让我们看到了“AI摄影”的价值。新年伊始&#xff0c;手机巨头们纷纷布局该赛道&#xff0c;基于AI大模型实现的影像功能成为业界关注焦点。…

Java Web(十)--jQuery

介绍 官网文档&#xff1a;jQuery 教程 jQuery API 中文文档 | jQuery API 中文在线手册 | jquery api 下载 | jquery api chm 下载地址&#xff1a;https://jquery.com/download/%20jQuery jQuery 是一个快速的&#xff0c;简洁的 javaScrip工具库&#xff0c;使用户能更方…

C语言 变量

变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有特定的类型&#xff0c;类型决定了变量存储的大小和布局&#xff0c;该范围内的值都可以存储在内存中&#xff0c;运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头…

全网最新的软件测试面试八股文

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 测试技术面试题 1、什么是兼容性测试&#xff1f;兼容性测试侧…

一、前端开发

#视频链接&#xff1a;https://www.bilibili.com/video/BV1rT4y1v7uQ?p1&vd_source1717654b9cbbc6a773c2092070686a95 前端开发 前端开发1、快速开发网站2、浏览器能识别的标签2.1 编码&#xff08;head&#xff09;2.2 title(head)2.3 标题2.4 div和span练习题2.5 超链接…

03|索引优化

数据准备 创建联合索引 KEY idx_name_age_position (name,age,position) USING BTREE CREATE TABLE employees (id int(11) NOT NULL AUTO_INCREMENT,name varchar(24) NOT NULL DEFAULT COMMENT 姓名,age int(11) NOT NULL DEFAULT 0 COMMENT 年龄,position varchar(20) NO…

内存操作函数(c语言)

目录 概述1. memcpy函数2.memcpy函数的模拟实现3. memcmp函数4.memcmp函数的模拟实现5. memset函数6.memset函数的模拟实现7. memmove函数8.memmove函数的模拟实现结语 概述 C语言提供了一些非常有用的内存操作函数&#xff0c;其中包括memcpy、memcmp、memset和memmove。这些…

MQTT简介

https://mqtt.org/ MQTT&#xff08;Message Queuing Telemetry Transport&#xff09; 一种轻量级的&#xff0c;基于发布订阅模式的通信协议&#xff0c;用于在物联网和机器与机器&#xff08;M2M&#xff09;通信中传输消息。 它具有低带宽和低功耗的特点&#xff0c;适用于…

vue3 开发记录

1.引入nprogress插件&#xff0c;显示未声明文件 无法找到模块“nprogress”的声明文件。 解决方法&#xff1a; vite-env.d.ts // 解决引入模块的报错提示 declare module "nprogress";2.在 .evn 文件中创建了自定义环境变量 VITE_APP_BASE_URL 但在项目中使用时出…

【学习记录】Resnet

Resnet的残差块 BasicBlock模块&#xff1a; Resnet的作用 解决梯度消失。网络越深&#xff0c;会导致梯度消失。Resnet可以解决梯度消失的问题。 Resnet的原理 参考视频&#xff1a;https://www.bilibili.com/video/BV1cM4y117ob/?spm_id_from333.337.search-card.all.cl…

请查收:2024年腾讯云服务器优惠价格表_租用配置报价

一张表看懂腾讯云服务器租用优惠价格表&#xff0c;一目了然&#xff0c;腾讯云服务器分为轻量应用服务器和云服务器CVM&#xff0c;CPU内存配置从2核2G、2核4G、4核8G、8核16G、4核16G、8核32G、16核32G、16核64等配置可选&#xff0c;公网带宽1M、3M、5M、12M、18M、22M、28M…

FreeRTOS任务切换

目录 一、PendSV异常 二、任务切换场合 1、执行系统调用 2、滴答定时器(SysTick)中断 三、PendSV中断服务函数 1、分析xPortPendSVHandler中断服务函数 四、查找下一个要运行的任务的两种方法 1、获取下一个要运行的任务 2、查找下一个要运行的任务的两种方法 2.1、通…

Windows系统安装TortoiseSVN并结合内网穿透实现远程访问本地服务器——“cpolar内网穿透”

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

ThreeDWorld(TDW)学习(待更新)

目录 前言 1.TDW 2.transport challenge 总结 前言 因为挑战赛了解到tdw仿真平台。 想了解的请点击&#xff1a; GitHub - threedworld-mit/tdw: ThreeDWorld simulation environment GitHub - chuangg/tdw-transport-challenge-starter-code 1.TDW ThreeDWorld (TDW)是一…

数据卷dockerfile

目录 一、数据卷 1. 简介 2. 数据卷和数据卷容器 1. 数据卷&#xff1a; 2. 数据卷容器&#xff1a; 二、自定义镜像 1. 作用 2. 自定义centos 3. 自定义tomcat8 一、数据卷 1. 简介 数据卷是一个可供一个或多个容器使用的特殊目录&#xff0c;它将主机操作系统目录直…

mysql修改字段的长度锁表问题

mysql修改字段的长度锁表问题 背景 MySQL&#xff08;这里指5.6及其后续版本&#xff09;修改字段的长度锁表会锁表吗&#xff1f;答案是可能会但不一定会 具体原理 MySQL 5.6 及以后版本扩大字段长度 支持 online ddl in-place 模式&#xff0c;而这将不会锁表。varchar 表示…

string字符串进行分割

c标准库中&#xff0c;对string字符串并没有提供分割操作&#xff0c;需要自己手动实现此功能。 方式1&#xff1a; 采用 std::stringstream 输入字符串&#xff0c;通过getline()函数&#xff0c;来对字符串进行分割。 #include <sstream>void getSplit(std::string s…

Unity—MVC分层开发思想

每日一句&#xff1a;当你不努力的时候&#xff0c;天赋就会一点一点被收回 目录 MVC分层开发思想 MVC是什么 MVC的开发步骤 案例&#xff1a;点击按钮实现金币进行添加&#xff0c;并且把金币记录到JSON里 MVC模式实现 背包系统基础代码 背包项目实现步骤 MVC分层开发思…

【vue+element ui】大屏自适应中el-select下拉内容在低分辨率下显示不全问题解决

目录 背景 现象 解决方案 背景 最近要把一个1920px*1080px的大屏改成自适应的&#xff1b;最低适配到1028px*720px&#xff1b; 现象 自适应适配改完之后 将电脑屏幕改成1028px*720px分辨率后&#xff0c;下拉显示正常 通过谷歌浏览器设置Toggle device toolbar为1028px*…