str*_*chr 15 architecture n-tier-architecture job-scheduling system-design
我正在尝试设计一个通用的作业调度程序,以扩展我的架构知识和在面试中思考系统设计问题的能力.到目前为止,我想出的是下面的内容.你能指出我应该在哪些方面努力做到全面解决这类问题吗?
我在线阅读了大量资源,但需要一些具体的指导才能继续前进.
为X公司设计通用的作业调度程序(这是当今的大型技术公司之一).
用例
创建/读取/更新/删除作业
调查过去运行的工作(工作类型,花费的时间,详细信息)
约束
每秒在系统上运行多少个作业?
=#jobs /小时由于用户+#jobs /小时由于机器
= 1m*0.5 /天/ 24/3600 + 1m/50*20/24/3600
〜= 12个工作/秒
系统需要存储多少数据?
推理:我只存储作业执行细节,在其他机器上完成实际工作(脚本执行),收集的一些数据是结束时间,成功/失败状态等.这些都可能只是文本,也可能是图形用于说明目的.我将通过作业调度程序(即过去10年)存储>>在系统中执行的所有作业的数据
=(设置作业详细信息的页面大小+收集的有关作业的数据大小)*作业数量*365>天*10年= 1 MB*900 000*365*10
〜= 3600 000 000 MB
= 3600 000 GB
= 3600 TB = 3.6 PB
抽象设计
根据上述信息,我们不需要太多的机器来保存数据.我会将设计分解为以下内容:
应用层:提供请求,显示UI详细信息.
数据存储层:类似于大型哈希表:存储键值的映射(键是由运行的dateTime组织的作业,而值将显示这些作业的详细信息).这样可以轻松搜索历史和/或预定作业.
瓶颈:
流量:12个工作/秒不是太具有挑战性.如果出现这种情况,我们可以使用负载均衡器将作业分发到不同的服务器以便执行.
数据:在3.6 TB时,我们需要一个可以轻松查询的哈希表,以便快速访问已在应用程序中执行的作业.
缩放抽象设计
这个作业调度程序的本质是它每个作业都拥有以下几个状态之一:Pending,Failed,Success,Terminated.没有业务逻辑返回很少的数据.
为了处理流量,我们可以拥有一个处理12个请求/秒的应用服务器和一个备份,以防这个失败.将来,我们可以使用负载均衡器来减少发送到每个服务器的请求数量(假设> 1台服务器正在生产中)这样做的好处是减少请求/服务器数量,增加可用性(如果一台服务器出现故障,以及处理spike-y交通井).
对于数据存储,要存储3.6 TB的数据,我们需要一些机器将其保存在数据库中.我们可以使用noSQL db或SQL db.鉴于后者有更广泛的使用和社区支持,这将有助于解决问题,目前被大公司使用,我会选择mySQL数据库.
随着数据的增长,我将采用以下策略来处理它:
1)在哈希上创建唯一索引
2)通过添加更多内存来垂直扩展mySQL数据库
3)通过分片对数据进行分区
4)使用具有主 - 主复制的主从复制策略来确保数据冗余
结论
因此,这将是我对作业调度程序组件的设计.
Mic*_*son 26
大多数大型作业调度程序都会考虑文档中未涉及的方面.
一些关键问题是:(没有特别的顺序)
我确信还有更多的东西 - 尝试浏览slurm或grid-engine上的文档以获得更多想法.
还需要考虑的事项:
您描述的大部分内容已由不同的框架实现,用于调度和执行作业。我所知道的一种——石英。虽然我会在 Quartz 中实现一些不同的东西,但它有很好的文档记录,并且会给你很多关于工作和他们通常面临的障碍的想法。
您描述的方法很好,但我会从中消除特定于域的问题(例如并行处理、分片、缩放)。如果作业要在不同的机器上运行,那是因为具体案例(例如为金融银行运行的作业)无法在一台机器上运行。我不认为您作为作业引擎的开发人员应该担心这一点。原因是您正在开发一个框架,而不是一个产品化的应用程序。
如果您打算为作业引擎本身引入分片,我认为您高估了作业引擎本身的复杂性。作业执行(框架)部分本身不会有很大的偶然性。然而,具体的实现,比如银行软件作业,可能需要处理相同的数据,但不同的数据集,然后你就有了分片。因此,简而言之,引入扩展机制超出了您的工作范围。
还有一点,我没有看到作业执行和消息总线之间存在相似之处,所以我不评论这个方向。