elastic-job详解(一):数据分片
數(shù)據(jù)分片的目的在于把一個(gè)任務(wù)分散到不同的機(jī)器上運(yùn)行,既可以解決單機(jī)計(jì)算能力上限的問(wèn)題,也能降低部分任務(wù)失敗對(duì)整體系統(tǒng)的影響。elastic-job并不直接提供數(shù)據(jù)處理的功能,框架只會(huì)將分片項(xiàng)分配至各個(gè)運(yùn)行中的作業(yè)服務(wù)器(其實(shí)是Job實(shí)例,部署在一臺(tái)機(jī)器上的多個(gè)Job實(shí)例也能分片),開(kāi)發(fā)者需要自行處理分片項(xiàng)與真實(shí)數(shù)據(jù)的對(duì)應(yīng)關(guān)系。框架也預(yù)置了一些分片策略:平均分配算法策略,作業(yè)名哈希值奇偶數(shù)算法策略,輪轉(zhuǎn)分片策略。同時(shí)也提供了自定義分片策略的接口。
分片原理
elastic-job的分片是通過(guò)zookeeper來(lái)實(shí)現(xiàn)的。分片的分片由主節(jié)點(diǎn)分配,如下三種情況都會(huì)觸發(fā)主節(jié)點(diǎn)上的分片算法執(zhí)行:
- 新的Job實(shí)例加入集群
- 現(xiàn)有的Job實(shí)例下線(如果下線的是leader節(jié)點(diǎn),那么先選舉然后觸發(fā)分片算法的執(zhí)行)
- 主節(jié)點(diǎn)選舉
上述三種情況,會(huì)讓zookeeper上leader節(jié)點(diǎn)的sharding節(jié)點(diǎn)上多出來(lái)一個(gè)necessary的臨時(shí)節(jié)點(diǎn),主節(jié)點(diǎn)每次執(zhí)行Job前,都會(huì)去看一下這個(gè)節(jié)點(diǎn),如果有則執(zhí)行分片算法。
分片的執(zhí)行結(jié)果會(huì)存儲(chǔ)在zookeeper上,如下圖,5個(gè)分片,每個(gè)分片應(yīng)該由哪個(gè)Job實(shí)例來(lái)運(yùn)行都已經(jīng)分配好。分配的過(guò)程就是上面觸發(fā)分片算法之后的操作。分配完成之后,各個(gè)Job實(shí)例就會(huì)在下次執(zhí)行的時(shí)候使用上這個(gè)分配結(jié)果。
?
每個(gè)job實(shí)例任務(wù)觸發(fā)前都會(huì)獲取本任務(wù)在本實(shí)例上的分片情況(直接和上圖zookeeper上instance節(jié)點(diǎn)比對(duì)某一個(gè)分片是否該有這個(gè)Job實(shí)例執(zhí)行),然后封裝成shardingContext,傳遞給調(diào)用任務(wù)的實(shí)際執(zhí)行方法:
/*** 執(zhí)行作業(yè).** @param shardingContext 分片上下文*/ void execute(ShardingContext shardingContext);?
分片算法
所有的分片策略都繼承JobShardingStrategy接口。根據(jù)當(dāng)前注冊(cè)到ZK的實(shí)例列表和在客戶端配置的分片數(shù)量來(lái)進(jìn)行數(shù)據(jù)分片。最終將每個(gè)Job實(shí)例應(yīng)該獲得的分片數(shù)字返回出去。 方法簽名如下:
/*** 作業(yè)分片.* * @param jobInstances 所有參與分片的單元列表* @param jobName 作業(yè)名稱* @param shardingTotalCount 分片總數(shù)* @return 分片結(jié)果*/Map<JobInstance, List<Integer>> sharding(List<JobInstance> jobInstances, String jobName, int shardingTotalCount);分片函數(shù)的觸發(fā),只會(huì)在leader選舉的時(shí)候觸發(fā),也就是說(shuō)只會(huì)在剛啟動(dòng)和leader節(jié)點(diǎn)離開(kāi)的時(shí)候觸發(fā),并且是在leader節(jié)點(diǎn)上觸發(fā),而其他節(jié)點(diǎn)不會(huì)觸發(fā)。
?
1. 基于平均分配算法的分片策略
基于平均分配算法的分片策略對(duì)應(yīng)的類是:AverageAllocationJobShardingStrategy。它是默認(rèn)的分片策略。它的分片效果如下:
- 如果有3個(gè)Job實(shí)例, 分成9片, 則每個(gè)Job實(shí)例分到的分片是: 1=[0,1,2], 2=[3,4,5], 3=[6,7,8].
- 如果有3個(gè)Job實(shí)例, 分成8片, 則每個(gè)Job實(shí)例分到的分片是: 1=[0,1,6], 2=[2,3,7], 3=[4,5].
- 如果有3個(gè)Job實(shí)例, 分成10片, 則個(gè)Job實(shí)例分到的分片是: 1=[0,1,2,9], 2=[3,4,5], 3=[6,7,8].
?
2. 作業(yè)名的哈希值奇偶數(shù)決定IP升降序算法的分片策略
這個(gè)策略的對(duì)應(yīng)的類是:OdevitySortByNameJobShardingStrategy,它內(nèi)部其實(shí)也是使用AverageAllocationJobShardingStrategy實(shí)現(xiàn),只是在傳入的節(jié)點(diǎn)實(shí)例順序不一樣,也就是上面接口參數(shù)的List<JobInstance>。AverageAllocationJobShardingStrategy的缺點(diǎn)是一旦分片數(shù)小于Job實(shí)例數(shù),作業(yè)將永遠(yuǎn)分配至IP地址靠前的Job實(shí)例上,導(dǎo)致IP地址靠后的Job實(shí)例空閑。而OdevitySortByNameJobShardingStrategy則可以根據(jù)作業(yè)名稱重新分配Job實(shí)例負(fù)載。如:
- 如果有3個(gè)Job實(shí)例,分成2片,作業(yè)名稱的哈希值為奇數(shù),則每個(gè)Job實(shí)例分到的分片是:1=[0], 2=[1], 3=[]
- 如果有3個(gè)Job實(shí)例,分成2片,作業(yè)名稱的哈希值為偶數(shù),則每個(gè)Job實(shí)例分到的分片是:3=[0], 2=[1], 1=[]
實(shí)現(xiàn)比較簡(jiǎn)單:
long jobNameHash = jobName.hashCode(); if (0 == jobNameHash % 2) {Collections.reverse(jobInstances); } return averageAllocationJobShardingStrategy.sharding(jobInstances, jobName, shardingTotalCount);?
3. 根據(jù)作業(yè)名的哈希值對(duì)Job實(shí)例列表進(jìn)行輪轉(zhuǎn)的分片策略
這個(gè)策略的對(duì)應(yīng)的類是:RotateServerByNameJobShardingStrategy,和上面介紹的策略一樣,內(nèi)部同樣是用AverageAllocationJobShardingStrategy實(shí)現(xiàn),也是在傳入的List<JobInstance>列表順序上做文章。
?
4. 自定義分片策略
除了可以使用上述分片策略之外,elastic-job還允許自定義分片策略。我們可以自己實(shí)現(xiàn)JobShardingStrategy接口,并且配置到分片方法上去,整個(gè)過(guò)程比較簡(jiǎn)單,下面僅僅列出通過(guò)配置spring來(lái)切換自定義的分片算法的例子:
<job:simple id="MyShardingJob1" class="nick.test.elasticjob.MyShardingJob1" registry-center-ref="regCenter" cron="0/10 * * * * ?" sharding-total-count="5" sharding-item-parameters="0=A,1=B,2=C,3=D,4=E" job-sharding-strategy-class="nick.test.elasticjob.MyJobShardingStrategy"/>?
轉(zhuǎn)載于:https://www.cnblogs.com/haoxinyue/p/6919375.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的elastic-job详解(一):数据分片的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Docker 制作镜像-redis
- 下一篇: 使用Arthas 获取Spring Ap