二级数据模型设计考虑我们在面临的需求中提到,命令需要在大型服务器上执行,并且可以灵活控制。为了满足这样的需求,在构建数据模型时,仅仅有执行信息是不够的,还要有控制信息,比如路由、并发、暂停点等。两者结合构成了CCS系统中的数据模型。控制信息控制信息包括命令传输所需要的“路由”信息和调度过程的控制信息,具体如下:Targetmachine:命令执行的目标服务器列表,可以是IP或Hostname。并发级别:并发执行组时每个组的服务器数量,用于控制组执行,避免系统升级时所有服务器同时升级造成业务中断。暂停节点:指定第一个服务器执行时暂停执行,方便先操作几台服务器确认没有问题再继续执行。如果出现问题,也可以将问题控制在小范围内。执行信息执行信息是指命令到达目标机后执行所必需的信息,具体如下:认证信息:表明执行者是谁的信息,用于确认执行者的合法性,如果是则拒绝执行不合法。认证信息:表示执行者持有的权限。如果权限不够,应该拒绝执行。命令信息:在目标机器上要执行的命令,也是数据模型盒子里最有价值的信息。除了控制信息和执行信息这两个关键信息外,还有一些辅助信息,如任务类型、任务创建/结束时间、任务超时时间等,这些也是数据模型在实际应用中必不可少的信息,但它们并不重要,因此不会详细描述。四级调度模型设计考虑在调度模型的设计中,考虑了百度云服务器的地域分布特点、任务调度与业务的强关联性、单机环境的复杂性、传输的稳定性要求过程中,我们将传输模型分为两类:四层,从上到下分别是统一接入层、分层调度层、机房汇聚层、代理执行层,分别负责全局服务接入、分层按业务层级调度、机房服务器任务管理、单机层。任务执行。同时,为了保证可用性,每一层都要保证足够的冗余(通过无状态集群/多机热备实现)和数据容灾(通过在每一层设置缓存和持久层实现)。各层介绍统一接入层:统一接入层的目的之一就是为用户提供一致的接入体验。有很多解决方案可以实现这个目标。目前在CCS系统中,是通过VIP实现的。统一接入层的第二个目的是通过Quota和Block来控制用户流量,同时实现用户账号共享,避免突如其来的流量压垮CCS系统后端。层次调度层:层次调度层是任务调度的核心层,承上启下。在通信方面,每个节点与机房执行层建立逻辑上的Full-Mesh连接,如图1所示,这样每个节点都有能力向百度内部的每台服务器发送命令。这里还要注意分层调度层中的分类概念。通过区分不同业务的重要性,分类可以独占或混合本层某个调度节点,通过各个节点之间相互隔离,实现重要业务互不干扰。.通过设置分级调度层,在保证全网调度能力的同时,可以有效区分不同层次的业务,使业务相互隔离,互不干扰。图1机房分级调度层与汇聚层Full-Mesh连接。机房汇聚层:在网络基础设施中,有网络汇聚层的概念,起到本地流量汇聚的作用。机房汇聚层与之类似,负责机房所有服务器的状态监控、命令下发、结果收集。机房汇聚层通过心跳消息(由各服务器上的执行代理定期上报)与下层通信。心跳消息有两个作用。心跳消息由汽车传递,既减少了消息量,又避免了复杂的实现逻辑。通过建立机房汇聚层,统一管理一个机房内的服务器,避免了向其他机房传输大量内部心跳报文,减少了公网带宽占用的同时保证通信的可靠性。图2机房汇聚层通过心跳与执行代理层通信,执行代理层:这里是命令传输的终点,也是命令执行的起点。命令信息通过部署在服务器上的执行客户端(以下简称CCS-Agent)与机房聚合之间的心跳拉取到目标服务器。在通信层面,命令信息到此为止,但执行代理的功能不止于此,相关内容将在下一节详细介绍。三级代理执行设计考虑在单机执行方案的设计中,最重要的问题是执行端的稳定性。万分之一的问题在部署到几十万台服务器上后会严重影响业务。为了实现这样的超稳定状态,我们设计了如图3所示的单机执行架构,将最重要的命令执行逻辑从CCS-Agent中分离出来,形成一个独立的通用执行层。在CCS-Agent中,只有Authentication、Authorization、Backup、CommandAssembly是不可执行的逻辑。同时为了保证通用执行层用户进程之间的异常隔离,我们将执行层分为三部分:执行代理进程、执行端进程、用户进程。每个执行端进程对应一个用户进程,负责用户进程的启动。停止控制和结果收集。图3ExecutionAgent层详细介绍CCS-Agent:在执行层,如前所述,主要负责用户认证、用户认证、数据备份、命令组装等命令执行前的准备工作。关于认证的问题,这两个功能也是CCS-Agent最重要的功能,这里重点说说。CCS系统具有严格的鉴权认证机制。毕竟,在在线服务器上执行命令是一个高风险的操作。在CCS系统中,用户权限控制不是基于Linux系统的账户体系,而是基于身份和角色。例如,张三要在服务器A上执行命令,当命令发送到目标服务器后,CCS-Agent会首先对用户张三进行身份验证,确认身份的合法性。如果身份合法,这个身份所属的角色(如RD、QA、OP等,RD和QA有在线系统查看权限,OP有更改权限)验证相应的命令只能如果身份合法且角色适当,则执行。通用执行层:如前所述,通用执行层分为执行代理进程、执行端进程和用户进程。除了隔离用户进程异常,提高稳定性之外,它还有一个好处——无损升级。当执行代理需要升级时,可以直接停止执行代理进程。由于此时已经执行的任务是由执行结束进程控制的,所以可以正常返回结果,不受影响。已经发送给执行代理的任务还没有来得及执行,重启代理后CCS-Agent会重新下发,不受影响。当执行端需要升级时,就更简单了。可以直接升级执行端。升级完成后,旧的执行端会继续执行到结束,新的任务会启动新的执行端。异常处理在系统运行过程中,难免会出现各种问题。下面我们就来和大家一起探讨一下在设计和实践中遇到的一些问题以及相应的解决方案。容量不足CCS系统上线以来,因容量问题导致的系统异常是最多的。当前CCS系统的许多特点都是从以往的经验教训中总结提炼出来的。最突出的是增加了统一接入层。并引入分层调度概念。统一接入层除了为用户提供一致的体验外,更重要的是统一分级配额和区块。通过设置分级的流量配额和阈值,可以给不同的用户不同的访问配额,必要时可以暂停某些访问配额。下发每个用户的任务,防止CCS系统后端因为突发流量而被拖垮,进而影响所有用户的使用。如果说统一接入层的加入消除了突发任务的影响,那么分层调度理念的引入则保证了重要任务不会受到影响。在引入分层调度之前,不同重要性级别的任务是混合调度的。曾经发生过因为某个任务的数据结构异常导致整个调度节点挂掉的悲剧。之后通过对调度节点进行分类,对任务进行分类,将任务从统一接入层分流,解决重要任务无法保障的问题。网络抖动网络抖动对CCS系统最直接的影响就是报文丢失。在任务调度过程中,无论是简单的客户端拉取执行进度消息,还是服务端主动推送执行进度消息,都各有不足。前者可靠性高但时延控制差,后者时延低但稳定性不足。为保证CCS系统的高可用性,通信模型层与层之间采用推拉结合的方式。客户端拉取信息时,通过降低拉取频率来降低??性能消耗。此时,延迟的增加由服务器的主动推送来补偿。单机执行异常在统一执行代理还没有诞生的史前时代,我们在单机执行命令的过程中遇到了无数的异常,典型的第三方软件bug类型(比如Pythonbug导致的程序Hang),资源耗尽型(操作系统PID耗尽无法执行新命令)、操作系统BUG型(如内核BUG导致服务器突然重启)、不可抗力型(如批量断电)serversauthorizedbyapowerfailure)等。为了保证异常任务不丢失,异常恢复快,我们在设计上主要遵循以下两点:备份优先级:执行端收到任务时的第一步不是考虑如何执行,而是考虑如何备份,即使有后续的执行结束。例外,也可以用备份信息重新执行。单线程优先级:单线程优先级主要是为了尽可能简化执行端的逻辑,避免复杂的多线程操作。毕竟越简单越容易保证稳定性。这也是执行端采用epoll执行代理进程+多执行端进程模式的主要原因。按照以上原则设计和实现的统一执行层部署在所有百度内部服务器上,在长期运行中表现出了极高的稳定性。总结通过构建CCS系统,我们解决了海量服务器上大规模执行命令的问题。在百度内部和百度云上得到了广泛的应用,承担了百度产品和百度云的大部分变革。如果您对本系统感兴趣,想应用到贵公司生产环境中,可以给我们留言,百度云智能运维团队竭诚为您服务。
