2023年7月21日发(作者:)
分布式调度框架原理与技术选型分布式任务调度框架1、什么是分布式任务调度?2、常见的分布式任务调度框架有哪些?3、分布式任务调度框架的技术选型?4、分布式任务调度框架的安装与使⽤?分布式任务调度,三个关键词:分布式、任务调度、配置中⼼。分布式:平台是分布式部署的,各个节点之间可以⽆状态和⽆限的⽔平扩展;任务调度:涉及到任务状态管理、任务调度请求的发送与接收、具体任务的分配、任务的具体执⾏;(这⾥⼜会遇到⼀共要处理哪些任务、任务要分配到哪些机器上处理、任务分发的时候判断哪些机器可以⽤等问题,所以⼜需要⼀个可以感知整个集群运⾏状态的配置中⼼)配置中⼼:可以感知整个集群的状态、任务信息的注册⼀个分布式任务调度系统需要以下内容:web模块、server模块、Scheduler模块、worker模块、注册中⼼。1、Web模块:⽤来提供任务的信息,控制任务的状态、信息展⽰等。2、Server模块:负责接收web端传来的任务执⾏的信息,下发任务调度请求给Scheduler,会去注册中⼼进⾏注册3、Scheduler模块:接收server端传来的调度请求,将任务进⾏更加细化的拆分然后下发,到注册中⼼进⾏注册,获取到可以⼲活的worker。4、Worker模块:负责具体的任务执⾏。5、注册中⼼。1、什么是分布式任务调度?任务调度是指基于给定的时间点,给定的时间间隔或者给定执⾏次数⾃动的执⾏任务。任务调度是是操作系统的重要组成部分,⽽对于实时的操作系统,任务调度直接影响着操作系统的实时性能。任务调度涉及到多线程并发、运⾏时间规则定制及解析、线程池的维护等诸多⽅⾯的⼯作。WEB服务器在接受请求时,会创建⼀个新的线程服务。但是资源有限,必须对资源进⾏控制,⾸先就是限制服务线程的最⼤数⽬,其次考虑以线程池共享服务的线程资源,降低频繁创建、销毁线程的消耗;然后任务调度信息的存储包括运⾏次数、调度规则以及运⾏数据等。⼀个合适的任务调度框架对于项⽬的整体性能来说显得尤为重要。2、常见的任务调度框架有哪些?我们在实际的开发⼯作中,或多或少的都会⽤到任务调度这个功能。常见的分布式任务调度框架有:cronsun、Elastic-job、saturn、lts、TBSchedule、xxl-job等。2.1cronsuncrontab是Linux系统⾥⾯最简单易⽤的定时任务管理⼯具,在Linux上由crond来周期性的执⾏指令列表,执⾏的任务称为cron job,多个任务就称为crontab。crontab任务调度指令的基本格式为:* * * * * command 分 时 ⽇ ⽉ 周 命令但是时间久了之后会发现,crontab会存在⼀些问题:⼤量的crontab分散在各台服务器,带来了很⾼的维护成本;任务没有按时执⾏,过了很长的时间才能发现,需要重试或者排查;crontab分散在很多集群上,需要⼀台⼀台的去查看⽇志;crontab存在单点问题,对于不能重复执⾏的定时任务很伤脑;……因此⾮常需要⼀个集中管理定时任务的系统,于是就有了cronsun。cronsun是⼀个分布式任务系统,单个节点和Linux机器上的contab近似,是为了解决多台Linux机器上crontab任务管理不⽅便的问题,同时提供了任务⾼可⽤的⽀持(当某个节点死机的时候可以⾃动调整到正常的节点执⾏)。与此同时,它还⽀持界⾯管理机器上的任务,⽀持任务失败邮件提醒,安装简单,使⽤简便,是替换crontab的⼀个不错的选择。cronsun中主要有三个组件,都是通过etcd通讯的。cronnode负责节点的分组及节点的状态,cronweb是⽤来管理任务的、任务的执⾏结果都可以在上⾯看。cronsun的系统架构如下图所⽰,简单的来说就是,所有的任务都会存储在⼀个分布式etcd⾥,单个crond部署成⼀个服务,也就是图中所⽰的node.1、node.2、node.n等,然后再由web界⾯去管理。如果任务执⾏失败的话,会发送失败的邮件,当单个节点死机的时候,也会⾃动调整到正常的节点去执⾏任务。cronsun是在管理后台添加任务的,所以⼀旦管理后台泄漏出去了,则存在⼀定的危险性,所以cronsun⽀持的安全设置: {"open": true,"#users": "允许选择运⾏脚本的⽤户", "users": ["www", "db" ],"#ext": "允许添加以下扩展名结束的脚本", "ext": [".", "." ]} 如以上设置开启安全限制,则添加和执⾏任务的时候只允许选择配置⾥⾯指定的⽤户来执⾏脚本,并且脚本的扩展名要在配置的脚本的扩展名限制的列表⾥⾯。2.2、Elastic-jobElastic-job是当当开源的⼀款⾮常好⽤的作业框架,Elastic-job在2.x之后,出现了两个相互独⽴的产品线:Elastic-job-lite和Elastic-job-cloud。截⽌2019年8⽉,已近2年没有更新维护了,所以⽣产上谨慎使⽤2.2.1、Elastic-job-lite Elastic-job-lite定位为轻量级⽆中⼼化的解决⽅案,使⽤jar包的形式提供分布式任务的协调服务,外部依赖仅依赖于zookeeper。 Elastic-job-lite的架构图如下图所⽰:从上⾯的框架图中可以看出,Elastic-job-lite框架使⽤zookeeper作为注册中⼼,Elastic-job-lite框架通过监听感知zookeeper数据的变化,并做相应的处理;运维平台也仅是通过读取zk数据来展现作业状态,或是更新zk数据修改全局配置。运维平台和Elastic-job-lite没有直接的关系,完全解耦合。Elastic-job-lite并不直接提供数据处理的功能,框架只会将分⽚项分配给各个正在运⾏中的服务器,分⽚项与真是数据的对应关系需要开发者在应⽤程序中⾃⾏处理。Elastic-job-lite并⽆作业调度中⼼节点,⽽是基于部署作业框架的程序在到达相应时间点时各⾃触发调度。注册中⼼仅⽤于作业注册和监控信息存储,⽽主作业节点仅⽤于处理分⽚和清理的功能。(1)注册中⼼的数据结构 我们先来了解⼀下该框架在zookeeper上的节点情况。⾸先注册中⼼在命名的空间下创建作业名称节点(作业名称⽤来区分不同的作业,⼀旦修改名称,则认为是新的作业),作业名称节点下⼜包含5个⼦节点:config:保存作业的配置信息,以JSON格式存储sharding:保存作业的分⽚信息,它的⼦节点是分⽚项序号,从零开始,⾄分⽚总数减⼀leader:该节点保存作业服务器主节点的信息,分为election、sharding和failover三个⼦节点,分别⽤于主节点的选举、分⽚和失效转移instances:该节点保存的是作业运⾏实例的信息,⼦节点是当前作业运⾏实例的主键servers:该节点保存作业服务器的信息,⼦节点是作业服务器的IP地址(2)实现原理第⼀台服务器上线触发主服务器选举,主服务器⼀旦下线,则重新触发选举,选举过程中阻塞,只有当主服务器选举完成,才会去执⾏其他的任务;某服务器上线时会⾃动将服务器的信息注册到注册中⼼,下线时会⾃动更新服务器的状态;主节点选举,服务器上下线,分⽚总数变更均更新重新分⽚标记;定时任务触发时,如需重新分⽚,则通过主服务器分⽚,分⽚过程中阻塞,分⽚结束后才可以执⾏任务。如分⽚过程中主服务器下线,则先选举主服务器在分⽚;由上⼀项说明可知,为了维持作业运⾏时的稳定性,运⾏过程中只会标记分⽚的状态,不会重新分⽚,分⽚仅可能发⽣在下次任务触发前;每次分⽚都会按照ip排序,保证分⽚结果不会产⽣较⼤的波动;实现失效转移功能,在某台服务器执⾏完毕后主动抓取未分配的分⽚,并且在某台服务器下线后主动寻找可⽤的服务器执⾏任务。elastic底层的任务调度还是使⽤的quartz,通过zookeeper来动态给job节点分⽚。如果很⼤体量的⽤户需要我们在特定的时间段内计算完成,那么我们肯定是希望我们的任务可以通过集群达到⽔平的扩展,集群⾥的每个节点都处理部分的⽤户,不管⽤户的数量有多⼤,我们只需要增加机器就可以了。举个例⼦:⽐如我们希望3台机器跑job,我么将我们的任务分成3⽚,框架通过zk的协调,最终会让3台机器分配到0,1,2的任务⽚,⽐如server0->0、server1->1、server2->2,当server0执⾏时,可以只查询id%3==0的⽤户,server1可以只查询id%3==1的⽤户,server2可以只查询id%3==2的⽤户。在以上的基础上再增加⼀个server3,此时,server3分不到任何的分⽚,没有分到任务分⽚的程序将不执⾏。如果此时server2挂了,那么server2被分到的任务分⽚将会分配给server3,所以server3就会代替server2执⾏。如果此时server3也挂了,那么框架也会⾃动的将server3的任务分⽚随机分配到server0或者server1,那么就可能成:server0->0、server1->1,2。这种特性称之为弹性扩容。2.2.2、Elastic-job-cloudElastic-job-cloud包含了Elastic-job-lite的全部功能,它是以私有云平台的⽅式提供集资源、调度以及分⽚为⼀体的全量级解决⽅案,依赖于Mesos和Zookeeper,它额外提供了资源治理、应⽤分发以及进程隔离等服务。他们两个提供同⼀套API开发作业,开发者仅需⼀次开发,然后可根据需要以lite或cloud的⽅式部署。2.3、saturnSaturn(定时任务调度系统)是唯品会⾃主研发的分布式的定时任务的调度平台,它是基于Elastic-job版本1开发的。⽬标是取代传统的Linux Cron/Spring Batch Job/Quartz的⽅式,做到全域统⼀配置、统⼀监控、任务⾼可⽤以及分⽚。Saturn的任务可以使⽤多种语⾔开发,⽐如python、Go、Shell、Java、Php等。 Saturn包括两⼤部分,Saturn Console和Saturn Executor。Console是⼀个WEB UI,⽤来对作业/Executor的管理,统计报表展现等。他同时也是整个调度系统的⼤脑:将作业任务分配到各Executor。Executor是执⾏任务的worker:按照作业配置的要求去执⾏部署于Executor所在容器或物理机当中的作业脚本和代码。Saturn⾼度依赖于zookeeper,每个executor及调度服务都会在zookeeper上进⾏注册,确保调度程序能够及时得到executor的状态。Saturn定时任务调度的最⼩单位是分⽚,即任务的⼀个执⾏单元。Saturn的基本任务就是将任务分成多个分⽚,并将每个分⽚通过算法调度到对应的executor上去执⾏。2.3.1、Staurn基本原理Saturn的基本原理是将作业在逻辑上划分为若⼲个分⽚,通过作业分⽚调度器将作业分⽚指派给特定的执⾏节点。执⾏节点通过quartz触发执⾏作业的具体实现,在执⾏的时候,会将分⽚序号和参数作为参数传⼊。作业的实现逻辑需分析分⽚序号和分⽚参数,并以此为依据来调⽤具体的实现(⽐如⼀个批量处理数据库的作业,可以划分0号分⽚处理1-10号数据库,1号分⽚可以处理11-20号数据库)。2.3.2、Saturn作业调度算法(1)⽅案的设计原理是给每个作业分⽚⼀个负载值和优先执⾏节点(prefer list),当需要重新分⽚时,参考作业优先设定和执⾏节点的负载值来进⾏域内节点之间的资源分配,从⽽达到资源平衡。(2)前置条件A:每个分⽚都引⼊⼀个负载值(load),由⽤户通过Saturn UI界⾯输⼊B:为每⼀个作业引⼊新的属性prefer list(优先列表,或者叫欲分配列表),由管理员通过ui界⾯编辑C:作业引⼊启⽤状态(enabled/disabled),⽤户通过UI界⾯改变这个状态;启⽤状态的作业会被节点执⾏,且不可编辑、删除,不可对prefer list进⾏调整,禁⽤状态的作业不会被执⾏(3)实施步骤第⼀步,摘取;第⼆步,放回(将这些作业分⽚按照负载值从⼤到⼩顺序逐个分配给负载最⼩的执⾏节点)。(3.1)executor上线摘取:第⼀步,找出新上线节点的全部可执⾏作业列表;对于每个作业,判断prefer list中是否包含了新上线的节点;如果是,则摘取其中全部的分⽚;这些已经处理过的作业称为预处理作业;第⼆步,从新上线节点的作业列表中减去预分配作业,然后使⽤以下的⽅法依次摘取:假如上线的executor为a,它能处理的作业类型为j1,j2(已减去预分配列表)。遍历当前域下的executor列表,拿掉全部作业类型为j1,j2的分⽚,加上尚未分配的j1,j2作业分⽚列表,作为算法的待分配列表在处理每个节点时,每拿掉⼀个作业分⽚后判断被拿掉的负载(load)是否已经超过了⾃⾝处理前总负载(load)的1/n(n为当前executor节点的总数量),如果超过,则本执⾏节点摘取完成,继续处理下⼀个执⾏节点;如果不超过则继续摘取,直到超过(⼤于等于)为⽌。放回:a.构造需要添加的作业分⽚列表,我们起名为待分配列表,长度为n,待分配列表按照负载(load)从⼤到⼩排序,排序时需保证相同作业的所有分⽚时连续的b.构造每种作业类型的executor列表(如果有prefer list,且有存活,则该作业的executor列表就是prefer list),得到⼀个map
xxl-job-lite的执⾏器实际是⼀个ConcurrentHashMap容器。3、任务调度框架的技术选型?1、Quartz:Java事实上的定时任务标准,但是关注点在于定时任务⽽⾮数据,虽然实现了⾼可⽤,但是缺少分布式并⾏调度的功能,性能低。2、TBSchedule:阿⾥早期开源的分布式任务调度系统。代码略陈旧,使⽤的是Timer⽽不是线程池执⾏任务调度。TBSchedule的作业类型⽐较单⼀,只能是获取/处理数据⼀种模式,⽂档缺失⽐较严重。3、详见分布式调度框架对⽐表格~4、分布式任务调度框架的安装与使⽤?4.1、Elastic-job1、环境准备:jdk1.7+、zookeeper3.4.6+、maven3.0.4+2、安装zookeeper3.4.12并启动这⾥zookeeper占⽤了2181端⼝。3、创建简单任务添加依赖:写⼀个简单的任务:在项⽬⼊⼝处添加作业的配置和zk的配置:运⾏,得到结果:4、下载Elastic-job-lite源码,使⽤maven进⾏打包。在elastic-job-lite/elastic-job-lite-console/target/elastic-job-lite-console-3.0.0.M1-SNAPSHOT/中,然后解压,会有和两个脚本,启动。浏览器中输⼊localhost:8899,就可以管理任务了。4.2、xxl-job-lite1、调度数据库初始化,tables_2、下载源码:包括调度中⼼+公共依赖+执⾏器⽰例3、配置部署“调度中⼼”:修改数据库配置——将项⽬进⾏打包——将xxl-job-admin包部署到tomcat上4、输⼊localhost:8080/xxl-job-admin即可访问调度中⼼5、配置部署执⾏器:xxl-job-executor-sample-springboot打成jar包直接运⾏,其他的打成war包部署在tomcat上。6、写⼀个任务,运⾏,去执⾏器上进⾏注册,然后调度中⼼配置执⾏器信息,添加任务
附录1、etcd etcd是⼀个开源的、分布式的键值对数据存储系统,提供共享配置、服务的注册和发现。etcd内部采⽤raft协议作为⼀致性算法,是基于Go语⾔实现的。2、zookeeperzookeeper是⼀个开源的分布式协调服务,它为分布式应⽤提供了⾼效且可靠的分布式协调服务,提供了诸如统⼀命名空间服务、配置服务和分布式锁等分布式基础服务。3、分布式锁 假如我们由三台机器,每台机器上都有⼀个进程。假设我们在第⼀台机器上挂载了⼀个资源,三个进程都要来竞争这个资源。我们不希望这三个进程同时来访问,那么就需要有⼀个协调器,来让他们有序的对该资源进⾏访问。这个协调器就是我们所说的那个锁,⽐如说“进程1”在使⽤该资源的时候,就会先去获得锁,“进程1”就对该资源保持独占,这样其他的进程就⽆法访问该资源。“进程1”⽤完该资源后就会将锁释放掉,让其他的进程来获得锁。因此这个锁机制就能保证我们的进程有序的访问该资源。就称作为“分布式锁”,是分布式协调技术实现的核⼼内容4、分⽚任务的分布式执⾏,需要将⼀个任务拆分为多个独⽴的任务项,然后由分布式的服务器分别执⾏某⼀个或⼏个分⽚项。5、单点故障通常分布式系统采⽤主从模式,就是⼀个主控机连接多个处理节点。主节点负责分发任务,从节点负责处理任务,当我们的主节点发⽣故障时,那么整个系统就瘫痪了,这就叫做单点故障。传统的解决办法:就是准备⼀个备⽤节点,这个备⽤节点定期给当前主节点发送ping包,主节点收到ping包后向备⽤节点发送回复Ack,当备⽤节点收到回复后就会认为主节点还活着,让他继续提供服务。当主节点挂了,那么备⽤节点就收不到Ack回复了,然后备⽤节点就代替它成为了主节点。但是存在⼀个安全隐患,那就是当发⽣⽹络故障时,备⽤节点收不到主节点的回复Ack,他会认为主节点死了,它会代替主节点成为新的主节点。zookeeper解决⽅案:在引⼊了zookeeper后我们启⽤了两个主节点,A和B启动后他们都会去Zookeeper去注册⼀个节点,假设A注册的节点为master-01,B注册的节点为master-02,注册完之后进⾏选举,编号最⼩的节点将被选举为主节点。如果A挂了,它在zookeeper注册的节点将会被⾃动删除,Zookeeper感知到节点的变化,然后再次发出选举,这时候B将获胜成为新的主节点。如果A恢复了,它会去zookeeper再注册⼀个节点,编号为master-03。这时zookeeper感知到节点的变化,会再次发起选举,此时还是B胜出。那么B继续担任主节点,A则成为备⽤节点。6、Mesos ——像⽤⼀台电脑⼀样使⽤整个数据中⼼是Apache下的开源分布式资源管理框架,它被称为分布式系统的内核,是以与Linux内核同样的原则⽽创建的,不同点仅仅是在于抽象的层⾯。使⽤ZooKeeper实现Master和Slave的容错。7、FailStore策略 FailStrore,顾名思义就是Fail and Store,这个主要是⽤于失败了存储的,主要⽤于节点容错,当远程数据交互失败后,存储在本地,等待远程通讯恢复后,再将数据进⾏提交。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689930378a295230.html
评论列表(0条)