分布式协调服务--zookeeper

news2024/11/17 22:37:20

目录

一、概述

1、zookeeper有两种运行状态

zookeeper架构的角色:

2、Paxos算法:消息传递的一致性算法

3、ZAB协议

Zab 协议实现的作用

Zab协议核心

Zab协议内容

消息广播

崩溃恢复

实现原理

协议实现


一、概述

zookeeper官网

zookeeper官网学习

1、zookeeper有两种运行状态

1、有leader模型

2、无leader模型

即:不可用状态

官方压测:从无主模型恢复到有主模型时间在200毫秒内

从这张图中可以看出一些重要的观察结果。首先,如果追随者失败并迅速恢复,那么ZooKeeper能够在失败的情况下保持高吞吐量。但也许更重要的是,领导人选举算法允许系统足够快地恢复,以防止吞吐量大幅下降。根据我们的观察,ZooKeeper只需要不到200毫秒的时间就可以选出新的领导者。第三,随着追随者的恢复,ZooKeeper能够在他们开始处理请求后再次提高吞吐量。

zookeeper是一个目录树结构!

node可以存数据1MB。

docker中搭建zookeeper集群 预留

zookeeper架构的角色:

  1. Leader
  2. Follower:只有Follower才能选举
  3. Observer:放大查询能力

zookeeper可靠性:快速恢复Leader、数据可靠可用一致性、攘外必先安内。

2、Paxos算法:消息传递的一致性算法

原文链接:https://www.douban.com/note/208430424/
        Paxos:它是一个基于消息传递的一致性算法,Leslie Lamport在1990年提出,近几年被广泛应用于分布式计算中,Google的Chubby,Apache的Zookeeper都是基于它的理论来实现的,Paxos还被认为是到目前为止唯一的分布式一致性算法,其它的算法都是Paxos的改进或简化。有个问题要提一下,Paxos有一个前提:没有拜占庭将军问题。就是说Paxos只有在一个可信的计算环境中才能成立,这个环境是不会被入侵所破坏的。
        Paxos描述了这样一个场景,有一个叫做Paxos的小岛(Island)上面住了一批居民,岛上面所有的事情由一些特殊的人决定,他们叫做议员(Senator)。议员的总数(Senator Count)是确定的,不能更改。岛上每次环境事务的变更都需要通过一个提议(Proposal),每个提议都有一个编号(PID),这个编号是一直增长的,不能倒退。每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生效。每个议员只会同意大于当前编号的提议,包括已生效的和未生效的。如果议员收到小于等于当前编号的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上面记录的编号,他不断更新这个编号。整个议会不能保证所有议员记事本上的编号总是相同的。现在议会有一个目标:保证所有的议员对于提议都能达成一致的看法。  
        好,现在议会开始运作,所有议员一开始记事本上面记录的编号都是0。有一个议员发了一个提议:将电费设定为1元/度。他首先看了一下记事本,嗯,当前提议编号是0,那么我的这个提议的编号就是1,于是他给所有议员发消息:1号提议,设定电费1元/度。其他议员收到消息以后查了一下记事本,哦,当前提议编号是0,这个提议可接受,于是他记录下这个提议并回复:我接受你的1号提议,同时他在记事本上记录:当前提议编号为1。发起提议的议员收到了超过半数的回复,立即给所有人发通知:1号提议生效!收到的议员会修改他的记事本,将1好提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法令并告诉对方:1元/度。  
        现在看冲突的解决:假设总共有三个议员S1-S3,S1和S2同时发起了一个提议:1号提议,设定电费。S1想设为1元/度, S2想设为2元/度。结果S3先收到了S1的提议,于是他做了和前面同样的操作。紧接着他又收到了S2的提议,结果他一查记事本,咦,这个提议的编号小于等于我的当前编号1,于是他拒绝了这个提议:对不起,这个提议先前提过了。于是S2的提议被拒绝,S1正式发布了提议: 1号提议生效。S2向S1或者S3打听并更新了1号法令的内容,然后他可以选择继续发起2号提议。  
        好,我觉得Paxos的精华就这么多内容。现在让我们来对号入座,看看在ZK Server里面Paxos是如何得以贯彻实施的。  
小岛(Island)——ZK Server Cluster  
议员(Senator)——ZK Server  
提议(Proposal)——ZNode Change(Create/Delete/SetData…)  
提议编号(PID)——Zxid(ZooKeeper Transaction Id)  
正式法令——所有ZNode及其数据  
        貌似关键的概念都能一一对应上,但是等一下,Paxos岛上的议员应该是人人平等的吧,而ZK Server好像有一个Leader的概念。没错,其实Leader的概念也应该属于Paxos范畴的。如果议员人人平等,在某种情况下会由于提议的冲突而产生一个“活锁”(所谓活锁我的理解是大家都没有死,都在动,但是一直解决不了冲突问题)。Paxos的作者Lamport在他的文章”The Part-Time Parliament“中阐述了这个问题并给出了解决方案——在所有议员中设立一个总统,只有总统有权发出提议,如果议员有自己的提议,必须发给总统并由总统来提出。好,我们又多了一个角色:总统。  
总统——ZK Server Leader
又一个问题产生了,总统怎么选出来的?
现在我们假设总统已经选好了,下面看看ZK Server是怎么实施的。  
情况一:  
居民甲(Client)到某个议员(ZK Server)那里询问(Get)某条法令的情况(ZNode的数据),议员毫不犹豫的拿出他的记事本(local storage),查阅法令并告诉他结果,同时声明:我的数据不一定是最新的。你想要最新的数据?没问题,等着,等我找总统Sync一下再告诉你。  
情况二:  
居民乙(Client)到某个议员(ZK Server)那里要求政府归还欠他的一万元钱,议员让他在办公室等着,自己将问题反映给了总统,总统询问所有议员的意见,多数议员表示欠屁民的钱一定要还,于是总统发表声明,从国库中拿出一万元还债,国库总资产由100万变成99万。居民乙拿到钱回去了(Client函数返回)。  
情况三:  
总统突然挂了,议员接二连三的发现联系不上总统,于是各自发表声明,推选新的总统,总统大选期间政府停业,拒绝居民的请求。  
呵呵,到此为止吧,当然还有很多其他的情况,但这些情况总是能在Paxos的算法中找到原型并加以解决。这也正是我们认为Paxos是Zookeeper的灵魂的原因。当然ZK Server还有很多属于自己特性的东西:Session, Watcher,Version等等等等,需要我们花更多的时间去研究和学习。

3、ZAB协议

原文链接:https://baijiahao.baidu.com/s?id=1718646106068529193&wfr=spider&for=pc

ZAB协议的全称是Zookeeper Atomic Broadcast(Zookeeper原子广播)。

Zookeeper 是通过 Zab 协议来保证分布式事务的最终一致性

  1. Zab协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复原子广播协议,是Zookeeper保证数据一致性的核心算法。Zab借鉴了Paxos算法,但又不像Paxos那样,是一种通用的分布式一致性算法。它是特别为Zookeeper设计的支持崩溃恢复的原子广播协议

  2. 在Zookeeper中主要依赖Zab协议来实现数据一致性,基于该协议,zk实现了一种主备模型(即Leader和Follower模型)的系统架构来保证集群中各个副本之间数据的一致性。

  3. 这里的主备系统架构模型,就是指只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader客户端将数据同步到其他Follower节点。

Zookeeper 客户端会随机的链接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向 Leader 提交事务,Leader 接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。

Zab 协议的特性

1)Zab 协议需要确保那些已经在 Leader 服务器上提交(Commit)的事务最终被所有的服务器提交

2)Zab 协议需要确保丢弃那些只在 Leader 上被提出而没有被提交的事务

模型图

Zab 协议实现的作用

1)使用一个单一的主进程(Leader)来接收并处理客户端的事务请求(也就是写请求),并采用了Zab的原子广播协议,将服务器数据的状态变更以事务proposal(事务提议)的形式广播到所有的副本(Follower)进程上去。

2)保证一个全局的变更序列被顺序引用

Zookeeper是一个树形结构,很多操作都要先检查才能确定是否可以执行,比如P1的事务t1可能是创建节点"/a",t2可能是创建节点"/a/bb",只有先创建了父节点"/a",才能创建子节点"/a/b"。

为了保证这一点,Zab要保证同一个Leader发起的事务要按顺序被apply,同时还要保证只有先前Leader的事务被apply之后,新选举出来的Leader才能再次发起事务。

3)当主进程出现异常的时候,整个zk集群依旧能正常工作

Zab协议原理

Zab协议要求每个 Leader 都要经历三个阶段:发现,同步,广播

  1. 发现:要求zookeeper集群必须选举出一个 Leader 进程,同时 Leader 会维护一个 Follower 可用客户端列表。将来客户端可以和这些 Follower节点进行通信。

  2. 同步:Leader 要负责将本身的数据与 Follower 完成同步,做到多副本存储。这样也是体现了CAP中的高可用和分区容错。Follower将队列中未处理完的请求消费完成后,写入本地事务日志中。

  3. 广播:Leader 可以接受客户端新的事务Proposal请求,将新的Proposal请求广播给所有的 Follower。

Zab协议核心

Zab协议的核心:定义了事务请求的处理方式

1)所有的事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被叫做Leader服务器。其他剩余的服务器则是Follower服务器

2)Leader服务器 负责将一个客户端事务请求,转换成一个事务Proposal,并将该 Proposal 分发给集群中所有的 Follower 服务器,也就是向所有 Follower 节点发送数据广播请求(或数据复制)

3)分发之后Leader服务器需要等待所有Follower服务器的反馈(Ack请求),在Zab协议中,只要超过半数的Follower服务器进行了正确的反馈后(也就是收到半数以上的Follower的Ack请求),那么 Leader 就会再次向所有的 Follower服务器发送 Commit 消息,要求其将上一个 事务proposal 进行提交。

Zab协议内容

Zab 协议包括两种基本的模式:崩溃恢复消息广播

协议过程

当整个集群启动过程中,或者当 Leader 服务器出现网络中弄断、崩溃退出或重启等异常时,Zab协议就会进入崩溃恢复模式,选举产生新的Leader。

当选举产生了新的 Leader,同时集群中有过半的机器与该 Leader 服务器完成了状态同步(即数据同步)之后,Zab协议就会退出崩溃恢复模式,进入消息广播模式

这时,如果有一台遵守Zab协议的服务器加入集群,因为此时集群中已经存在一个Leader服务器在广播消息,那么该新加入的服务器自动进入恢复模式:找到Leader服务器,并且完成数据同步。同步完成后,作为新的Follower一起参与到消息广播流程中。

协议状态切换

当Leader出现崩溃退出或者机器重启,亦或是集群中不存在超过半数的服务器与Leader保存正常通信,Zab就会再一次进入崩溃恢复,发起新一轮Leader选举并实现数据同步。同步完成后又会进入消息广播模式,接收事务请求。

保证消息有序

在整个消息广播中,Leader会将每一个事务请求转换成对应的 proposal 来进行广播,并且在广播 事务Proposal 之前,Leader服务器会首先为这个事务Proposal分配一个全局单递增的唯一ID,称之为事务ID(即zxid),由于Zab协议需要保证每一个消息的严格的顺序关系,因此必须将每一个proposal按照其zxid的先后顺序进行排序和处理。

消息广播

1)在zookeeper集群中,数据副本的传递策略就是采用消息广播模式。zookeeper中数据副本的同步方式与二段提交相似,但是却又不同。二段提交要求协调者必须等到所有的参与者全部反馈ACK确认消息后,再发送commit消息。要求所有的参与者要么全部成功,要么全部失败。二段提交会产生严重的阻塞问题。

2)Zab协议中 Leader 等待 Follower 的ACK反馈消息是指“只要半数以上的Follower成功反馈即可,不需要收到全部Follower反馈”

消息广播具体步骤

1)客户端发起一个写操作请求。

2)Leader 服务器将客户端的请求转化为事务 Proposal 提案,同时为每个 Proposal 分配一个全局的ID,即zxid。

3)Leader 服务器为每个 Follower 服务器分配一个单独的队列,然后将需要广播的 Proposal 依次放到队列中取,并且根据 FIFO 策略进行消息发送。

4)Follower 接收到 Proposal 后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后向 Leader 反馈一个 Ack 响应消息。

5)Leader 接收到超过半数以上 Follower 的 Ack 响应消息后,即认为消息发送成功,可以发送 commit 消息。

6)Leader 向所有 Follower 广播 commit 消息,同时自身也会完成事务提交。Follower 接收到 commit 消息后,会将上一条事务提交。

zookeeper 采用 Zab 协议的核心,就是只要有一台服务器提交了 Proposal,就要确保所有的服务器最终都能正确提交 Proposal。这也是 CAP/BASE 实现最终一致性的一个体现。

Leader 服务器与每一个 Follower 服务器之间都维护了一个单独的 FIFO 消息队列进行收发消息,使用队列消息可以做到异步解耦。 Leader 和 Follower 之间只需要往队列中发消息即可。如果使用同步的方式会引起阻塞,性能要下降很多。

崩溃恢复

一旦 Leader 服务器出现崩溃或者由于网络原因导致 Leader 服务器失去了与过半 Follower 的联系,那么就会进入崩溃恢复模式。

在 Zab 协议中,为了保证程序的正确运行,整个恢复过程结束后需要选举出一个新的 Leader 服务器。因此 Zab 协议需要一个高效且可靠的 Leader 选举算法,从而确保能够快速选举出新的 Leader 。

Leader 选举算法不仅仅需要让 Leader 自己知道自己已经被选举为 Leader ,同时还需要让集群中的所有其他机器也能够快速感知到选举产生的新 Leader 服务器。

崩溃恢复主要包括两部分:Leader选举数据恢复

Zab 协议如何保证数据一致性

假设两种异常情况:

1、一个事务在 Leader 上提交了,并且过半的 Folower 都响应 Ack 了,但是 Leader 在 Commit 消息发出之前挂了。

2、假设一个事务在 Leader 提出之后,Leader 挂了。

要确保如果发生上述两种情况,数据还能保持一致性,那么 Zab 协议选举算法必须满足以下要求:

Zab 协议崩溃恢复要求满足以下两个要求

1)确保已经被 Leader 提交的 Proposal 必须最终被所有的 Follower 服务器提交

2)确保丢弃已经被 Leader 提出的但是没有被提交的 Proposal

根据上述要求

Zab协议需要保证选举出来的Leader需要满足以下条件:

1)新选举出来的 Leader 不能包含未提交的 Proposal

即新选举的 Leader 必须都是已经提交了 Proposal 的 Follower 服务器节点。

2)新选举的 Leader 节点中含有最大的 zxid

这样做的好处是可以避免 Leader 服务器检查 Proposal 的提交和丢弃工作。

Zab 如何数据同步

1)完成 Leader 选举后(新的 Leader 具有最高的zxid),在正式开始工作之前(接收事务请求,然后提出新的 Proposal),Leader 服务器会首先确认事务日志中的所有的 Proposal 是否已经被集群中过半的服务器 Commit。

2)Leader 服务器需要确保所有的 Follower 服务器能够接收到每一条事务的 Proposal ,并且能将所有已经提交的事务 Proposal 应用到内存数据中。等到 Follower 将所有尚未同步的事务 Proposal 都从 Leader 服务器上同步过啦并且应用到内存数据中以后,Leader 才会把该 Follower 加入到真正可用的 Follower 列表中。

        Zab 数据同步过程中,如何处理需要丢弃的 Proposal

在 Zab 的事务编号 zxid 设计中,zxid是一个64位的数字。

其中低32位可以看成一个简单的单增计数器,针对客户端每一个事务请求,Leader 在产生新的 Proposal 事务时,都会对该计数器加1。而高32位则代表了 Leader 周期的 epoch 编号。

epoch 编号可以理解为当前集群所处的年代,或者周期。每次Leader变更之后都会在 epoch 的基础上加1,这样旧的 Leader 崩溃恢复之后,其他Follower 也不会听它的了,因为 Follower 只服从epoch最高的 Leader 命令。

        每当选举产生一个新的 Leader ,就会从这个 Leader 服务器上取出本地事务日志充最大编号 Proposal 的 zxid,并从 zxid 中解析得到对应的 epoch 编号,然后再对其加1,之后该编号就作为新的 epoch 值,并将低32位数字归零,由0开始重新生成zxid。

Zab 协议通过 epoch 编号来区分 Leader 变化周期,能够有效避免不同的 Leader 错误的使用了相同的 zxid 编号提出了不一样的 Proposal 的异常情况。

基于以上策略

当一个包含了上一个 Leader 周期中尚未提交过的事务 Proposal 的服务器启动时,当这台机器加入集群中,以 Follower 角色连上 Leader 服务器后,Leader 服务器会根据自己服务器上最后提交的 Proposal 来和 Follower 服务器的 Proposal 进行比对,比对的结果肯定是 Leader 要求 Follower 进行一个回退操作,回退到一个确实已经被集群中过半机器 Commit 的最新 Proposal。

实现原理

Zab 节点有三种状态

  1. Following:当前节点是跟随者,服从 Leader 节点的命令。

  2. Leading:当前节点是 Leader,负责协调事务。

  3. Election/Looking:节点处于选举状态,正在寻找 Leader。

代码实现中,多了一种状态:Observing 状态

这是 Zookeeper 引入 Observer 之后加入的,Observer 不参与选举,是只读节点,跟 Zab 协议没有关系。

节点的持久状态

  1. history:当前节点接收到事务 Proposal 的Log

  2. acceptedEpoch:Follower 已经接受的 Leader 更改 epoch 的 newEpoch 提议。

  3. currentEpoch:当前所处的 Leader 年代

  4. lastZxid:history 中最近接收到的Proposal 的 zxid(最大zxid)

Zab 的四个阶段

1、选举阶段(Leader Election)

节点在一开始都处于选举节点,只要有一个节点得到超过半数节点的票数,它就可以当选准 Leader,只有到达第三个阶段(也就是同步阶段),这个准 Leader 才会成为真正的 Leader。

Zookeeper 规定所有有效的投票都必须在同一个 轮次 中,每个服务器在开始新一轮投票时,都会对自己维护的 logicalClock 进行自增操作

每个服务器在广播自己的选票前,会将自己的投票箱(recvset)清空。该投票箱记录了所受到的选票。

例如:Server_2 投票给 Server_3,Server_3 投票给 Server_1,则Server_1的投票箱为(2,3)、(3,1)、(1,1)。(每个服务器都会默认给自己投票)

前一个数字表示投票者,后一个数字表示被选举者。票箱中只会记录每一个投票者的最后一次投票记录,如果投票者更新自己的选票,则其他服务器收到该新选票后会在自己的票箱中更新该服务器的选票。

这一阶段的目的就是为了选出一个准 Leader ,然后进入下一个阶段。

协议并没有规定详细的选举算法,后面会提到实现中使用的 Fast Leader Election。

2、发现阶段(Descovery

在这个阶段,Followers 和上一轮选举出的准 Leader 进行通信,同步 Followers 最近接收的事务 Proposal 。

一个 Follower 只会连接一个 Leader,如果一个 Follower 节点认为另一个 Follower 节点,则会在尝试连接时被拒绝。被拒绝之后,该节点就会进入 Leader Election阶段。

这个阶段的主要目的是发现当前大多数节点接收的最新 Proposal,并且准 Leader 生成新的 epoch ,让 Followers 接收,更新它们的 acceptedEpoch

3、同步阶段(Synchronization)

同步阶段主要是利用 Leader 前一阶段获得的最新 Proposal 历史,同步集群中所有的副本

只有当 quorum(超过半数的节点) 都同步完成,准 Leader 才会成为真正的 Leader。Follower 只会接收 zxid 比自己 lastZxid 大的 Proposal。

4、广播阶段(Broadcast)

到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 Leader 可以进行消息广播。同时,如果有新的节点加入,还需要对新节点进行同步。

需要注意的是,Zab 提交事务并不像 2PC 一样需要全部 Follower 都 Ack,只需要得到 quorum(超过半数的节点)的Ack 就可以。

协议实现

协议的 Java 版本实现跟上面的定义略有不同,选举阶段使用的是 Fast Leader Election(FLE),它包含了步骤1的发现指责。因为FLE会选举拥有最新提议的历史节点作为 Leader,这样就省去了发现最新提议的步骤。

实际的实现将发现和同步阶段合并为 Recovery Phase(恢复阶段),所以,Zab 的实现实际上有三个阶段。

Zab协议三个阶段:

1)选举(Fast Leader Election)

2)恢复(Recovery Phase)

3)广播(Broadcast Phase)

Fast Leader Election(快速选举)

前面提到的 FLE 会选举拥有最新Proposal history (lastZxid最大)的节点作为 Leader,这样就省去了发现最新提议的步骤。这是基于拥有最新提议的节点也拥有最新的提交记录

  1. 成为 Leader 的条件:

  2. 1)选 epoch 最大的

  3. 2)若 epoch 相等,选 zxid 最大的

  4. 3)若 epoch 和 zxid 相等,选择 server_id 最大的(zoo.cfg中的myid)

节点在选举开始时,都默认投票给自己,当接收其他节点的选票时,会根据上面的Leader条件判断并且更改自己的选票,然后重新发送选票给其他节点。当有一个节点的得票超过半数,该节点会设置自己的状态为 Leading ,其他节点会设置自己的状态为 Following

Recovery Phase(恢复阶段)

这一阶段 Follower 发送他们的 lastZxid 给 Leader,Leader 根据 lastZxid 决定如何同步数据。这里的实现跟前面的 Phase 2 有所不同:Follower 收到 TRUNC 指令会终止 L.lastCommitedZxid 之后的 Proposal ,收到 DIFF 指令会接收新的 Proposal。

history.lastCommitedZxid:最近被提交的 Proposal zxid

history.oldThreshold:被认为已经太旧的已经提交的 Proposal zxid

干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!

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

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

相关文章

Trace32使用Data.Test和Data.TestList命令测试内存类型以及完整性

我们在debug的时候,可以使用Trace32自带的一些命令快速地检测目标系统的内存的类型和完整性(是否可读或可写),以便快速排除内存缺陷带来的干扰。 目录 Data.Test: 内存完整性测试 Memory integrity test Data.TestL…

Android进阶 View事件体系(二):从源码解析View的事件分发

Android进阶 View事件体系(二):从源码解析View的事件分发 内容概要 本篇文章为总结View事件体系的第二篇文章,前一篇文章的在这里:Android进阶 View事件体系(一):概要介绍和实现Vie…

chatgpt赋能python:Python动态增加成员变量简介

Python动态增加成员变量简介 Python是著名的解释型编程语言,在众多开源项目中得到了广泛的应用。它以简洁明了的语法和高效的运行速度而闻名,成为了许多开发者的首选。 Python提供了极大的灵活性,使得我们可以随意添加、修改和删除对象的属…

chatgpt赋能python:Python切割技巧:如何用Python切割字符串和列表

Python切割技巧:如何用Python切割字符串和列表 Python是一种高级编程语言,被广泛用于数据分析、机器学习、Web应用程序等领域。在Python编程中,切割技巧是一项必备技能。 什么是切割技巧? 切割技巧是指用一种编程语言&#xff…

chatgpt赋能python:Python列表倒序-从入门到实践

Python列表倒序 - 从入门到实践 Python是一种高级编程语言,被广泛运用于web开发、科学计算、数据分析等领域,也是初学者学习的首选语言之一。Python的列表(List)是其中一个常用的数据类型。在本文中,我们将深入探讨Python列表倒序的方法&…

chatgpt赋能python:Python列表反向:如何用简单的代码将列表元素反转

Python列表反向:如何用简单的代码将列表元素反转 在很多编程语言中,将列表元素反转是一项常见的任务。Python也不例外。Python内置函数提供了一种非常直接的方式来将列表元素反转,而不需要费力地创建一个新列表。 什么是列表反向&#xff1…

chatgpt赋能python:Python动态代码的SEO优化技巧

Python 动态代码的SEO优化技巧 Python是一种常用的编程语言,它以简化开发流程和易于阅读的代码著称。Python动态代码能够让开发者更快捷方便地进行编码,并且能够改善SEO表现。在本文中,我们将着重介绍Python动态代码与SEO优化涉及的技巧。 …

chatgpt赋能python:Python分组匹配:了解正则表达式中的分组匹配技巧

Python 分组匹配: 了解正则表达式中的分组匹配技巧 在 Python 中,正则表达式是一种重要的文本处理工具,它可以帮助我们在字符串中匹配、查找和替换特定的文本模式。其中,分组匹配是正则表达式的重要特性之一,它可以将匹配的结果按…

快速理解会话跟踪技术Cookie和Session

文章目录 会话跟踪技术客户端会话跟踪技术Cookie服务端会话跟踪技术Session 会话跟踪技术 会话:客服端和服务端的多次请求与响应称为会话。 会话跟踪:服务器需要识别多次请求是否来自同一浏览器,在同一次会话多次请求中共享数据。 HTTP协议是…

chatgpt赋能python:Python加解密算法简介

Python加解密算法简介 在当今数字化的时代,数据的安全性变得至关重要。而加密算法就成为了保障数据安全的重要手段之一。Python作为一门高级编程语言,提供了许多加密算法库,使得开发人员可以轻松地实现加密功能。本文将着重介绍Python中一些…

机器学习模型——回归模型

文章目录 监督学习——回归模型线性回归模型最小二乘法求解线性回归代码实现引入依赖:导入数据:定义损失函数:定义核心算法拟合函数:测试:画出拟合曲线: 多元线性回归梯度下降求线性回归梯度下降和最小二乘…

chatgpt赋能python:Python中%取模操作的介绍

Python中%取模操作的介绍 在Python中,取模操作使用符号“%”表示,它的作用是取两个数相除的余数。例如,10 % 3等于1,因为10除以3的余数为1。这个操作可以用在很多场合,比如判断一个数是奇数还是偶数,或者判…

带你开发一个远程控制项目---->STM32+标准库+阿里云平台+传感器模块+远程显示。

目录 本次实验项目: 下次实验项目: 本次项目视频结果/APP/实物展示 实物展示 APP展示 视频展示 模块选择说明; 温湿度传感器模块介绍 光照传感器介绍 ESP8266-01S模块介绍 本次实验项目: 项目清单平台单片机语言实现温湿度传感器模…

Reinforcement Learning | 强化学习十种应用场景及新手学习入门教程

文章目录 1.在自动驾驶汽车中的应用2.强化学习的行业自动化3.强化学习在贸易和金融中的应用4.NLP(自然语言处理)中的强化学习5.强化学习在医疗保健中的应用6.强化学习在工程中的应用7.新闻推荐中的强化学习8.游戏中的强化学习9.实时出价——强化学习在营…

Redis中的Reactor模型源码探索

文章目录 摘要了解Linux的epoll了解Reactor模型 源码initServerinitListenersaeMain 事件管理器aeProcessEvents读事件 摘要 有时候在面试的时候会被问到Redis为什么那么快?有一点就是客户端请求和应答是基于I/O多路复用(比如linux的epoll)的…

【高级语言程序设计(一)】第 9 章:编译预处理命令

目录 前言 一、宏定义命令 (1)无参宏定义 (2)有参宏定义 ① 带参数的宏定义 ② 带参宏定义与函数的区别 二、文件包含命 (1)文件包含命令的定义 (2)文件包含命令的格式 &…

【Leetcode60天带刷】day02—— 977.有序数组的平方、209.长度最小的子数组、 59.螺旋矩阵II

题目:997.有序数组的平方 Leetcode原题链接:997.有序数组的平方——力扣 思考历程与知识点: 题目的意思很简单,就是把每个数的平方,按从小到大的顺序排个序,再输出出来。 第一想法是先每个数平方一遍&a…

Stream API的使用

使用Stream API对集合中的数据进行操作,就类似使用SQL语句对数据库执行查询 Stream不会存储数据Stream不会改变源对象,而是返回一个持有结果的新StreamStream是延迟执行的,只有在需要结果的时候才执行,即只有执行终止操作&#xf…

离散数学_十章-图 ( 2 ):图的术语和几种特殊的图

📷10.2 图的术语和几种特殊的图 1. 基本术语1.1 邻接(相邻)1.2 邻居1.3 顶点的度1.4 孤立点1.5 悬挂点例题 2. 握手定理3. 握手定理的推论4. 带有有向边的图的术语4.1 邻接4.2 度——出度 和 入度4.3 例题: 5. 定理:入…

PHP 反序列化漏洞

PHP反序列化漏洞在实际测试中出现的频率并不高,主要常出现在CTF中。 PHP序列化概述 PHP序列化函数: serialize:将PHP的数据,数组,对象等序列化为字符串unserialize:将序列化后的字符串反序列化为数据&…