如何确认一台基于Linux的DHCP服务器已经成功分发IP地址租约到客户端?

如何确认一台基于Linux的DHCP服务器已经成功分发IP地址租约到客户端?,第1张

linux的dhcp服务器好像不带这个功能,一般通过日志查询,正因为官方不带,所有很多类似软件,我随便列举几个:
php DHCP hosts list : 一个 php 脚本,用于列出一个 DHCP 服务器上的 host 信息
rogueDetect :发送一个“诱骗”作用的 DHCP DISCOVER ,并等待非权威的 DHCP 服务器消息,以找出未授权的 DHCP 服务器
phpDHCPAdmin :一个基于 web 界面的管理 DHCP 工具。有认证、错误检查、数据库驱动,简单易用
Analyzes of behavior of protocol DHCP :dhcpmap 能够“注入”和捕捉 DHCP 流量
dhcpphp :一个 PHP 脚本,用于显示一个 DHCP 服务器的 leases 记录
webDHCP :类似 phpDHCPAdmin 的工具
DHCP lease parser :是一个简单的守护进程,它把 DHCP 服务器的 leases 状态的变化记录到一个数据库,以便历史查询。

最近在学习ZooKeeper,一直想写篇相关博文记录下学习内容,碍于自己是个拖延症重度患者总是停留在准备阶段,直到今天心血来潮突然想干点什么,于是便一不做二不休,通过对《从Paxos到Zookeeper 分布式一致性原理与实践》一书中ZAB相关内容的总结,以及对一些优秀博文的整理码出来这篇简文。本文首先对ZooKeeper进行一个简单的介绍,然后重点介绍ZooKeeper采用的ZAB(ZooKeeper Atomic Broadcast)一致性协议算法,加深自己对ZAB协议的理解的同时也希望与简友们一起分享讨论。

ZooKeeper是一个具有高效且可靠的分布式协调服务, 由Yahoo创建的基于Google的Chubby开源实现,并于2010年11月正式成为Apache软件基金会的顶级项目。

ZooKeeper是一个典型的分布式数据一致性解决方案,分布式应用程序可基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。

保证如下分布式一致性特性

顺序一致性

从同一个客户端发起的事务请求,最终将会严格地按照其发生顺序被应用到ZooKeeper中。

原子一致性

所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,即要么整个集群所有机器都成功应用了某一个事务,要么都没有应用,一定不会出现集群中部分机器应用了该事务,而另外一部分没有应用的情况。

单一视图

无论客户端连接的是哪个ZK服务器,其看到的服务端数据模型都是一致的。

可靠性

一旦服务端成功地应用了一个事务并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非另外一个事务又对其进行了变更。

实时性

通常人们看到实时性的第一反应是,一旦一个事务被成功应用,那么客户端能够立即从服务端上读取到这个事务变更后的最新数据状态。但这个需要注意的是, ZooKeeper仅仅保证在一定时间段内 , 客户端最终一定能够从服务端上读取到最新的数据状态 。

Leader 一个ZooKeeper集群同一时间只会有一个实际工作的Leader,它会发起并维护与各Follwer及Observer间的心跳。所有的写 *** 作必须要通过Leader完成再由Leader将写 *** 作广播给其它服务器。

Follower 一个ZooKeeper集群可能同时存在多个Follower,它会响应Leader的心跳。Follower可直接处理并返回客户端的读请求,同时会将写请求转发给Leader处理,并且负责在Leader处理写请求时对请求进行投票。

Observer 角色与Follower类似,但是无投票权。

ZooKeeper Atomic Broadcast (ZAB, ZooKeeper原子消息广播协议)是ZooKeeper实现分布式数据一致性的核心算法,ZAB借鉴Paxos算法,但又不像Paxos算法那样,是一种通用的分布式一致性算法, 它是一种特别为ZooKeeper专门设计的支持崩溃恢复的原子广播协议 。

ZAB协议的核心是定义了对于那些会改变ZooKeeper服务器数据状态的事务请求处理方式,即:

所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,而余下的其他服务器称为Follower服务器。Leader服务器负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有的Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进提交。

ZAB协议整体可划分为两个基本的模式: 消息广播和崩溃恢复

按协议原理可细分为四个阶段: 选举(Leader Election)、发现(Discovery)、同步(Synchronization)和广播(Broadcast)

按协议实现分为三个时期: 选举(Fast Leader Election)、恢复(Recovery Phase)和广播(Broadcast Phase)

ZAB协议的消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程。针对客户端的事务请求,Leader服务器会为其生成对应的事务Proposal,并将其发送给集群中其余所有的机器,然后在分别收集各自的选票,最后进行事务提交,此处与二阶段提交过程略有不同,ZAB协议的二阶段提交过程中, 移除了中断逻辑 ,所有的Follower服务器要么正常反馈Leader提出的事务Proposal,要么就抛弃Leader服务器。同时,ZAB协议将二阶段提交中的中断逻辑移除意味着 我们可以在过半的Follower服务器已经反馈Ack之后就开始提交事务Proposal了,而不需求等待集群中所有的Follower服务器都反馈响应 。

然而,在这种简化的二阶段提交模型下,无法处理Leader服务器崩溃退出而带来的数据不一致问题,因此ZAB协议添加了 崩溃恢复 模式来解决这个问题,另外,整个消息广播协议是基于有FIFO特性的TCP协议来进行网络通信的,因此很容易地保证消息广播过程中消息接收和发送的顺序性。

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

具体的,在消息广播过程中,Leader服务器会为每个Follower服务器都各自分配一个单独的队列,然后将需要广播的事务Proposal依次放入这些队列中取,并且根据FIFO策略进行消息发送。每一个Follower服务器在接收到这个事务Proposal之后,都会首先将其以事务日志的形式写入本地磁盘中,并且成功写入后反馈给Leader服务器一个Ack相应。当Leader服务器接收到过半数Follower的Ack响应后,就会广播一个Commit消息给所有的Follower服务器以通知其进行事务提交,同时Leader自身也会完成对事务的提交,而每个Follower服务器在接收到Commit消息后,也会完成对事务的提交。

上面讲解的ZAB协议的这个基于原子广播协议的消息广播过程,在正常运行情况下运行非常良好,但是一旦Leader服务器出现崩溃或者由于网络原因导致Leader服务器失去了与过半Follower的联系,那么就会进入崩溃恢复模式。在ZAB协议中,为了保证程序的正确运行,整个恢复过程结束后需要选举出一个新的Leader服务器。因此,ZAB协议需要一个高效且可靠的Leader选举算法,从而确保能够快速选举出新的Leader。同时,Leader选举算法不仅仅需要让Leader自己知道其自身已经被选举为Leader,同时还需要让集群中的所有其他服务器也快速地感知到选举产生的新的Leader服务器。崩溃恢复主要包括Leader选举和数据恢复两部分,下面将详细讲解 Leader选举和数据恢复流程 。

现有的选举算法有一下四种: 基于UDP的LeaderElection 、 基于UDP的FastLeaderElection 、 基于UDP和认证的FastLeaderElection 和 基于TCP的FastLeaderElection ,在3410版本中弃用其他三种算法

myid —— zk服务器唯一ID

zxid ——  最新事务ID

高32位 是Leader的 epoch ,从1开始,每次选出新的Leader,epoch加一;

低32位 为该epoch 内的序号 ,每次epoch变化,都将低32位的序号重置;

保证了zkid的 全局递增性 。

logicClock 表示这是该服务器发起的第多少轮投票,从1开始计数

state 当前服务器的状态

self_id 当前服务器的 唯一ID

self_zxid 当前服务器上所保存的数据的 最大事务ID ,从0开始计数

vote_id 被推举的服务器的 唯一ID

vote_zxid 被推举的服务器上所保存的数据的 最大事务ID ,从0开始计数

LOOKING  不确定Leader状态。该状态下的服务器认为当前集群中没有Leader,会发起Leader选举。

FOLLOWING  跟随者状态。表明当前服务器角色是Follower,并且它知道Leader是谁。

LEADING  领导者状态。表明当前服务器角色是Leader。

OBSERVING  观察者状态, 不参与选举 ,也不参与集群写 *** 作时的投票。

能够确保提交已经被Leader提交的事务Proposal,同时丢弃已经被跳过的事务Proposal。针对这个要求,如果让Leader选举算法能够保证新选举出来的Leader服务器拥有集群中所有机器最高编号(即ZXID最大)的事务Proposal,那么就可以保证这个新选举出来的Leader一定具有所有已经提交的提案。更为重要的是,如果让具有最高编号事务Proposal的机器成为Leader,就可以省去Leader服务器检查Proposal的提交和丢弃工作的这一步 *** 作了。

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

每个服务器在广播自己的选票前,会将自己的投票箱清空。该投票箱记录了所收到的选票。例:服务器2投票给服务器3,服务器3投票给服务器1,则服务器1的投票箱为(2, 3), (3, 1), (1, 1)。 票箱中只会记录每一投票者的最后一票 ,如投票者更新自己的选票,则其它服务器收到该新选票后会在自己票箱中更新该服务器的选票。

每个服务器最开始都是通过广播把票投给自己。

服务器会尝试从其它服务器获取投票,并记入自己的投票箱内。如果无法获取任何外部投票,则会确认自己是否与集群中其它服务器保持着有效连接。如果是,则再次发送自己的投票;如果否,则马上与之建立连接。

根据选票logicClock -> vote_zxid -> vote_id依次判断

1 判断选举轮次

收到外部投票后,首先会根据投票信息中所包含的logicClock来进行不同处理:

外部投票的logicClock > 自己的logicClock:   说明该服务器的选举轮次落后于其它服务器的选举轮次,立即清空自己的投票箱并将自己的logicClock更新为收到的logicClock,然后再对比自己之前的投票与收到的投票以确定是否需要变更自己的投票,最终再次将自己的投票广播出去;

外部投票的logicClock < 自己的logicClock: 当前服务器直接忽略该投票,继续处理下一个投票;

外部投票的logickClock = 自己的: 当时进行选票PK。

2 选票PK

选票PK是基于(self_id, self_zxid)与(vote_id, vote_zxid)的对比:

若logicClock一致,则对比二者的vote_zxid,若外部投票的vote_zxid比较大,则将自己的票中的vote_zxid与vote_myid更新为收到的票中的vote_zxid与vote_myid并广播出去,另外将收到的票及自己更新后的票放入自己的票箱。如果票箱内已存在(self_myid, self_zxid)相同的选票,则直接覆盖

若二者vote_zxid一致,则比较二者的vote_myid,若外部投票的vote_myid比较大,则将自己的票中的vote_myid更新为收到的票中的vote_myid并广播出去,另外将收到的票及自己更新后的票放入自己的票箱

如果已经确定有过半服务器认可了自己的投票(可能是更新后的投票),则终止投票。否则继续接收其它服务器的投票。

投票终止后,服务器开始更新自身状态。若过半的票投给了自己,则将自己的服务器状态更新为LEADING,否则将自己的状态更新为FOLLOWING。
注: 图中箭头上的(1,1,0) 三个数一次代表该选票的服务器的 LogicClock 、被推荐的服务器的myid (即 vote_myid ) 以及被推荐的服务器的最大事务ID(即 vote_zxid );

(1, 1) 2个数分别代表投票服务器myid(即 self_myid )和被推荐的服务器的myid (即 vote_myid )

选举流程如下:

自增选票轮次&初始化选票&发送初始化选票

首先,三台服务器自增选举轮次将LogicClock=1;然后初始化选票,清空票箱;最后发起初始化投票给自己将各自的票通过广播的形式投个自己并保存在自己的票箱里。

接受外部投票&更新选票

以Server 1 为例,分别经历 Server 1 PK Server 2 和 Server 1 PK Server 3 过程

Server 1 PK Server 2

Server 1 接收到Server 2的选票(1,2,0) 表示,投票轮次LogicClock为1,投给Server 2,并且Server 2的最大事务ID,ZXID 为0;

这时Server 1将自身的选票轮次和Server 2 的选票轮次比较,发现 LogicClock=1相等 ,接着Server 2比较比较最大事务ID,发现也 zxid=0也相等 ,最后比较各自的myid,发现Server 2的 myid=2 大于自己的myid=1 ;

根据选票PK规则,Server 1将自己的选票由 (1, 1) 更正为 (1, 2),表示选举Server 2为Leader,然后将自己的新选票 (1, 2)广播给 Server 2 和 Server 3,同时更新票箱子中自己的选票并保存Server 2的选票,至此Server 1票箱中的选票为(1, 2) 和 (2, 2);

Server 2收到Server 1的选票同样经过轮次比较和选票PK后确认自己的选票保持不变,并更新票箱中Server 1的选票由(1, 1)更新为(1, 2),注意此次Server 2自己的选票并没有改变所有不用对外广播自己的选票。

Server 1 PK Server 3

更加Server 1 PK Server 2的流程类推,Server 1自己的选票由(1, 2)更新为(1, 3), 同样更新自己的票箱并广播给Server 2 和 Server 3;

Server 2再次接收到Server 1的选票(1, 3)时经过比较后根据规则也要将自己的选票从(1, 2)更新为(1, 3), 并更新票箱里自己的选票和Server 1的选票,同时向Server 1和 Server 3广播;

同理 Server 2 和 Server 3也会经历上述投票过程,依次类推,Server 1 、Server 2 和Server 3 在俩俩之间在经历多次 选举轮次比较 和 选票PK 后最终确定各自的选票。

选票确定后服务器根据自己票箱中的选票确定各自的角色和状态,票箱中超过半数的选票投给自己的则为Leader,更新自己的状态为LEADING,否则为Follower角色,状态为FOLLOWING,

成为Leader的服务器要主动向Follower发送心跳包,Follower做出ACK回应,以维持他们之间的长连接。
1《从Paxos到Zookeeper 分布式一致性原理与实践》 [倪超著]

2 《实例详解ZooKeeper ZAB协议、分布式锁与领导选举》

3《ZooKeeper’s atomic broadcast protocol:Theory and practice》[Andr ́e Medeiros]

几十万人真心不少了。。。
首先考虑客户端的连接层, 考虑到一个服务器的吞吐量和socket限制,建议用负载均衡将不同的频道的客户分散到不同的前端连接器上,连接器的socket可以考虑libevent + 线程池这种架构, 消息用protobuf序列化
后台可以考虑用redis加kafka来完成session管理和消息分发, 由于消息太多了可能会影响kafka的性能, 建议给消息一个优先级。 给优先级低的消息一个消息池。另外由于消息会大量产生和释放, 用普通的内存管理开销太大, 碎片也会很严重。 建议使用TCMalloc做内存分配器或者自己写一个slab, redis尽量做一个MS,用户会话session可以集中管理

1如今的手游世界,如果没搞个跨服赛事,都不好意思说它是一个手游了。

说到跨服,就不得不说下匹配服了。比如一个跨服天梯赛事,需要满足不同服的玩家能够同屏PK。为了能够把实力接近的玩家作为对手,我们需要一个独立的匹配服来收集数据,然后进行房间分配。匹配服,也是跨服赛设计的基础。

典型的匹配服通信层我们可以采用p>

为了能区别游戏服和匹配服的消息类型,我们匹配服的消息,都加一个M(Match)前

4业务处理器

我们依然使用@Controller注解来标识一个模块处理器,使用@RequestMapper注解来标记业务处理方法。不同的是,在游戏服我们每个消息的元信息都带有一个模块号和子类型号。在匹配服,我们就不这里处理了。因为匹配服的业务比较少。我们直接用消息类的名称作为业务签名即可。

在业务分发器,我们保存每一个方法签名,与对应的方法处理器。

5匹配服在收到一个>

启动匹配服服务器(MatchStartupjava)

再执行游戏服的单元测试

如果你是看CDN的东西看到的这句话,那么我可以来解释一下流程。“全局负载均衡技术将用户的访问指向离用户最近的工作正常的流媒体服务器上”。首先我们要明确几件事:
1、在CDN的案例图中,其实B和C不会在不同的城域。如果在不同的城市,一般会在那个地域也放置一个反向代理服务器或反向代理节点。B和C为同一地域,A为B、C的负载均稀器或调度器;
2、CDN的部署里,为避免单点故障或应对业务峰值,A并不是单台服务器,一般由多台服务器进行调度,一般采用LVS进行七层的负载和转发。通过LVS的负载均衡策略将业务转发至B和C,负载均衡策略可以进行设置,如轮询,权重轮询、随机等等;
3、CDN一般由DNS来做为用户流量调度,也是CDN的核心,即将用户的请求调度至距用户最近的节点,例如节点D,节点D通过负载均衡策略将请求分发至节点D后端的业务服务器E和F。
4、你看到的这句话,是指DNS层面的调度。
流媒体业务使用CDN的发布业务的前提和流程如下:
1、在流媒体业务服务器域名注册商修改域名的CNAME记录为CDN服务厂商的域名;(这一步是使用CDN的首要条件)
2、CDN服务厂商为业务设置不同地域的缓存节点,如北京、上海、美国等
3、不同地域设置的缓存节点具有不同的IP地址地址池,并且该节点内拥有业务调度器(LVS的DR)及真正的业务缓存服务器,缓存服务器通过类似Squid等程序定期缓存流媒体业务服务器的视频信息及网页信息,每隔一段时间进行更新请求;
4、用户通过DNS调度请求到某一节点时,该节点通过LVS技术将用户的请求调度至节点内某一以缓存节点进行处理,并返回结果给用户;(可参照LVS的工作模式)
5、当缓存节点有用户请求的内容时,将直接返回内容给用户,当缓存节点发现请求的内容不存在时,会主动返回流媒体业务的源服务器进行内容请求,并将结果缓存至缓存节点。
6、
用户最终拿到缓存节点上的视频内容及信息,由于通过DNS调度至用户最近的节点,通过LVS调度至最快最优的服务器进行处理,故加快了用户访问网站及视频
的速度。(视频的加速其实还有一种技术叫cache技术,即将视频提前下载到距用户最近的节点,用户看起来等于在局域网中查看)
DNS和CDN调度的流程如下:
1、用户访问流媒体业务的域名如“>

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13496879.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-08-19
下一篇 2023-08-19

发表评论

登录后才能评论

评论列表(0条)

保存