一种解决Spark数据倾斜问题的负载均衡方法及装置与流程

文档序号:15517583发布日期:2018-09-25 18:43阅读:754来源:国知局

本发明属于在线集群资源调度技术领域,涉及一种解决spark数据倾斜问题的负载均衡方法及装置。



背景技术:

学术界和工业界广泛采用大规模的内存计算平台,处理来自不同应用程序和数据源的大量数据。这些平台通过在内存中缓存中间应用程序数据,并利用更强大、更灵活的基于有向无环图(dag)的任务调度机制,大大减少磁盘i/o的次数。同时,基于dag的编程范式为用户提供了表达应用程序需求的灵活性,然而,复杂的任务调度使用户识别应用程序瓶颈以及性能调优带来了巨大挑战。

spark作为当今流行的内存计算平台,以其先进的设计理念,迅速受到学术界和工业界的追捧。spark平台的计算效率胜过广泛使用的mapreduce的开源实现hadoop平台,官方的测试结果表明,当数据从磁盘中读取时,spark的计算效率是hadoopmapreduce的10倍以上;当数据从内存中读取时,spark的计算效率是hadoopmapreduce的100倍。spark通过弹性分布式数据集(rdd)设计思想及管道流计算方式,优化了应用程序的执行逻辑。当大数据应用遇到行动算子才会生成一个spark作业(job),而一个作业由一系列阶段组成。按照rdd的宽依赖与窄依赖关系,分为两种类型的阶段:map阶段和reduce阶段,如图1所示。在map阶段中,从节点执行原始问题的部分输入数据,当执行完子问题后将结果写入内存或磁盘;在reduce阶段中,各任务从相应节点拉取计算结果,重新组成原始问题的输出。这种并行计算模式,使得spark能够通过集群方式,高效地处理大数据任务。

然而,在spark的执行过程中,由于输入数据分布的不均衡以及spark默认分区算法分配的不均衡,会出现数据倾斜问题;当发生数据倾斜时,部分任务的执行时间会明显多于其他任务,这一现象在reduce阶段中尤其明显。由于同一阶段的任务具有同步障碍,只有在当前stage中运行最慢的任务执行完毕时,才能开始后续阶段中任务的执行,因此,当出现数据倾斜时,会增加整个作业的总完工时间,从而降低程序执行效率,进而增加系统总能耗。

现有的spark平台中,为了防止straggler型任务,采用了与hadoopmapreduce类似的推测执行机制。为了最大化系统性能,理想情况下每个任务的执行时间应大致相同。因原始输入数据的不均衡分布等原因造成任务执行时间差异巨大时,spark检测到部分任务为straggler型任务,会尝试在其余空闲节点以相同输入数据启动相同任务,将优先完成的任务的计算结果作为最终结果。当集群由于硬件老化、软件错误配置等原因造成部分任务运行缓慢时,spark的推测执行机制能有效地减少作业的总完工时间。然而当产生数据倾斜的原因是由于其输入数据分布的不均衡时,spark的推测执行机制就无能为力了。这是因为输入数据相同的任务在不同机器上重新执行会导致相同的执行时间,而冗余任务占用了集群部分资源,最终将导致整个作业的总完工时间增加。



技术实现要素:

有鉴于此,本发明的一方面,提供一种解决spark数据倾斜问题的负载均衡方法,该方法能够减轻任务的数据倾斜程度,加快任务执行速度。

为达到上述目的,本发明提供如下技术方案:

一种解决spark数据倾斜问题的负载均衡方法,包括:

s1:监测计算节点的平均cpu利用率、内存利用率,sparkexecutor进程启动后,初始化executor的权重信息;

s2:每一个计算节点根据预设抽样比例对本地中间数据进行抽样,然后计算节点将本地抽样信息通过消息通信发送给master节点;

s3:master节点汇总所有计算节点的抽样信息,然后根据预设抽样比例,建立数据分布的直方图,预测数据分布的总体特征;

s4:根据数据分布情况,将数据划分为多个分区,分区数为所有executor总核数的整数倍,分区过程中对大型key进行拆分;

s5:计算executor的性能因子,每一个数据分区对应为一个executor任务,然后将任务按照贪心策略分配给性能因子最高的executor;

s6:在整个过程中,executor的权重根据其负载和资源利用率动态调整,重复步骤s5直到任务分配完毕。

进一步,在步骤s1中,executor的权重初始值

wi=speedcpu×(1-rcpu)×(1-rmem),

其中,speedcpu为节点cpu的主频大小,rcpu表示为节点的cpu平均利用率,rmem表示为节点的内存利用率。

进一步,在步骤s2中,包括输入rdd数据,并对输入的rdd数据通过rdd算子计算其总记录条数rddsize,即各计算节点根据拥有的rdd数据分区,分别计算每分区的记录条数,最终汇总至driver端;

根据预设抽样比例a计算总共需要抽取的样本大小

samplesize=rddsize*a,

然后根据rdd的分区数量rddpartitions,计算每一个分区需要抽取的样本大小

samplesizeperpartition=math.ceil(samplesize/rddpartitions);

各计算节点在本地按照samplesizeperpartition的大小对rdd数据分区进行随机抽样,各计算节点统计本地抽取样本key值的记录数,然后通过消息通信将(ki,ci)发送给master节点,其中ki表示key值,ci表示相应key值的记录数;

在步骤s3中,master节点汇总每个rdd数据分区的样本总数,根据预设抽样比例a,估计数据的总体分布,即求出键值对集合

tuples={(k1,c1),(k2,c2),......(km,cm)}。

进一步,根据估算的中间数据键值对集合tuples={(k1,c1),(k2,c2),......(km,cm)},计算每个分区平均应该分配的键值对数量设置每个分区被分配的数据量上限为pavg,其中,n表示分区数量,pj为每个分区所包含的键值对数量,1≤j≤n,f为分区函数,f:k→{1,…n},k为中间数据键值对key值的集合,f表示将中间数据划分到n个分区中;

然后按照ci值降序排列tuples,依次从队头取出key,将ki分配给第一个剩余容量最大的分区,如果该分区剩余容量大于等于ci,则将ki直接分配给该分区,并修改该分区剩余容量大小,如果该分区剩余容量小于ci,则分配该分区剩余容量大小的数据到该分区,将分配的ki记为ki_1,并记录ki_1的分区归属,继续分配剩余ki到剩余容量最大的分区,如果下次被分配的分区的剩余容量大小仍然不够,则依次将分配的key标记为ki_2,ki_3,...,ki_n,其中,1≤n≤partitionnum,partitionnum为分区数量,同时记录其分区归属,直到ki分配完毕,重复该过程直到所有key都完成预分区过程;如果存在ki到ki_1,ki_2,...,ki_n的转换关系,则需要将原始(ki,ci)转换为(ki_1,ci_1),(ki_2,ci_2),...,(ki_n,ci_n),即将原始ki按照ci_j大小转换为多个新的ki_j,1≤j≤n;

如果当前key在抽样集合中,则根据记录的ki或ki_j的分区归属信息分配key到相应分区,否则使用默认的哈希算法分配key到相应分区。

进一步,在步骤s4中,设置分区数量为应用预先分配的cpu核数的整数倍,即

partitionnum=λ*coreapp,

其中,coreapp为应用被分配的cpu核数,λ为预设的cpu核数的整数倍数,λ≥1。

进一步,引入控制系统理论中的一种负反馈调节机制,该机制在当前时刻加入上一时刻的调整量,在当前时刻为0时刻时,当前executor的cpu利用率cui(tj)的值为其监测值cui′(tj),在当前时刻大于等于1时刻时,当前executor的cpu利用率cui(tj)的值由上一时刻cpu利用率cui(tj-1)的值以及当前时刻的监测值cui′(tj)共同决定,每一时刻executor的cpu利用率的监测值cui′(tj)直接从系统中获取,cpu利用率的负反馈调节机制为

进一步,executor内存利用率从原始spark系统的数据结构中间接获取,在数据存储模块的blockmanagermasterendpoint类中包括blockmanageridbyexecutor和blockmanagerinfo两个哈希表,所述blockmanageridbyexecutor用于保留executor和blockmanagerid的一一对应关系,所述blockmanagerinfo用于维护blockmanagerid和blockmanagerinfo的一一对应关系,所述blockmanagerinfo中保存有每个blockmanagerid的内存使用状况,根据两个哈希表的传递关系,从blockmanagerinfo中得到每个executor的剩余内存量remainingmem,每一个executor的内存利用率

mui=(1-remainingmem/totalmem)×100%,

其中,totalmem为每个executor被分配的内存大小。

进一步,在步骤s6中,对executor的权重调整的过程包括:

s61:初始化每个executor的计算能力计数值capabilityi以及监测次数值counti;

s62:计算每个executor的cpu利用率cui以及内存利用率mui,如果executor的cpu利用率cui和内存利用率mui都没有超过其对应的cpu利用率上界cuupperbound和内存利用率上界muupperbound,则对其计算能力计数值capabilityi以及监测次数值counti都增加1,否则只增加监测次数值counti;

s63:当监测次数值counti到达设置的调整周期t时,对executor的权重进行调整,如果计算能力计数值capabilityi大于α×t,就增加executor的权重,如果计算能力计数值capabilityi小于β×t,就减少executor的权重,其中,α和β为预设的调节因子;

s64:每次权重调整完毕时都将计算能力计数值capabilityi以及监测次数值counti重新设置为0,重复该过程直到任务完成。

进一步,在步骤s5中,包括:

s51:计算每个executor的性能因子fi=wi/favg,

favg为所有executor权重的平均值,

s52:按照executor的性能因子大小降序排列所有executor;

s53:遍历所有任务,首先将任务分配到性能因子最大的executor上,如果该executor的可用cpu核数大于每个任务需要的cpu核数,则在当前executor分配该任务,同时更新该executor的可用cpu核数,任务后续将在该executor上以最大的数据本地性运行。

本发明的另一方面,提供了一种解决spark数据倾斜问题的负载均衡装置,包括:

抽样模块:根据预设抽样比例对本地中间数据进行抽样,将本地抽样信息进行汇总,再根据抽样比例,建立数据分布的直方图,预测数据分布的总体特征;

均衡分区模块:根据数据分布情况,将数据划分为多个分区,分区数为所有executor总核数的整数倍,将中间数据均衡的分配到每个分区中;

权重调整模块:当到达设置的权重调整周期时,根据其负载和资源利用率动态调整executor的权重;

任务分配模块:计算executor的性能因子,每一个数据分区对应为一个executor任务,然后将任务按照贪心策略分配给性能因子最高的executor;

执行模块:用于按照所述顺序执行任务。

本发明的有益效果在于:本发明能够减轻任务的数据倾斜程度,加快任务执行速度,提高集群资源利用率,降低系统总能耗。

附图说明

为了使本发明的目的、技术方案和有益效果更加清楚,本发明提供如下附图进行说明:

图1为本发明背景技术所述的spark集群系统的数据处理示意图;

图2为本发明实施例所述解决spark数据倾斜问题的负载均衡方法流程图;

图3为本发明实施例所述解决spark数据倾斜问题的负载均衡装置示意图;

图4为本发明实施例所述的解决spark数据倾斜问题的负载均衡系统部署示意图;

图5为本发明实施例所述的解决spark数据倾斜问题的负载均衡样例说明图。

具体实施方式

下面将结合附图,对本发明的优选实施例进行详细的描述。

如图2所示,本实施例所述的一种解决spark数据倾斜问题的负载均衡方法,包括以下六个步骤:

s101.监测计算节点的平均cpu利用率、内存利用率,sparkexecutor进程启动后,初始化executor的权重信息;

s102.每一个计算节点根据抽样比例对本地中间数据进行抽样,该抽样比例由用户单独设置,然后计算节点将本地抽样信息通过消息通信发送给master节点;

s103.master节点汇总所有计算节点的抽样信息,然后根据抽样比例,建立数据分布的直方图,预测数据分布的总体特征;

s104.根据数据分布情况,将数据划分为多个分区,分区数为所有executor总核数的整数倍,具体倍数可以由用户指定,分区过程中对大型key进行拆分;

s105.计算executor的性能因子,每一个数据分区对应为一个executor任务,然后将任务按照贪心策略分配给性能因子最高的executor;

s106.在整个过程中,executor的权重需要根据其负载和资源利用率动态调整,重复步骤s105直到任务分配完毕。

本发明的又一实施例,如图3所示,提供了一种解决spark数据倾斜问题的负载均衡装置300,包括:

抽样模块310:根据预设抽样比例对本地中间数据进行抽样,将本地抽样信息进行汇总,再根据抽样比例,建立数据分布的直方图,预测数据分布的总体特征;

均衡分区模块320:根据数据分布情况,将数据划分为多个分区,分区数为所有executor总核数的整数倍,将中间数据均衡的分配到每个分区中;

权重调整模块330:当到达设置的权重调整周期时,根据其负载和资源利用率动态调整executor的权重;

任务分配模块340:计算executor的性能因子,每一个数据分区对应为一个executor任务,然后将任务按照贪心策略分配给性能因子最高的executor;

执行模块350:用于按照所述顺序执行任务。

本发明实施例还提供了一种包括本发明实施例的图4所示的调度装置的spark集群系统,该集群系统可按sparkstandalone运行架构进行部署。

可选地,executor的权重初始值,其中,speedcpu为节点cpu的主频大小,rcpu表示为节点的cpu平均利用率,rmem表示为节点的内存利用率,权重的初始值由节点cpu的主频大小、cpu利用率以及内存利用率共同决定,即初始值与节点硬件属性以及资源利用率高度相关,节点cpu的主频越大、cpu利用率越低、内存利用率越低,该executor的空闲计算能力越大,分配数据时具有优先分配权。

可选地,对输入的rdd数据通过rdd算子计算其总记录条数rddsize,即各计算节点根据拥有的rdd数据分区,分别计算每分区的记录条数,最终汇总至driver端;根据设置的抽样比例a计算总共需要抽取的样本大小samplesize=rddsize*a,然后根据rdd的分区数量rddpartitions,计算每一个分区需要抽取的样本大小

samplesizeperpartition=math.ceil(samplesize/rddpartitions);

各计算节点在本地按照samplesizeperpartition的大小对rdd数据分区进行随机抽样,各计算节点统计本地抽取样本key值的记录数,然后通过消息通信将(ki,ci)发送给master节点,其中ki表示key值,ci表示相应key值的记录数;master节点汇总每个rdd数据分区的样本总数,根据设置的抽样比例a,估计数据的总体分布,即求出键值对集合tuples={(k1,c1),(k2,c2),......(km,cm)}。

可选地,根据估算的中间数据键值对集合tuples={(k1,c1),(k2,c2),......(km,cm)},计算每个分区平均应该分配的键值对数量设置每个分区被分配的数据量上限为pavg,其中,n表示分区数量,pj为每个分区所包含的键值对数量,1≤j≤n,f为分区函数,f:k→{1,…n},k为中间数据键值对key值的集合,f表示将中间数据划分到n个分区中;然后按照ci值降序排列tuples,依次从队头取出key,将ki分配给第一个剩余容量最大的分区,如果该分区剩余容量大于等于ci,则将ki直接分配给该分区,并修改该分区剩余容量大小,如果该分区剩余容量小于ci,则分配该分区剩余容量大小的数据到该分区,将分配的ki记为ki_1,并记录ki_1的分区归属,继续分配剩余ki到剩余容量最大的分区,如果下次被分配的分区的剩余容量大小仍然不够,则依次将分配的key标记为ki_2,ki_3,...,ki_n,其中,1≤n≤partitionnum,partitionnum为分区数量,同时记录其分区归属,直到ki分配完毕,重复该过程直到所有key都完成预分区过程;如果存在ki到ki_1,ki_2,...,ki_n的转换关系,则需要将原始(ki,ci)转换为(ki_1,ci_1),(ki_2,ci_2),...,(ki_n,ci_n),即将原始ki按照ci_j大小转换为多个新的ki_j,1≤j≤n;如果当前key在抽样集合中,则根据记录的ki或ki_j的分区归属信息分配key到相应分区,否则使用默认的哈希算法分配key到相应分区。

可选地,为了最大化应用预先分配的资源,设置分区数量为应用预先分配的cpu核数的整数倍,即partitionnum=λ*coreapp,其中,coreapp为应用被分配的cpu核数,λ为预设的cpu核数的整数倍数,λ≥1,具体倍数可以由用户自行设置。

可选地,为了减少cpu利用率的抖动误差,引入控制系统理论中的一种负反馈调节机制,该机制在当前时刻加入上一时刻的调整量,即,在当前时刻为0时刻时,当前executor的cpu利用率cui(tj)的值为其监测值cui′(tj),在当前时刻大于等于1时刻时,当前executor的cpu利用率cui(tj)的值由上一时刻cpu利用率cui(tj-1)的值以及当前时刻的监测值cui′(tj)共同决定,而每一时刻executor的cpu利用率的监测值cui′(tj)直接从系统中获取,cpu利用率的负反馈调节机制为

可选地,executor内存利用率从原始spark系统的数据结构中间接获取。在数据存储模块的blockmanagermasterendpoint类中存在blockmanageridbyexecutor和blockmanagerinfo两个哈希表,前者保留了executor和blockmanagerid的一一对应关系,后者维护了blockmanagerid和blockmanagerinfo的一一对应关系,而blockmanagerinfo中保存了每一个blockmanagerid的内存使用状况,根据两个哈希表的传递关系,可以从blockmanagerinfo中得到每个executor的剩余内存量remainingmem,每个executor被分配的内存大小在应用提交时就已经确定,则每一个executor的内存利用率mui=(1-remainingmem/totalmem)×100%,其中,totalmem为每个executor被分配的内存大小。

可选地,计算节点的每个executor的空闲计算能力是随着其资源使用状况动态变化的,需要在任务执行的过程中对每个executor的空闲计算能力进行度量,当到达设置的权重调整周期时对executor的权重进行调整,具体的调整过程为:初始化每个executor的计算能力计数值capabilityi以及监测次数值counti;计算每个executor的cpu利用率cui以及内存利用率mui,如果executor的cpu利用率cui和内存利用率mui都没有超过其对应的cpu利用率上界cuupperbound和内存利用率上界muupperbound,则对其计算能力计数值capabilityi以及监测次数值counti都增加1,否则只增加监测次数值counti;当监测次数值counti到达设置的调整周期时t,正式开始对executor的权重进行调整,如果计算能力计数值capabilityi大于α×t,则说明当前executor在周期t内有大于α×t次处于不饱和状态,其空闲计算能力较高,可以执行更多任务,即增加其权重,反之,如果计算能力计数值capabilityi小于β×t,则说明当前executor在周期t内有小于β×t次处于不饱和状态,其计算负载较高,应该减少任务的分配,即将其权重减少,其中,α和β为调节因子,由用户根据场景进行设置,在实践中根据经验默认设置为0.8和0.2;每次权重调整完毕时都将计算能力计数值capabilityi以及监测次数值counti重新设置为0,重复该过程直到任务完成。

可选地,为了降低计算复杂度,任务分配时主要采取贪心策略,首先计算每个executor的性能因子fi=wi/favg,favg为所有executor权重的平均值,按照executor的性能因子大小降序排列所有executor;遍历所有任务,首先将任务分配到性能因子最大的executor上,如果该executor的可用cpu核数大于每个任务需要的cpu核数(默认为1核),则在当前executor分配该任务,同时更新该executor的可用cpu核数,任务后续将在该executor上以最大的数据本地性运行;如果任务需要分配多轮,则重复该过程直到所有任务分配完成。

以下通过具体实例来进一步说明本发明各实施例:

如图5所示,假设一个spark应用中存在3种key(k1,k2,k3),且需要将其分为3个分区,通过抽样算法估计k1,k2,k3的数量分别为2000、200、100,每个分区平均应该分配的键值对数量为767,将3个分区被分配的数据量上限设置为767,首先对k1进行分配,将k1分配到第1个分区上,由于该分区剩余容量767小于k1数量2000,故分配767个key到第1个分区上,将这部分key记为ki_1,继续分配剩余k1,由于第2个分区剩余容量767小于k1剩余数量1233,故分配767个key到第2个分区上,将这部分key记为ki_2,继续分配剩余k1,由于第3个分区剩余容量767大于k1剩余数量466,则将剩余的k1全部分配到第3个分区,将这部分key记为ki_3,k1分配完毕,此时第3个分区剩余容量大小为301,同理分配k2,k3到第3个分区上,此时,3个分区上被分配的键值对数量分别为767、767、766,各分区间的键值对数量大致相同。每一个数据分区对应为一个executor任务,将任务按照贪心策略分配给性能因子最高的executor,executor的权重需要wi=speedcpu×(1-rcpu)×(1-rmem)根据其负载和资源利用率动态调整,重复该步骤直到任务分配完毕。

最后说明的是,以上优选实施例仅用以说明本发明的技术方案而非限制,尽管通过上述优选实施例已经对本发明进行了详细的描述,但本领域技术人员应当理解,可以在形式上和细节上对其作出各种各样的改变,而不偏离本发明权利要求书所限定的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1