定時(shí)同步數(shù)據(jù)的任務(wù)優(yōu)化

前言

定時(shí)任務(wù)在系統(tǒng)中并不少見喳张,主要目的是用于需要定時(shí)處理數(shù)據(jù)或者執(zhí)行某個(gè)操作的情況下,如定時(shí)關(guān)閉訂單美澳,或者定時(shí)備份销部。而常見的定時(shí)任務(wù)分為2種,第一種:固定時(shí)間執(zhí)行制跟,如:每分鐘執(zhí)行一次舅桩,每天執(zhí)行一次。第二種:延時(shí)多久執(zhí)行雨膨,就是當(dāng)發(fā)生一件事情后擂涛,根據(jù)這件時(shí)間發(fā)生的時(shí)間定時(shí)多久后執(zhí)行任務(wù),如:15分鐘后關(guān)閉訂單付款狀態(tài)聊记,24小時(shí)候后關(guān)閉訂單并且釋放庫(kù)存撒妈,而由于第二種一般都是單一數(shù)據(jù)的處理(主要是指數(shù)據(jù)量不大,一般情況下只有一個(gè)主體處理對(duì)象排监,如:一個(gè)訂單以及訂單中的N個(gè)商品)狰右,所以一般情況下第二種出現(xiàn)性能問題的幾率不大(不代表沒有),所以本文主要是針對(duì)第一種定時(shí)任務(wù)來進(jìn)行優(yōu)化舆床,而且主要是針對(duì)數(shù)據(jù)同步或者傳遞數(shù)據(jù)來進(jìn)行優(yōu)化棋蚌,而優(yōu)化的方式也是根據(jù)實(shí)際項(xiàng)目中的情況在不同階段進(jìn)行優(yōu)化的

第一階段

第一階段屬于原始階段,邏輯也最為簡(jiǎn)單挨队,由于同步分為數(shù)據(jù)同步和傳遞數(shù)據(jù)谷暮,而且2種的需求各不一致(主要是在于是否允許丟失),所以分開分析

第一種類型:傳遞數(shù)據(jù)

由于傳遞數(shù)據(jù)可以允許丟失盛垦,常見的場(chǎng)景如調(diào)用憑證推送(常見于接口需要暴露給第三方湿弦,為了安全性,可以定時(shí)推送調(diào)用憑證來保證接口安全性)情臭,消息推送(訂單消費(fèi)成功后推送消息省撑,由于可能推送失敗,所以需要進(jìn)入定時(shí)任務(wù)進(jìn)行重試俯在,但是因?yàn)橄?shí)時(shí)性,所以重試到一定次數(shù)后放棄重試)

傳遞數(shù)據(jù)在第一階段設(shè)計(jì)非常簡(jiǎn)單娃惯,定時(shí)推送跷乐,有限的錯(cuò)誤次數(shù),同步成功后修改狀態(tài)趾浅,同步失敗后對(duì)失敗次數(shù)+1愕提,一旦超過錯(cuò)誤次數(shù)馒稍,就不在繼續(xù)嘗試

第二種類型:同步數(shù)據(jù)

同步數(shù)據(jù)跟傳遞數(shù)據(jù)不同點(diǎn)在于同步數(shù)據(jù)一定需要保證數(shù)據(jù)能投遞成功,否則就要一直進(jìn)行重試浅侨,比如2個(gè)系統(tǒng)間的訂單同步纽谒,會(huì)員信息同步等

同步數(shù)據(jù)再第一階段也非常簡(jiǎn)單,定時(shí)同步數(shù)據(jù)如输,失敗就設(shè)置同步狀態(tài)為同步失敗鼓黔,每次同步就只查詢狀態(tài)為未同步和同步失敗記錄

第二階段

一開始需要傳遞或者同步的系統(tǒng)很少,數(shù)據(jù)也少不见,所以沒有什么問題澳化,但是第二階段不一樣了,數(shù)據(jù)量稍微有所新增稳吮,但是增量不大缎谷,主要是需要同步的系統(tǒng)多了,打個(gè)比方灶似,連鎖商店列林,總部需要把數(shù)據(jù)下傳到所有門店去,這樣門店就不用每次去總部獲取數(shù)據(jù)酪惭,這樣太耗費(fèi)時(shí)間了席纽,當(dāng)然門店每次從總部獲取到數(shù)據(jù)可以緩存到本地,不過跟本文內(nèi)容關(guān)系不大撞蚕,所以這里不再討論润梯。由于需要同步的系統(tǒng)太多,所以延伸出另外一個(gè)問題甥厦,一旦一個(gè)系統(tǒng)的網(wǎng)絡(luò)環(huán)境不好纺铭,會(huì)影響其他系統(tǒng)數(shù)據(jù)同步,所以在第二階段刀疙,引入了黑名單機(jī)制舶赔,由于黑名單機(jī)制對(duì)于傳遞數(shù)據(jù)和同步數(shù)據(jù)大致相同,所以這里就不分開描述谦秧,有差異性的地方也會(huì)指出

黑名單具體處理機(jī)制

黑名單分二級(jí):

第一級(jí)用于控制本次定時(shí)任務(wù)竟纳,當(dāng)本次運(yùn)行定時(shí)任務(wù)時(shí),不同的接受數(shù)據(jù)服務(wù)器可能有0-N條數(shù)據(jù)需要同步疚鲤,所以一旦進(jìn)入第一級(jí)黑名單后锥累,本次后面都不會(huì)向接受數(shù)據(jù)服務(wù)器發(fā)起請(qǐng)求,而是直接失敿桶略;

第二級(jí)用于控制多長(zhǎng)時(shí)間內(nèi)不進(jìn)入重試,是控制整個(gè)的,從查詢需要同步的數(shù)據(jù)時(shí)候就直接過濾并且設(shè)置為同步失敗狀態(tài)(傳遞消息需要對(duì)失敗次數(shù)加1)

首先第一級(jí)际歼,當(dāng)請(qǐng)求不到接受數(shù)據(jù)的服務(wù)器的時(shí)候(鏈接失敗惶翻,或者鏈接超時(shí)),會(huì)再重試2次(傳遞數(shù)據(jù)由于及時(shí)性要求鹅心,所以不會(huì)重試吕粗,并且超時(shí)時(shí)間也會(huì)合理的減少),如果2次都同步失敗旭愧,這判斷本條數(shù)據(jù)同步失敗颅筋,并且進(jìn)入第一級(jí)黑名單,并且判斷一定時(shí)間內(nèi)進(jìn)入了幾次第一級(jí)黑名單榕茧,具體使用redis控制垃沦,首先是否進(jìn)入第一級(jí)黑名單直接程序中存儲(chǔ)就好,一定時(shí)間段內(nèi)進(jìn)入了幾次黑名單用押,就使用有序集合保存肢簿,排序的分值就存儲(chǔ)當(dāng)前時(shí)間戳

進(jìn)入第一級(jí)黑名單后,使用一定時(shí)間內(nèi)進(jìn)入幾次的限制條件蜻拨,來判斷是否進(jìn)入第二級(jí)黑名單池充,比如5分鐘進(jìn)入3次第一級(jí)黑名單,就進(jìn)入第二級(jí)黑名單缎讼,那么就查詢分值大于5分鐘前時(shí)間戳的數(shù)據(jù)集合收夸,如果集合結(jié)果有3條或以上數(shù)據(jù)了,那么就進(jìn)入第二級(jí)黑名單血崭,同時(shí)清理掉redis中關(guān)于第一級(jí)黑名單存儲(chǔ)的數(shù)據(jù)卧惜,如果沒有3條數(shù)據(jù),那么就刪除分值小于5分鐘前的時(shí)間戳的數(shù)據(jù)夹纫,避免垃圾數(shù)據(jù)過多

使用黑名單機(jī)制咽瓷,可以有效避免一些因?yàn)榉?wù)本來不可訪問導(dǎo)致一直還重試的問題,并且由于有二級(jí)黑名單舰讹,所以也一定程度上避免了因?yàn)闀簳r(shí)網(wǎng)絡(luò)波動(dòng)茅姜,導(dǎo)致數(shù)據(jù)長(zhǎng)久無法同步的問題

第三階段

由于需要傳遞的數(shù)據(jù)和需要同步數(shù)據(jù)的服務(wù)越來越多,并且由于各種問題導(dǎo)致很多數(shù)據(jù)不能一次性同步成功月匣,所以每次定時(shí)任務(wù)都需要同步大量數(shù)據(jù)钻洒,這樣就導(dǎo)致及時(shí)性很差了,比如幾千條數(shù)據(jù)同步下來锄开,就算一條只需要幾十毫秒素标,從開始到最后一條數(shù)據(jù)同步成功也是幾十秒之后了,所以需要再次對(duì)定時(shí)任務(wù)進(jìn)行優(yōu)化院刁,數(shù)據(jù)量大而導(dǎo)致同步慢原因很簡(jiǎn)單糯钙,是由于單個(gè)線程串行同步的粪狼,也就是說必須要上一條數(shù)據(jù)處理了才能處理下一條數(shù)據(jù)退腥,所以可以使用多線程來優(yōu)化任岸,提高硬件使用率

多線程的定時(shí)任務(wù)

當(dāng)然肯定不可能給每條數(shù)據(jù)創(chuàng)建一個(gè)線程,先不說得創(chuàng)建多少條線程狡刘,僅僅是創(chuàng)建線程的消耗就已經(jīng)很大了享潜,而且線程數(shù)量太多,頻繁切換線程上下文也會(huì)導(dǎo)致性能損耗嗅蔬,所以最合適的就是將數(shù)據(jù)分配到機(jī)器CPU核心數(shù)量的線程剑按,或者核心數(shù)量*2的線程上去處理更合適,當(dāng)然具體情況具體分析澜术,最好還是具體測(cè)試得出合適的線程數(shù)量艺蝴,同時(shí)由于肯定是會(huì)存在多個(gè)定時(shí)任務(wù),所以可以多個(gè)定時(shí)任務(wù)使用同一個(gè)線程池鸟废,但是每個(gè)任務(wù)只使用合適線程數(shù)量來處理

線程數(shù)據(jù)分配原則

同一個(gè)被接受調(diào)用的數(shù)據(jù)的服務(wù)器的數(shù)據(jù)肯定是分配到一個(gè)線程中去處理猜敢,比如要分配8個(gè)線程來處理,那么可以創(chuàng)建8個(gè)集合盒延,先保存查詢出來需要被同步的數(shù)據(jù)缩擂,同時(shí)查詢出來的數(shù)據(jù)根據(jù)被接受數(shù)據(jù)的服務(wù)器標(biāo)識(shí)排序,用接受數(shù)據(jù)的服務(wù)器標(biāo)識(shí)的hash值來%8來確定放入哪個(gè)集合添寺,或者使用輪詢的方式放入指定集合胯盯,分配好之后則創(chuàng)建8個(gè)runable放入線程池中去執(zhí)行

防止定時(shí)任務(wù)疊加

開啟多線程處理后,由于主線程在把任務(wù)放入線程池中運(yùn)行的時(shí)候就會(huì)返回了计露,所以一定需要防止定時(shí)任務(wù)疊加博脑,比如任務(wù)是10秒執(zhí)行一次的,每次定時(shí)任務(wù)本身的線程只執(zhí)行了1秒票罐,下次定時(shí)任務(wù)的時(shí)候會(huì)發(fā)現(xiàn)定時(shí)任務(wù)已經(jīng)處理完成叉趣,但是實(shí)際上真正同步數(shù)據(jù)的8個(gè)線程都沒有執(zhí)行完成,就會(huì)出現(xiàn)一條數(shù)據(jù)重復(fù)同步胶坠,或者把數(shù)據(jù)累加到上次任務(wù)的集合中去(看具體的處理方式導(dǎo)致不同的結(jié)果)君账,最后就跟滾雪球一樣,整個(gè)服務(wù)就算不崩潰沈善,也會(huì)出現(xiàn)各種問題乡数,或者就是浪費(fèi)大量資源去做重復(fù)同步,所以為了防止任務(wù)疊加闻牡,需要使用閉鎖來防止定時(shí)任務(wù)本身返回的情況净赴,同時(shí)使用閉鎖也要注意處理異常的情況,防止發(fā)生異常后罩润,閉鎖沒有執(zhí)行操作玖翅,導(dǎo)致定時(shí)任務(wù)一直不能返回

閉鎖

使用閉鎖防止定時(shí)任務(wù)返回,8個(gè)線程的情況下創(chuàng)建閉鎖

CountDownLatch latch = new CountDownLatch(8);

每個(gè)線程執(zhí)行完數(shù)據(jù)后需要countDown方法來通知,或者叫關(guān)閉一個(gè)柵欄吧金度,創(chuàng)建閉鎖的傳入的8我們可以看成創(chuàng)建了8個(gè)柵欄

latch.countDown();

同時(shí)在定時(shí)任務(wù)的線程中应媚,需要等待所有柵欄關(guān)閉才能繼續(xù)執(zhí)行,所以需要調(diào)用方法

latch.await();

這樣只有所有線程執(zhí)行完成后猜极,定時(shí)任務(wù)的線程才會(huì)繼續(xù)執(zhí)行中姜,防止任務(wù)疊加

==使用多線程了,一定要注意多線程的一些線程安全以及其他的一些問題==跟伏,如果對(duì)閉鎖和多線程本身不夠了解的話丢胚,可以自行去查閱一些相關(guān)資料

第四階段

數(shù)據(jù)量非常大,接受數(shù)據(jù)的服務(wù)也非常多

一臺(tái)服務(wù)器的硬件資源始終有限受扳,尤其是網(wǎng)絡(luò)資源携龟,由于接受數(shù)據(jù)的服務(wù)不一定是內(nèi)網(wǎng)服務(wù),加上各種問題導(dǎo)致鏈接失敗勘高,所以數(shù)據(jù)量大的情況下峡蟋,就算使用了多線程,還是會(huì)造成數(shù)據(jù)延遲很久才同步成功(主要延遲原因是網(wǎng)絡(luò)問題)相满,這時(shí)候就需要使用多臺(tái)服務(wù)器了层亿,而使用多臺(tái)服務(wù)器定時(shí)執(zhí)行就存在一個(gè)問題,數(shù)據(jù)分片立美,簡(jiǎn)單來說怎么保證一條數(shù)據(jù)只能被一臺(tái)服務(wù)器處理匿又,數(shù)據(jù)分片有2種方式,第一種:不同服務(wù)器處理不同的表的數(shù)據(jù)建蹄。第二種:數(shù)據(jù)本身主鍵或者某種標(biāo)志分配處理

2種處理方式有各自的優(yōu)缺點(diǎn)

第一種:

優(yōu)點(diǎn):簡(jiǎn)單碌更,只需要簡(jiǎn)單拆分或者配置即可

缺點(diǎn):無法擴(kuò)展更多,最多只能可能擴(kuò)展到數(shù)據(jù)表數(shù)量臺(tái)服務(wù)器洞慎,并且對(duì)于熱點(diǎn)數(shù)據(jù)無法更優(yōu)處理痛单,比如訂單這些熱點(diǎn)數(shù)據(jù),始終都在一臺(tái)服務(wù)器

第二種:

優(yōu)點(diǎn):理論上可無限擴(kuò)展劲腿,可以針對(duì)熱點(diǎn)數(shù)據(jù)專門擴(kuò)展

缺點(diǎn):配置麻煩旭绒,每次新增服務(wù)器需要重新配置

實(shí)現(xiàn)分片定時(shí)任務(wù)

由于第一種配置簡(jiǎn)單,而且擴(kuò)展性不強(qiáng)焦人,所以本文主要講述第二種方式的實(shí)現(xiàn)挥吵;

如果所有數(shù)據(jù)有生成都有自增型主鍵id,那么最簡(jiǎn)單也最公平的就是給每臺(tái)服務(wù)器配置一個(gè)從0開始連續(xù)的服務(wù)器id花椭,每臺(tái)服務(wù)器查詢數(shù)據(jù)的時(shí)候加一個(gè)條件id%服務(wù)器臺(tái)數(shù)=當(dāng)前服務(wù)器id忽匈,注意這樣會(huì)導(dǎo)致id列的索引可能無法命中(根據(jù)數(shù)據(jù)庫(kù)不同,是否命中情況不一致)矿辽,這樣配置的好處就是絕對(duì)公平丹允,每臺(tái)服務(wù)器分配到的數(shù)據(jù)量是平等的郭厌,壞處就是一臺(tái)服務(wù)器可能會(huì)給所有接受數(shù)據(jù)服務(wù)發(fā)起請(qǐng)求,無法更好的利用鏈接復(fù)用雕蔽,另外也無法針對(duì)服務(wù)器配置來增加或者降低權(quán)重(當(dāng)然可以一個(gè)服務(wù)器配置2個(gè)id的方式來實(shí)現(xiàn)折柠,但是這樣也不友好)

如果為了更好的利用鏈接復(fù)用,可以使用先計(jì)算出接受數(shù)據(jù)服務(wù)標(biāo)志的hashcode值萎羔,然后跟進(jìn)hashcode值%服務(wù)器臺(tái)數(shù)=當(dāng)前服務(wù)器id的形式液走,這樣就可以將接受數(shù)據(jù)服務(wù)分組式的配置到某個(gè)服務(wù)器上去處理碳默,當(dāng)然如果接受數(shù)據(jù)服務(wù)本身存在很大的數(shù)據(jù)量差異贾陷,就不推薦這種方式了,畢竟這樣容易把大量數(shù)據(jù)堆積到某臺(tái)服務(wù)器上去處理

當(dāng)然還有其他多種分片的配置方式嘱根,比如采用表配置的方式來配置哪臺(tái)服務(wù)器處理哪些數(shù)據(jù)髓废,也可以使用上面種方式的結(jié)合體,可以根據(jù)具體情況分析到底怎么樣才能更適合的進(jìn)行數(shù)據(jù)分片處理该抒,當(dāng)然常規(guī)情況下慌洪,采用id%服務(wù)器的臺(tái)數(shù)是能滿足大部分需求的

其他優(yōu)化

當(dāng)系統(tǒng)針對(duì)性能優(yōu)化到一定程度的時(shí)候,就可以考慮從業(yè)務(wù)或者其他方面進(jìn)行優(yōu)化了凑保,比如一旦有系統(tǒng)進(jìn)入二級(jí)黑名單了冈爹,就發(fā)出警告通知,或者沒有進(jìn)入二級(jí)黑名單欧引,但是卻經(jīng)常進(jìn)入一級(jí)黑名單频伤,也提出一個(gè)報(bào)警,這樣可以讓人去排查原因芝此,確認(rèn)是程序問題還是網(wǎng)絡(luò)本身的問題憋肖。另外也可以設(shè)置一個(gè)閾值,某個(gè)接受數(shù)據(jù)的服務(wù)一直響應(yīng)很慢婚苹,或者經(jīng)常響應(yīng)時(shí)間超過某個(gè)閾值的時(shí)候岸更,可以考慮進(jìn)行降權(quán)處理,或者排查程序已經(jīng)網(wǎng)絡(luò)相關(guān)的原因

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膊升,一起剝皮案震驚了整個(gè)濱河市怎炊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廓译,老刑警劉巖评肆,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異责循,居然都是意外死亡糟港,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門院仿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秸抚,“玉大人速和,你說我怎么就攤上這事“溃” “怎么了颠放?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吭敢。 經(jīng)常有香客問我碰凶,道長(zhǎng),這世上最難降的妖魔是什么鹿驼? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任欲低,我火速辦了婚禮,結(jié)果婚禮上畜晰,老公的妹妹穿的比我還像新娘砾莱。我一直安慰自己,他們只是感情好凄鼻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布腊瑟。 她就那樣靜靜地躺著,像睡著了一般块蚌。 火紅的嫁衣襯著肌膚如雪闰非。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天峭范,我揣著相機(jī)與錄音财松,去河邊找鬼。 笑死虎敦,一個(gè)胖子當(dāng)著我的面吹牛游岳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播其徙,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胚迫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了唾那?” 一聲冷哼從身側(cè)響起访锻,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闹获,沒想到半個(gè)月后期犬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡避诽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年龟虎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡澈蟆,死狀恐怖构蹬,靈堂內(nèi)的尸體忽然破棺而出秕狰,到底是詐尸還是另有隱情,我是刑警寧澤气破,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布寂嘉,位于F島的核電站遏暴,受9級(jí)特大地震影響贡耽,放射性物質(zhì)發(fā)生泄漏衷模。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一蒲赂、第九天 我趴在偏房一處隱蔽的房頂上張望阱冶。 院中可真熱鬧,春花似錦凳宙、人聲如沸熙揍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至有梆,卻和暖如春是尖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泥耀。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工饺汹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痰催。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓兜辞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親夸溶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逸吵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容