作业(Job)是DolphinDB中最基本的执行单位,可以简单理解为一段DolphinDB脚本代码在DolphinDB系统中的一次执行。Job根据阻塞与否可分成同步作业和异步作业。
同步作业
同步作业也称为交互式作业(Interactive Job),它的主要来源有:
由于这种类型的作业对实时性要求较高,DolphinDB在执行过程中会自动给予较高的优先级,使其更快地得到计算资源。
异步作业
异步作业是在DolphinDB后台执行的作业,包括:
这类任务一般对结果的实时反馈要求较低,且需要长期执行,DolphinDB一般会给予较低的优先级。
子任务
在DolphinDB中,若数据表数据量过大,一般都需要进行分区处理。如果一个Job A里含有分区表的查询计算任务(如SQL查询),将会分解成多个子任务并送到不同的节点上并行执行,等待子任务执行完毕之后,再合并结果,继续Job A的执行。类似的,DolphinDB的分布式计算也会产生子任务。因此,Job也可以理解成一系列的子任务。
Worker与Executor
DolphinDB是一个P2P架构的系统,即每一个Data Node的角色都是相同的,它们都可以执行来自用户提交的Job,而因为一个Job可能产生子任务,每个Data Node需要有负责Job内部执行的调度者,我们称它为Worker,它负责处理用户提交的Job,简单计算任务的执行,并执行Job的任务分解,任务分发,并汇集最终的执行结果。Job中分解出来的子任务将会被分发到集群中的Data Node上(也有可能是本地Data Node),并由Data Node上的Worker或Executor线程负责执行。
具体Worker与executor在执行job的时候主要有以下几种情况:
为了最大化性能,DolphinDB会将子任务发送到数据所在的Data Node上执行,以减少网络传输开销。比如:
Job调度
Job优先级
在DolphinDB中,Job是按照优先级进行调度的,优先级的取值范围为0-9,取值越高优先级则越高。对于优先级高的Job,系统会更及时地给与计算资源。每个Job一般默认会有一个default priority,取值为4,然后根据Job的类型又会有所调整。
Job调度策略
基于Job的优先级,DolphinDB设计了多级反馈队列来调度Job的执行。具体来说,系统维护了10个队列,分别对应10个优先级,系统总是分配线程资源给高优先级的Job,对于处于相同优先级的Job,系统会以round robin的方式分配线程资源给Job;当一个优先级队列为空的时候,才会处理低优先级的队列中的Job。
Job并行度
由于一个Job可能会分成多个并行子任务,DolphinDB的Job还拥有一个并行度parallelism,表示在一个Data Node上,将会最多同时用多少个线程来执行Job产生的并行任务,默认取值为2,可以认为是一种时间片单位。举个例子,若一个Job的并行度为2,Job产生了100个并行子任务,那么Job被调度的时候系统只会分配2个线程用于子任务的计算,因此需要50轮调度才能完成整个Job的执行。
Job优先级的动态变化
为了防止处于低优先级的Job被长时间饥饿,DolphinDB会适当降低Job的优先级。具体的做法是,当一个job的时间片被执行完毕后,如果存在比其低优先级的Job,那么将会自动降低一级优先级。当优先级到达最低点后,又回到初始的优先级。因此低优先级的任务迟早会被调度到,解决了饥饿问题。
设置Job的优先级
DolphinDB的Job的优先级可以通过以下方式来设置:
计算容错
DolphinDB database 的分布式计算含有一定的容错性,主要得益于分区副本冗余存储。当一个子任务被发送到一个分区副本节点上之后,若节点出现故障或者分区副本发生了数据校验错误(副本损坏),Job Scheduler(即某个Data Node的一个worke线程)将会发现这个故障,并且选择该分区的另一个副本节点,重新执行子任务。用户可以通过设置dfsReplicationFactor参数来调整这种冗余度。
计算与存储耦合以及作业之间的数据共享
DolphinDB的计算是尽量靠近存储的。DolphinDB之所以不采用计算存储分离,主要有以下几个原因:
综上这些原因,DolphinDB采取了计算与存储耦合的架构。具体来说:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!