本發(fā)明涉及信息技術(shù)領(lǐng)域,具體涉及一種面向?qū)崟r(shí)流計(jì)算的動(dòng)態(tài)逐級(jí)反壓方法。
背景技術(shù):
從社交網(wǎng)絡(luò)資訊(以提供熱門話題或?qū)崟r(shí)搜索)到廣告處理數(shù)據(jù)引擎,實(shí)時(shí)流計(jì)算在當(dāng)今工業(yè)中被廣泛地使用,如apahestorm,twitter’sheron,apacheflink,sparkstreaming,samza等。在這些系統(tǒng)中,數(shù)據(jù)的產(chǎn)生完全由數(shù)據(jù)源確定,數(shù)據(jù)源的動(dòng)態(tài)變化及狀態(tài)不統(tǒng)一導(dǎo)致數(shù)據(jù)流的速率呈現(xiàn)出了突發(fā)性的特征,而數(shù)據(jù)流的突發(fā)性特征常常導(dǎo)致過載的發(fā)生,發(fā)生過載還有以下幾個(gè)原因:網(wǎng)絡(luò)擁塞,資源利用率高,干擾,異質(zhì)性,io高頻阻塞等。因此,在實(shí)時(shí)流計(jì)算中,過載是常見且難以避免的。
實(shí)時(shí)流計(jì)算已被許多知名企業(yè)應(yīng)用于大數(shù)據(jù)計(jì)算領(lǐng)域,如淘寶實(shí)時(shí)分析、阿里云galaxy實(shí)時(shí)計(jì)算、攜程網(wǎng)站性能監(jiān)控等。對(duì)于實(shí)時(shí)性系統(tǒng),系統(tǒng)的響應(yīng)性和穩(wěn)定性是關(guān)注的重點(diǎn)。響應(yīng)意味著降低處理數(shù)據(jù)的延遲,即數(shù)據(jù)計(jì)算延遲,例如,數(shù)據(jù)從它輸入至系統(tǒng)中到其結(jié)果反映給用戶所經(jīng)過的時(shí)間;穩(wěn)定性意味著系統(tǒng)能夠穩(wěn)定持久地在集群中運(yùn)行。而過載的發(fā)生極易導(dǎo)致系統(tǒng)整體的數(shù)據(jù)計(jì)算延遲增加和不穩(wěn)定甚至不可用。
對(duì)于流計(jì)算而言,數(shù)據(jù)流是不可控的:數(shù)據(jù)到達(dá)時(shí)機(jī)不可控、數(shù)據(jù)質(zhì)量不可控、上游數(shù)據(jù)流量不可控。以阿里巴巴集團(tuán)2016年11月11交易情況為例,當(dāng)天成交額達(dá)178億美元,阿里云于最高峰時(shí)每秒處理17.5萬筆交易,支付寶于最高峰時(shí)每秒處理12萬筆,這個(gè)交易額是平時(shí)的數(shù)十萬倍,這就要求系統(tǒng)能夠動(dòng)態(tài)適應(yīng)不確定的數(shù)據(jù)流,具有大數(shù)據(jù)流量動(dòng)態(tài)匹配的能力。而現(xiàn)有的大部分實(shí)時(shí)流計(jì)算系統(tǒng)缺大數(shù)據(jù)流量動(dòng)態(tài)匹配的能力,如apachestorm,sparkstreaming等。在實(shí)時(shí)流計(jì)算系統(tǒng)中,計(jì)算結(jié)構(gòu)是一個(gè)有向無環(huán)圖(dag),稱為拓?fù)?topology),拓?fù)溆蓴?shù)據(jù)流(steam),數(shù)據(jù)流的生成者組件(spout)和運(yùn)算組件(bolt)組成。task是拓?fù)渲衧pout或bolt在運(yùn)行時(shí)的實(shí)例。拓?fù)渲械臄?shù)據(jù)通常由上游發(fā)送組件主動(dòng)推送給下游接收組件,上游組件在推送數(shù)據(jù)時(shí)不會(huì)考慮下游組件的負(fù)載情況、工作狀態(tài)等因素,如果下游組件因過載無法處理數(shù)據(jù),實(shí)時(shí)流計(jì)算系統(tǒng)一般采用快速失敗(fail-fast)策略——如果接收組件不能處理傳入的數(shù)據(jù),系統(tǒng)將其丟棄。如果系統(tǒng)沒有實(shí)現(xiàn)數(shù)據(jù)的容錯(cuò),那么這個(gè)fail-fast將會(huì)導(dǎo)致無限制的數(shù)據(jù)被丟棄,即使系統(tǒng)實(shí)現(xiàn)了數(shù)據(jù)的容錯(cuò),也只是簡單地將丟失的數(shù)據(jù)重新發(fā)送,沒有動(dòng)態(tài)匹配的能力。這樣的設(shè)計(jì)會(huì)導(dǎo)致topology在消耗所有集群資源的情況下拓?fù)淙蝿?wù)沒有任何進(jìn)度。
mitzenmacherm提出的方法是通過讓輸入的數(shù)據(jù)隨機(jī)選擇下游的兩個(gè)最小負(fù)載的服務(wù)器節(jié)點(diǎn)來減少延遲。但是,這種技術(shù)本質(zhì)上依賴輸入的數(shù)據(jù)獲取所有服務(wù)器節(jié)點(diǎn)的最新負(fù)載信息,而在快速移動(dòng)的以毫秒為單位進(jìn)行的流處理系統(tǒng)中,持續(xù)地監(jiān)控服務(wù)器節(jié)點(diǎn)負(fù)載會(huì)嚴(yán)重加劇系統(tǒng)負(fù)荷,這使得這種方式難以真正實(shí)現(xiàn)。twitter的heron是2016年提出的實(shí)時(shí)流計(jì)算系統(tǒng),實(shí)現(xiàn)的方法是直接遏制源頭的反壓策略,但這種方法可能不是最優(yōu)的,因?yàn)榭赡軆H僅只需要遏制上游的發(fā)送速度,而直接遏制源頭的策略會(huì)導(dǎo)致整體topology延遲取決于運(yùn)行最慢的組件。
技術(shù)實(shí)現(xiàn)要素:
為了克服現(xiàn)有的實(shí)時(shí)流計(jì)算方法的拓?fù)渲袉蝹€(gè)任務(wù)影響整體延遲、反壓過程不平滑、系統(tǒng)容易出現(xiàn)負(fù)載振蕩的不足,本發(fā)明提出了一種減少拓?fù)渲袉蝹€(gè)任務(wù)對(duì)整體延遲的影響、反壓過程平滑、系統(tǒng)不會(huì)出現(xiàn)負(fù)載振蕩的面向?qū)崟r(shí)流計(jì)算的動(dòng)態(tài)逐級(jí)反壓方法,此方法根據(jù)任務(wù)(task)節(jié)點(diǎn)的當(dāng)前自身負(fù)載情況來調(diào)整上游向其發(fā)送數(shù)據(jù)的速率。
為了解決上述技術(shù)問題本發(fā)明提供如下的技術(shù)方案:
一種面向?qū)崟r(shí)流計(jì)算的動(dòng)態(tài)逐級(jí)反壓方法,包括以下步驟:
步驟(1)遍歷當(dāng)前需要進(jìn)行反壓的任務(wù)task集合ti;
步驟(2)若ti為空,則結(jié)束,否則ti取出下一個(gè)taski并將其從ti中移除;
步驟(3)判斷taski是否處于過載,若是進(jìn)行步驟(4),否則進(jìn)行步驟(9);
步驟(4)獲取taski的上游節(jié)點(diǎn)集合u;
步驟(5)判斷u是否為空,若為空則返回步驟(2),否則u取出下一個(gè)ui并將其從u中移除,并進(jìn)行步驟(6);
步驟(6)判斷ui節(jié)點(diǎn)是否正在進(jìn)行反壓,若是返回步驟(5),否則進(jìn)行步驟(7)~(8);
步驟(7)ui節(jié)點(diǎn)的發(fā)射速度降為當(dāng)前的v’,v’為系統(tǒng)預(yù)設(shè)的反壓梯值。若ui是第一次反壓,則記錄ui的初始速度originv,并保存到ui本地;
步驟(8)ui節(jié)點(diǎn)將自身反壓狀態(tài)設(shè)置為true,返回步驟(5);
步驟(9)判斷taski是否負(fù)載過輕且持續(xù)sentivity,若是則進(jìn)行步驟(10),否則進(jìn)行步驟(2),sentivity為系統(tǒng)預(yù)設(shè)的敏感度值;
步驟(10)獲取taski的上游節(jié)點(diǎn)集合u;
步驟(11)若u為空,返回步驟(2),否則u取出下一個(gè)節(jié)點(diǎn)ui并將其從u中移除;
步驟(12)判斷ui節(jié)點(diǎn)是否處于反壓狀態(tài),若反壓狀態(tài)為true,則進(jìn)行步驟(13),否則返回步驟(11);
步驟(13)ui節(jié)點(diǎn)的發(fā)射速度降為當(dāng)前的1/v’;
步驟(14)判斷ui是否恢復(fù)到最初始的速度originv,若是則進(jìn)行步驟(15),否則進(jìn)行步驟(11);
步驟(15)ui節(jié)點(diǎn)將自身反壓狀態(tài)設(shè)置為false,返回步驟(11)。
本發(fā)明的有益效果是,當(dāng)某一task過載導(dǎo)致延遲增加,上游的bolt會(huì)減緩向下游發(fā)射的速率,更多的資源會(huì)被用來處理當(dāng)前的正在處理的數(shù)據(jù)上,避免因阻塞、數(shù)據(jù)超時(shí)、重發(fā)等導(dǎo)致的延遲增加。當(dāng)task的負(fù)載降低至最小閾值且持續(xù)sensitivity秒,task會(huì)向上游發(fā)送取消反壓信號(hào),上游task收到取消反壓信號(hào)后首先會(huì)檢查自身是否處于反壓狀態(tài),若是則會(huì)恢復(fù)上一次的發(fā)射速度(當(dāng)前速度的1/v’),只有當(dāng)組件恢復(fù)至初試速度時(shí)才會(huì)消除反壓狀態(tài)。迭代地進(jìn)行反壓/取消反壓和使用定時(shí)器的原因都是為了抑制反壓導(dǎo)致的負(fù)載振蕩。該方法的主要優(yōu)點(diǎn)是:1)無需設(shè)置額外的監(jiān)控節(jié)點(diǎn);2)當(dāng)前組件只負(fù)責(zé)向直接上游反壓,減少了拓?fù)渲袉蝹€(gè)任務(wù)對(duì)整體延遲的影響;3)反壓過程平滑,系統(tǒng)不會(huì)出現(xiàn)負(fù)載振蕩。
附圖說明
圖1是本發(fā)明實(shí)施例中拓?fù)淙蝿?wù)(task)組件示意圖。
圖2是本發(fā)明實(shí)施例中zookeeper消息隊(duì)列示意圖。
圖3是本發(fā)明實(shí)施例中任務(wù)(task)通信模型示意圖。
圖4是本發(fā)明實(shí)施例中動(dòng)態(tài)逐級(jí)反壓流程示意圖。
圖5是本發(fā)明實(shí)施例中動(dòng)態(tài)逐級(jí)反壓結(jié)構(gòu)示意圖。
具體實(shí)施方式
為使本發(fā)明的上述特征和過程更加明顯易懂,下文特舉實(shí)施例,并配合附圖作詳細(xì)說明如下。
圖1為本發(fā)明實(shí)施例中拓?fù)淙蝿?wù)(task)組件示意圖。如圖1所示,拓?fù)渲械拿總€(gè)當(dāng)前組件c(spout或者bolt),在輸入數(shù)據(jù)流i后,觸發(fā)相關(guān)的操作fv,產(chǎn)生新的數(shù)據(jù)流t發(fā)送給下游組件,并根據(jù)自身反壓信號(hào)將狀態(tài)從s改變到s’(若狀態(tài)不變,則s=s’),用公式表示即為(s’,t)=fv(s,i)。
本實(shí)施例中task之間通信的消息隊(duì)列通過zookeeper實(shí)現(xiàn),圖2是本發(fā)明實(shí)施例中zookeeper消息隊(duì)列。如圖2所示,該消息隊(duì)列提供了異步通信協(xié)議的先入先出(fifo)隊(duì)列,消息的發(fā)送者subject和接收者observer不需要同時(shí)與消息隊(duì)列交互,subject的put操作用于向隊(duì)列插入元素,observer的get操作用于從隊(duì)列取出元素。圖中1~6的方塊表示數(shù)據(jù)的插入順序,先插入的數(shù)據(jù)(數(shù)字小)會(huì)首先被get操作取出。
基于task通信消息隊(duì)列,實(shí)現(xiàn)了task之間的通信模型。圖3是本發(fā)明實(shí)施例中任務(wù)(task)通信模型示意圖,如圖3所示,當(dāng)taski與其上游ui進(jìn)行通信時(shí),其流程如下:
(1)taski將反壓信號(hào)發(fā)送到send-queue隊(duì)列;
(2)znode-create-handler線程訂閱到send-queue消費(fèi)消息,根據(jù)消息內(nèi)容在zookeeper的/taskmessage目錄下創(chuàng)建節(jié)點(diǎn);
(3)znode-delete-handler線程監(jiān)聽/taskmessage目錄,并負(fù)責(zé)消費(fèi)目錄下的消息并將消息發(fā)送至trigger-queue,每消費(fèi)一個(gè)節(jié)點(diǎn)后將其刪除;
(4)ui訂閱到trigger-queue消費(fèi)消息,根據(jù)消息內(nèi)容作相關(guān)操作,如反壓等;
(5)receive-thread負(fù)責(zé)接收ui的狀態(tài)信息并更新至zookeeper的/taskstate目錄;
(6)所有的task均監(jiān)聽/taskstate目錄,當(dāng)目錄有變化時(shí),相應(yīng)的task會(huì)收到通知并作相關(guān)操作。
反壓實(shí)質(zhì)上是當(dāng)下游組件處理不過來時(shí)促使上游組件盡量減緩消息的傳入,使得整個(gè)topology不會(huì)出現(xiàn)因消息阻塞而導(dǎo)致數(shù)據(jù)丟失和topology過載或不穩(wěn)定的機(jī)制。運(yùn)算組件bolt在收到上游的一個(gè)數(shù)據(jù)時(shí)會(huì)調(diào)用相關(guān)的計(jì)算方法,在該方法中嵌入基于流量動(dòng)態(tài)逐級(jí)反壓方法,靈敏度時(shí)間參數(shù)sensitivity,即至少經(jīng)過sensitivity毫秒調(diào)用一次動(dòng)態(tài)逐級(jí)反壓方法。tasks之間的反壓信號(hào)通過zookeeper消息隊(duì)列通信,這種異步方式可能會(huì)導(dǎo)致下游task的統(tǒng)計(jì)信息與上游task統(tǒng)計(jì)信息有輕微不一致的情況,但是這種不一致性不影響正確性。
圖4是本發(fā)明實(shí)施例中動(dòng)態(tài)逐級(jí)反壓流程示意圖,不同的bolt會(huì)根據(jù)自身流量獨(dú)立進(jìn)行反壓調(diào)整。如圖4所示,結(jié)合圖3,動(dòng)態(tài)逐級(jí)反壓方法詳細(xì)步驟如下:
步驟(1)遍歷當(dāng)前需要進(jìn)行反壓的task集合ti。
步驟(2)若ti為空,則結(jié)束,否則ti取出下一個(gè)taski并將其從ti中移除;
步驟(3)判斷taski的緩存隊(duì)列是否到達(dá)最大閾值,最大閾值設(shè)置為50m,若是則判定該taski處于過載狀態(tài),進(jìn)行步驟(4),否則進(jìn)行步驟(9);
步驟(4)獲取taski的上游節(jié)點(diǎn)集合u;
步驟(5)若u為空,返回步驟(2),否則u取出下一個(gè)節(jié)點(diǎn)ui并將其從u中移除;
步驟(6)判斷ui節(jié)點(diǎn)是否正在進(jìn)行反壓,若沒有正在進(jìn)行反壓,則進(jìn)行步驟(7)~(8),若正在進(jìn)行反壓,則進(jìn)行步驟(5);
步驟(7)ui節(jié)點(diǎn)的發(fā)射速度降為當(dāng)前的v’,v’為系統(tǒng)預(yù)設(shè)的反壓梯值。若ui是第一次反壓,則記錄ui的初始速度originv,并保存到ui本地,過程如下:
7.1)將反壓信號(hào)和ui的taskid發(fā)送到send-queue隊(duì)列,taskid是節(jié)點(diǎn)的唯一標(biāo)識(shí);
7.2)znode-create-handler線程獲得send-queue的反壓信號(hào)和taskid,根據(jù)消息內(nèi)容在zookeeper的/taskmessage目錄下創(chuàng)建文件節(jié)點(diǎn);
7.3)znode-delete-handler線程監(jiān)聽/taskmessage目錄的文件節(jié)點(diǎn),從文件節(jié)點(diǎn)內(nèi)容讀取反壓信號(hào)和taskis并發(fā)送到trigger-queue隊(duì)列,然后將該文件節(jié)點(diǎn)刪除;
7.4)ui訂閱到trigger-queue,獲取并刪除與自身taskid相同的反壓信號(hào);
7.5)ui節(jié)點(diǎn)的發(fā)射速度降為當(dāng)前的v’,v’為系統(tǒng)預(yù)設(shè)的反壓梯值。若是ui第一次反壓,則記錄ui的初始速度originv,并保存到ui本地;
步驟(8)ui節(jié)點(diǎn)將自身反壓狀態(tài)設(shè)置為true,返回步驟(5);
步驟(9)判斷taski的緩存隊(duì)列是否到達(dá)最低閾值且持續(xù)sentivity,最低閾值設(shè)置為500kb。sentivity為系統(tǒng)預(yù)設(shè)的敏感度值,設(shè)置為2000毫秒。若是則表示負(fù)載過輕,進(jìn)行步驟(10),否則返回步驟(2);
步驟(10)獲取taski的上游節(jié)點(diǎn)集合u;
步驟(11)若u為空,返回步驟(2),否則u取出下一個(gè)節(jié)點(diǎn)ui并將其從u中移除;
步驟(12)判斷ui節(jié)點(diǎn)是否處于反壓狀態(tài),若反壓狀態(tài)為true,則進(jìn)行步驟(13),否則返回步驟(11)
步驟(13)ui節(jié)點(diǎn)的發(fā)射速度降為當(dāng)前的1/v’,過程如下:
13.1)將取消反壓信號(hào)和ui的taskid發(fā)送到send-queue隊(duì)列;
13.1)znode-create-handler線程獲得send-queue的取消反壓信號(hào)和taskid,根據(jù)消息內(nèi)容在zookeeper的/taskmessage目錄下創(chuàng)建文件節(jié)點(diǎn);
13.2)znode-delete-handler線程監(jiān)聽/taskmessage目錄的文件節(jié)點(diǎn),從文件節(jié)點(diǎn)內(nèi)容讀取反壓信號(hào)和taskis并發(fā)送到trigger-queue隊(duì)列,然后將該文件節(jié)點(diǎn)刪除;
13.3)ui訂閱到trigger-queue,獲取并刪除與自身taskid相同的取消反壓信號(hào);
13.4)ui節(jié)點(diǎn)的發(fā)射速度降為當(dāng)前的1/v’;
步驟(14)判斷ui是否恢復(fù)到最初始的速度originv,若是則進(jìn)行步驟(15),否則返回步驟(11);
步驟(15)ui節(jié)點(diǎn)將自身反壓狀態(tài)設(shè)置為false,返回步驟(11)。
以上步驟的效果是,當(dāng)某一task過載時(shí),上游的節(jié)點(diǎn)會(huì)減緩向下游發(fā)射的速率,更多的資源會(huì)被用來處理當(dāng)前的正在處理的數(shù)據(jù)上,避免因阻塞、數(shù)據(jù)超時(shí)、重發(fā)等導(dǎo)致的延遲增加。當(dāng)task的負(fù)載降低至最小閾值且持續(xù)sensitivity毫秒,task會(huì)向上游發(fā)送取消反壓信號(hào),上游task收到取消反壓信號(hào)后首先會(huì)檢查自身是否處于反壓狀態(tài),若是則會(huì)恢復(fù)上一次的發(fā)射速度(當(dāng)前速度的1/v’),只有當(dāng)組件恢復(fù)至初試速度時(shí)才會(huì)消除反壓狀態(tài)。迭代地進(jìn)行反壓/取消反壓和使用定時(shí)器的原因都是為了抑制反壓導(dǎo)致的負(fù)載振蕩。
圖5是本發(fā)明實(shí)施例中動(dòng)態(tài)逐級(jí)反壓結(jié)構(gòu)示意圖。如圖5所示,當(dāng)所有節(jié)點(diǎn)通過state保存節(jié)點(diǎn)狀態(tài)信息,通過trigger觸發(fā)相關(guān)操作。因此,從整體結(jié)構(gòu)上觀察,反壓步驟如下:
步驟(1)節(jié)點(diǎn)spout/bolt向下游發(fā)送一個(gè)數(shù)據(jù)(tuple);
步驟(2)下游節(jié)點(diǎn)的當(dāng)前節(jié)點(diǎn)處于過載狀態(tài);
步驟(3)當(dāng)前節(jié)點(diǎn)trigger觸發(fā)反壓,通過zookeeper向上游傳遞反壓信號(hào);
步驟(4)zookeeper接收反并持久化反壓信號(hào)。
步驟(5)backpressure-cordinator-handler監(jiān)聽到zookeeper的反壓信號(hào)后獲取并刪除該信號(hào),同時(shí)向節(jié)點(diǎn)發(fā)送反壓。
步驟(6)收到反壓信號(hào)的節(jié)點(diǎn)的trigger被觸發(fā),調(diào)整發(fā)射數(shù)據(jù)的速率后修改state狀態(tài)。