Redis集群相关

目录

一、Redis主从集群

主从数据同步原理

全量同步

1)为什么是基本一致而不是完全一致呢?

2)上述过程还有一个问题,怎么判断是不是第一次同步?

增量同步

1)master节点怎么知道slave节点与自己的数据差异在哪里呢?

2)那么如何减少repl_baklog大小上限超出问题的出现呢?

全量同步和增量同步的区别

二、Redis哨兵

背景

哨兵工作原理

1)Sentinel怎么知道一个Redis节点是否宕机呢?

主观下线

客观下线

2)如何选举新的master?

3)如何实现故障转移?

三、Redis分片集群

背景

散列插槽

插槽原理

1)那为什么要做这个插槽呢?

2)那为什么数据key要与插槽绑定而不是与节点绑定?

3)Redis如何判断某个key应该在哪个实例?

4)如何将同一类数据固定的保存在同一个Redis实例?

集群伸缩

故障转移

手动转移


一、Redis主从集群

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。

主从数据同步原理

全量同步

主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点。

具体流程:判断是否是第一次同步,如果是,返回版本信息(replication id 和offset),将salve节点的版本信息变为master的,随后进行全量同步。全量同步,即为进行bgsave命令进行异步生成RDB快照并发送给salve节点,salve节点拿到RDB快照之后就等于拿到了master主节点的数据,接下来把salve节点自己本地的数据情清空,然后把RDB快照加载到内存中。此时就能确保主从节点上的数据基本一致。

1)为什么是基本一致而不是完全一致呢?

因为在生成RDB快照过程中,主进程还可能会去处理用户的请求,就意味着还可能在新的数据写入。这些写操作会进入repl_baklog缓冲区,repl_baklog缓冲区里记录的就是在这个RDB期间收到的一些新的写命令。最后把这些写命令也发送给slave节点,就完成了主从数据的一致。

2)上述过程还有一个问题,怎么判断是不是第一次同步?

判断依据:

  • Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid。
  • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

因此slave节点做数据同步,必须向master节点声明自己的replication id 和offset,master节点才可以判断到底需要同步哪些数据。

因为slave节点原本也是一个master节点,有自己的replid和offset,(宕机重启后)当第一次变成slave节点,与master节点建立连接时,发送的replid和offset是自己的replid和offset。master节点判断发现slave节点发送来的replid与自己的不一致,说明这是一个全新的slave节点,就知道要做全量同步了。master节点会将自己的replid和offset都发送给这个slave节点,slave节点保存这些信息。以后slave节点的replid就与master节点一致了。因此,master节点判断一个节点是否是第一次同步的依据就是看replid是否一致

因此,完整流程描述如下:

  1. slave节点请求增量同步。
  2. master节点判断replid,发现不一致,拒绝增量同步。
  3. master节点将完整内存数据生成RDB,发送RDB到slave节点。
  4. slave节点清空本地数据,加载master的RDB节点。
  5. master节点将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave节点。
  6. slave节点执行接收到的命令,保持与master节点之间的同步。

增量同步

全量同步需要先做RDB,然后将RDB文件通过网络传输给slave节点,成本太高了。因此除了第一次做全量同步,其它大多数时候slave节点与master节点都是做增量同步。

什么是增量同步?就是只更新slave节点与master节点存在差异的部分数据。即只用更新offset后的命令即可,offset之后的命令就是主从之间的数据差异,只更新这部分即可。

1)master节点怎么知道slave节点与自己的数据差异在哪里呢?

这就要说到全量同步时的repl_baklog文件了。这个repl_baklog文件是一个固定大小的数组,只不过数组是环形,也就是说角标到达数组末尾后,会再次从0开始读写,这样数组头部的数据就会被覆盖。

repl_baklog中会记录Redis处理过的命令日志及offset,包括master节点当前的offset、slave已经拷贝到的offset,即主从之间的offset差就是要同步到从节点的数据。

随着不断有数据写入,master节点的offset逐渐变大,记录的最新位置就是master节点当前的offset。同时slave节点也不会去做数据同步,同步的位置就是slave的offset,追赶master节点的offset。因此,slave节点与master节点的offset之间的差异,就是salve节点需要增量拷贝的数据了。

所以可以理解成,repl_baklog其实就是slave节点与master节点之间的数据差异的一个缓冲区。只要slave节点与master节点之间的数据差异不超过这个环的存储上限,那你永远都能够这个环里找到你所需要的数据,永远能实现增量同步。

但是如果slave节点与master节点之间的数据差异差太多,已经超过这个环的存储上限,那么这个时候就没办法做增量同步了。

我们继续分析,直到数组被填满,

此时,如果有新的数据写入,就会覆盖数组中的旧数据。不过,旧的数据只要是绿色的,说明是已经被同步到slave的数据,即便被覆盖了也没什么影响。因为未同步的仅仅是红色部分。

但是,如果slave出现网络阻塞,导致master的offset远远超过了slave的offset,马上就要超过这个个环的上限。如果master继续写入新数据,其offset就会覆盖旧的数据,直到将slave现在的offset也覆盖,注意此时master已经覆盖了从节点尚未同步过去的数据,这就出现了主从之间数据的不一致。

棕色框中的红色部分,就是尚未同步,但是却已经被覆盖的数据。此时如果slave恢复,需要同步,却发现自己的offset都没有了,无法完成增量同步了。只能做全量同步。  这就保证了主从数据的一致性。

总结一下,repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导
致尚未备份的数据被覆盖,则无法基于log做增量同步,只能再次全量同步。

2)那么如何减少repl_baklog大小上限超出问题的出现呢?

主从同步可以保证主从数据的一致性,非常重要。 可以从以下几个方面来优化Redis主从就集群:

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,直接通过网络传输,把数据发送给从节点,只适用于网络较快的设备,这样就能避免全量同步时的磁盘IO,提高全量同步的性能。
  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO,提高全量同步的性能。
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步。
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力。

全量同步和增量同步的区别

(1)全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。

什么时候执行全量同步?

  • slave节点第一次连接master节点时。
  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖时。

(2)增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave

什么时候执行增量同步?

  • slave节点断开又恢复,并且在repl_baklog中能找到offset时。

 

二、Redis哨兵

背景

主从结构中,如果一个slave节点宕机,根本不用担心。因为只要这个slave节点重启,就能从master节点上完成数据同步恢复数据。

那如果宕机的不是slave节点而是master节点呢?如果说已经做了master节点的持久化,那master节点重启是可以解决这个问题的,数据也不会丢失。但是如果说在master节点宕机的这段时间内,还有在重启数据恢复的过程中,由于目前master节点是宕机状态,用户是无法执行写操作,也就意味着这个集群的可用性就下降了。

那么有什么办法能保证主从集群的高可用性呢?我们只需要去监控集群中的节点状态, 当发现master节点宕机的那一刻,立即选出一个新的slave节点作为新的master节点,因为这个slave节点本身一直在数据同步,有完整的数据,把它变成master节点很容易,这个时候我们整个集群依然是健康的,不仅可以进行读操作还可以写操作。至于那个宕机的master节点,将来等它启动之后变成slave节点就可以了。

这样就实现了主从切换,也就意味着这个集群的高可用性可以得到一个很好的保障。

但是这个监测和重启的动作谁来做呢?Redis主从模式当主服务器宕机后,需要手动把一台从服务器切换为主服务器,需要人工干预费事费力,为了解决这个问题出现了哨兵模式

哨兵工作原理

Redis提供了哨兵Sentinel)机制来监控主从集群监控状态,确保集群的高可用性。

哨兵的作用如下:

  • 状态监控:Sentinel 会不断检查您的master和slave是否按预期工作。
  • 故障恢复(failover):如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后会成为slave。
  • 状态通知:Sentinel充当Redis客户端的服务发现来源,当集群发生failover时,会将最新集群信息推送给Redis的客户端。

那么问题来了,

1)Sentinel怎么知道一个Redis节点是否宕机呢?

Sentinel基于心跳机制监测服务状态。每个Sentinel会每秒钟 一次的频率向它所知的主服务器、从服务器以及其他Sentinel实例发送一个PING命令,获取其拓扑结构和状态信息。然后通过实例的响应结果来做出判断,来确认这些节点是否可达,共同监控数据节点的运行状况。

  • 主观下线(sdown):如果某sentinel节点发现某Redis节点未在规定时间响应,则认为该节点主观下线。
  • 客观下线(odown):若超过指定数量(通过quorum设置)的sentinel都认为该节点主观下线,则该节点客观下线。quorum值最好超过Sentinel节点数量的一半,Sentinel节点数量至少3台。

主观下线

如果某个sentinel节点发现某实例未在规定的时间内(down-after-milliseconds)响应,则认为实例下线了。这种下线是主观下线。

哨兵每秒向所有与它创建命令连接的实例(包括主服务器、从服务器、其他sentine)发送PING命令,并通过实例返回的PING命令回复来判断是否在线。收到的有效回复为:+PONG、-LOADING、-MASTERDOWN命令。其余的都是无效回复(也包括没有回复的)。

如果在down-after-milliseconds毫秒以内,sentinel收到的都是无效回复,那么这个sentinel就会认为实例进入主观下线状态,同时修改实例结构中的flags属性,改为SRI_S_DOWN(主观下线)。

down-after-milliseconds毫秒不仅会成为sentinel判断master进入主观下线的标准,还会成为sentinel判断master属下所有从服务器,以及所有同样监视master的其他sentinel进入主观下线的依据。

客观下线

如果超出指定数量(quorum)的sentinel都认为该实例主观下线,则该实例就。quorum值最后超过sentinel实例数量的一半。

当sentinel将一个主服务器判断为主观下线后,为了确认这个主服务器是否真的下线了,它(当前这个sentinel)会向同样监视这一主服务器的其他sentinel进行询问,看看它们是否也认为当前主服务器已经进入了下线状态(无论是主观的还是客观的)。

根据其他sentinel回复的SENTINEL is-master-down-by-addr命令,sentinel将统计其他sentient是否同意主服务器已经下线的数量。当这个数量达到配知道你个判断客观所需要的数量时候,也就是当sentinel从其他sentinel那接收到足够数量的已下线判断之后,sentient会将主服务器实例结构flags属性的SRI_O_DOWN标识打开,标识主服务器已经进入客观下线状态,并对主服务器执行故障专业操作。

2)如何选举新的master?

一旦发现master故障,sentinel需要在salve中选择一个作为新的master。

选择依据是这样的:

首先会判断slave节点与master节点断开时间长短,如果断开时间超过down-after-milliseconds * 10,因为断开时间越长证明丢失的数据越多,则就会直接排除该slave节点,它就不具有选举权。这样就可以排除掉一部分数据是旧的slave节点。

然后判断slave节点的slave-priority值(默认都是1),这个slave-priority值越小优先级越高,如果是0则永不参与选举。

如果slave-prority一样,则判断slave节点的offset值,代表当前slave节点与master节点之间数据同步的进度,offset值越大证明这个当前slave节点与master节点之间的数据月接近,说明数据越新,优先级越高。因为我们要优先保证数据的完整性。

假设所有的slave节点的offset值都一样,那最后是判断slave节点的run_id大小,这个run_id(通过info server可以查看run_id)是在slave节点启动时的那一刻由Reids自动生成的一个id。这个run_id其实大小并不重要,此时我们就随便挑一个,run_id越小优先级越高。

那么,问题来了,当选出一个新的master后,该如何实现身份切换呢?

3)如何实现故障转移?

当选中了其中一个slave为新的master后(例如slavel),故障的转移的步骤如下:

假设现在的master宕机了,此时slave节点7002被选择作为新的master节点。

那么在做故障转移的时候,第一步sentinel会向salve节点发起一个请求,告诉salve节点去执行slaveof no one 命令,执行命令之后这个salve节点就会成为master节点。

第二步就是广播,sentinel给所有其他的slave节点发送slaveof xxx.xxx.xx.xx 端口。比如我们新master节点是192.168.1.11 7002,那么命令就是 slaveof 192.168.1.11 7002命令,让这些slave成为新master的从节点,开始从新master上同步数据。

最后,sentinel会强制修改故障节点的配置文件,在配置文件中设置slaveof 192.168.1.11 7002命令,也就是把它标记为slave。一旦配置文件修改了之后,当故障节点恢复后自动成为新master的slave节点。

此时,所有的slave就都成为了新master的从节点,整个主从切换就完成了。

三、Redis分片集群

背景

主从集群可以去应对Redis的高可用、高并发读的问题。但是Redis主从之间也会做同步,为了提高主从同步的性能,我们单节点的Redis的内存设置不能太高。如果内存占用过多,在RDB持久化的时候或者做全量同步的时候,会导致大量的IO,性能会下降。

那如果单节点的Redis的内存上限降低了,那如果有海量数据存储需要存储的时候怎么办?遇到了高并发写的问题该如何解决?

总结就是,但依然有两个问题没有解决:

  • 海量数据存储

  • 高并发写

要解决这两个问题就需要用到分片集群了。分片的意思就是把数据拆分存储到不同节点,这样整个集群的存储数据量就更大了。

分片集群特征:

  • 集群中有多个master,每个master保存不同分片数据 ,解决海量数据存储问题。同时每个master都可以写操作,并发写能力也得到提升。
  • 每个master都可以有多个slave节点 ,同时具备了主从集群的特性,确保高可用。
  • master之间通过ping监测彼此健康状态 ,类似哨兵作用。
  • 客户端请求可以访问集群任意节点,最终都会被转发到数据所在节点。

散列插槽

插槽原理

Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到,

1)那为什么要做这个插槽呢?

既然每个master都可以存储数据,那存储到哪一个里面,以后怎么取。插槽就是来解决这个问题的。

数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:

  • key中包含"0",且“0”中至少包含1个字符,,“0!”中的部分是有效部分。
  • key中不包含“!”,整个key都是有效部分。

例如,key是num,那么就根据num计算,如果是{itcast}num,有效部分就是itcast,则根据itcast计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。

2)那为什么数据key要与插槽绑定而不是与节点绑定?

正因为Redis的master节点是可能出现宕机情况的,或者是集群扩容增加了节点,或者是集群伸缩删除了节点。那如果一个节点删除或者宕机了,节点上面的数据也会跟着丢失。

而如果数据是与插槽绑定,那当节点删除或者宕机时,可以将这个节点对应的插槽转移到活着的节点。集群扩容时也可以将插槽进行转移。这样数据跟着插槽走就永远可以找到数据所在的位置。

3)Redis如何判断某个key应该在哪个实例?
  1. 将16384个插槽分配到不同的实例。
  2. 根据key的有效部分计算哈希值,对16384取余。
  3. 余数作为插槽,寻找插槽所在实例即可。

如图,在7001这个节点执行set a 1时,对a做hash运算,对16384取余得到的结果是15495,而15495槽是在7003这个节点上,因此此时会重定向到7003节点取值。在7003节点执行 get a就可以拿到a对应的value值1。在7003节点执行get num命令时,对num做hash运算,对16384取余,得到的结果是2765,因此会重定向到7001节点取值。

4)如何将同一类数据固定的保存在同一个Redis实例?

这一类数据使用相同的有效部分,例如key都以{typeld}为前缀。

集群伸缩

redis-cli --cluster提供了很多操作集群的命令,可以通过下面方式查看:

 比如,添加节点的命令:

故障转移

分片集群虽然没有哨兵机制,但是也具有故障转移的功能。

当集群中有一个master宕机会发生什么呢?

  1. 首先是该实例与其它实例失去连接。
  2. 然后是疑似宕机。
  3. 最后是确定下线,自动提升一个slave为新的master。

手动转移

利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。

大致的流程:在一个slave节点上执行cluster failover命令,那么这个slave节点对应的master节点会被替换掉,这个slave节点会成为新的主节点,而那个对应的master节点会成为从节点。

具体流程如下:

手动的Failover支持三种不同模式:

  • 缺省:默认的流程,如图1~6歩
  • force:省略了对offset的一致性校验
  • takeover:直接执行第5歩,忽略数据一致性、忽略master状态和其它master的意见

当在一个slave节点上执行cluster failover命令的时候,slave节点会向master节点发一个消息,告诉master节点我要替换你了。这个时候为了避免消息的丢失,master节点会拒绝客户端的一切请求,返回当前的offset值给slave节点,告诉slave节点我现在的数据已经最新到这个位置了。

此时,slave节点和master节点会检查当前的这个offset值是否一致。如果slave节点和master节点的数据不一致,slave节点会进行数据同步。数据同步完成之后,slave节点和master节点数据就会完全一致(因为此时已经不接收新的客户端请求了)。

数据完全一致之后,就可以进行故障转移了。完成之后,让slave把自己标记成一个master,广播通知集群中的每一个节点。当集群中的每一个节点收到消息之后,以后就和这个新的master节点做交互。并且原来的那个master节点接收到消息之后,就会知道与新的master节点之间的数据同步和转移已经结束了,会转为一个slave节点。

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

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

相关文章

初学者如何快速入门人工智能

一、引言 人工智能(Artificial Intelligence,简称AI),作为当今科技领域极具前景与影响力的方向之一,吸引着众多人士投身其中。无论是对科技充满好奇的学生,还是意图拓展职业发展路径的职场人士&#xff0c…

STM32 USB CUBEMX

开发背景 使用的平台:STM32H750 注意事项 时钟必须是48MHZ,其它都不行 2. 将默认任务的堆栈设大一点 如果使用操作系统,USB任务跑在默认任务里,因此需要设置默认任务的堆栈缓存是直接定义的全局变量,需要设置编译器…

Spring Boot常见错误与解决方法

White graces:个人主页 🙉专栏推荐:Java入门知识🙉 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 目录 创建第一个SpringBoot项目 SpringBoot项目各个…

基于神经协同过滤(Neural Collaborative Filtering,NCF)的算法

论文题目:Neural Collaborative Filtering∗ 论文地址:https://arxiv.org/abs/1708.05031 今天我要分享一篇关于深度学习在推荐系统中应用的经典论文,题为“基于神经协同过滤(Neural Collaborative Filtering,NCF&…

如何去除背景音乐保留人声?保留人声,消除杂音

在日常生活和工作中,我们经常遇到需要处理音频的情况,尤其是当我们想要去除背景音乐,仅保留人声时。这种需求在处理电影片段、制作音乐MV、或者提取演讲内容等场景中尤为常见。本文将为您详细介绍如何去除背景音乐并保留人声,帮助…

组合式API有什么好处

什么是组合式API? 组合式 API (Composition API) 是一系列 API (响应式API、生命周期钩子、依赖注入)的集合。它不是函数式编程,组合式 API 是以 Vue 中数据可变的、细粒度的响应性系统为基础的,而函数式编程通常强调…

论文笔记:Prototypical Verbalizer for Prompt-based Few-shot Tuning

论文来源:ACL 2022 论文地址:https://arxiv.org/pdf/2203.09770.pdfhttps://arxiv.org/pdf/2203.09770.pdf 论文代码:https://github.com/thunlp/OpenPrompthttps://github.com/thunlp/OpenPrompt Abstract 基于提示的预训练语言模型&#…

数据结构——遍历二叉树

目录 什么是遍历二叉树 根据遍历序列确定二叉树 例题(根据先序中序以及后序中序求二叉树) 遍历的算法实现 先序遍历 中序遍历 后序遍历 遍历算法的分析 二叉树的层次遍历 二叉树遍历算法的应用 二叉树的建立 复制二叉树 计算二叉树深度 计算二…

VR全景摄影的拍摄和编辑软件推荐

随着虚拟现实技术的不断进步,VR全景摄影逐渐成为商业、娱乐和教育等多个领域中的重要工具。通过专业的设备与软件,摄影师能够创作出沉浸式的360度全景作品,为观众提供身临其境的视觉体验。在这篇文章中,我们将介绍VR全景摄影的相关…

(接口测试)day01接口测试理论 http理论 接口测试流程 接口文档解析

一.接口测试理论 1.接口和接口测试 服务器为客户端开了一个验证接口(接口本质:函数方法)客户端向服务器传送的消息可以相当于函数的参数,接口是用来让客户端传递数据的 接口:相当于开了一个通道 当服务器要给客户端响…

yjs机器学习常见算法01——KNN(K—近邻算法)

1.K—近邻算法 的含义: 简单来说就是通过你的邻居的“类别”,来推测你的“类别” 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最临近)的样本中大多数属于某一类别,则该样本也属于这个类别。 2.…

猫头虎分享:什么是 ChatGPT 4o Canvas?

猫头虎是谁? 大家好,我是 猫头虎,猫头虎技术团队创始人,也被大家称为猫哥。我目前是COC北京城市开发者社区主理人、COC西安城市开发者社区主理人,以及云原生开发者社区主理人,在多个技术领域如云原生、前端…

独家创作YOLOv8韭菜检测系统(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测)

1.简介:资源包含可视化的韭菜检测系统,可检测图片和视频当中出现的韭菜,以及自动开启摄像头,进行韭菜检测。基于最新的YOLO-v8训练的韭菜检测模型和完整的python代码以及韭菜的训练数据,下载后即可运行。 2.文件夹介绍…

怎么找矩阵系统,怎么源码搭建,源头技术开发需要哪些支持

一、引言 在进行矩阵系统源码搭建时,选择合适的工具至关重要。正确的工具选择不仅可以提高开发效率,还能确保系统的稳定性、可扩展性和性能。本文将探讨在矩阵系统源码搭建过程中如何选择合适的工具。 二、前端开发工具选择 前端框架 React:由…

【智能大数据分析 | 实验三】Storm实验:实时WordCountTopology

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘,以提取有价值的信息和洞察。它结合了大数据技术、人工智能(AI)、机器学习(ML&a…

手机、固话号码想要认证,需要显示企业名称该怎么设置?

在现如今激烈竞争的商业环境中,依然有越来越多的企业意识到品牌的力量与价值,作为吸引客户关注、打造客户第一印象的关键环节。如何让企业外呼号码展示品牌与企业名称就变得格外关键。 那么手机、固话号码申请号码品牌认证究竟是什么?申请的…

使用CSS Flexbox创建简洁时间轴

使用CSS Flexbox创建简洁时间轴 在网页设计中,时间轴是一种常见且有效的方式来展示事件的顺序和进程。本文将介绍如何使用CSS Flexbox创建一个简洁优雅的时间轴,无需复杂的JavaScript代码。 基本HTML结构 首先,我们需要创建基本的HTML结构: html复制<div class"ti…

IT招聘乱象的全面分析

近年来&#xff0c;IT行业的招聘要求似乎越来越苛刻&#xff0c;甚至有些不切实际。许多企业在招聘时&#xff0c;不仅要求前端工程师具备UI设计能力&#xff0c;还希望后端工程师精通K8S服务器运维&#xff0c;更有甚至希望研发经理掌握所有前后端框架和最新开发技术。这种招聘…

AI大模型是怎么运作的?深入解析

在当今这个日新月异的科技时代&#xff0c;人工智能&#xff08;AI&#xff09;如同一位隐形的助手&#xff0c;悄然渗透进我们生活的方方面面&#xff0c;其影响力日益显著。这位“隐形助手”背后的工作原理究竟是怎样的呢&#xff1f;接下来&#xff0c;本文将从AI的基本原理…

随机多智能体系统中的自然策略能力

本文探讨了在随机多智能体系统中采用自然策略进行PATL及PATL逻辑的模型检验问题。研究发现&#xff0c;当活跃联盟被限于确定性策略时&#xff0c;NatPATL的模型检验问题是NP完全的&#xff1b;在同样的限制条件下&#xff0c;NatPATL的复杂度则为2NEXPTIME。若不限制策略类型&…