日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分布式计算框架Gearman原理详解

發(fā)布時(shí)間:2024/2/28 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式计算框架Gearman原理详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是Gearman?

Gearman提供了一個(gè)通用的應(yīng)用程序框架,用于將工作轉(zhuǎn)移到更適合于工作的其他機(jī)器或流程。它允許你并行工作,負(fù)載平衡處理,并在語言間調(diào)用函數(shù)。它可用于從高可用性網(wǎng)站到傳輸數(shù)據(jù)庫復(fù)制事件的各種應(yīng)用程序。換句話說,它是分布式處理交流的神經(jīng)系統(tǒng)。關(guān)于Gearman的一些優(yōu)點(diǎn):

  • 開源它是免費(fèi)的!(在這個(gè)詞的兩個(gè)意思中)Gearman有一個(gè)活躍的開源社區(qū),如果你需要幫助或者想貢獻(xiàn),很容易參與進(jìn)來。擔(dān)心授權(quán)?Gearman是BSD。
  • 多語言?- 有一些語言的接口,這個(gè)列表正在增長。您也可以選擇使用一種語言提交工作的客戶端編寫異構(gòu)應(yīng)用程序,并在另一種語言中執(zhí)行該工作的工作人員。
  • 靈活?- 您不受限于任何特定的設(shè)計(jì)模式。您可以使用您選擇的任何模型快速組合分布式應(yīng)用程序,這些選項(xiàng)之一是Map / Reduce。
  • 快速?- Gearman有一個(gè)簡單的協(xié)議和接口,用C / C ++編寫的優(yōu)化的,線程化的服務(wù)器可以最大限度地減少應(yīng)用程序開銷。
  • 嵌入式?- 由于Gearman速度快,重量輕,適用于各種尺寸的應(yīng)用。以最小的開銷引入現(xiàn)有的應(yīng)用程序也很容易。
  • 沒有單點(diǎn)故障?- Gearman不僅可以幫助擴(kuò)展系統(tǒng),而且還可以通過容錯(cuò)方式實(shí)現(xiàn)。
  • 消息大小沒有限制?- Gearman支持最多4gig的單個(gè)消息。需要做更大的事情?沒問題Gearman可以大塊消息。
  • 擔(dān)心縮放??- 不要擔(dān)心Gearman。克雷格的名單,Tumblr,Yelp,Etsy,...發(fā)現(xiàn)別人已經(jīng)知道了多年。

內(nèi)容正在定期更新,所以請(qǐng)經(jīng)常查看。?如果您想了解更多信息或參與其中,您可能還想查看其他溝通形式!

Gearman如何工作?

一個(gè)Gearman驅(qū)動(dòng)的應(yīng)用程序由三部分組成:一個(gè)客戶端,一個(gè)工作者和一個(gè)作業(yè)服務(wù)器。客戶端負(fù)責(zé)創(chuàng)建要運(yùn)行的作業(yè)并將其發(fā)送到作業(yè)服務(wù)器。作業(yè)服務(wù)器將找到可以運(yùn)行作業(yè)并轉(zhuǎn)發(fā)作業(yè)的合適工作人員。工作人員執(zhí)行客戶端請(qǐng)求的工作,并通過作業(yè)服務(wù)器向客戶端發(fā)送響應(yīng)。Gearman提供您的應(yīng)用程序調(diào)用的客戶端和工作者API來與Gearman作業(yè)服務(wù)器(也稱為gearmand)交談,因此您不需要處理網(wǎng)絡(luò)或作業(yè)的映射。在內(nèi)部,gearman客戶端和工作者API使用TCP套接字與作業(yè)服務(wù)器進(jìn)行通信。為了更詳細(xì)地解釋Gearman的工作原理,我們來看看一個(gè)簡單的應(yīng)用程序,它將顛倒字符串中字符的順序。這個(gè)例子在PHP中給出,

我們首先編寫一個(gè)客戶端應(yīng)用程序,負(fù)責(zé)發(fā)送作業(yè)并等待結(jié)果,以便打印出來。它通過使用Gearman客戶端API來發(fā)送一些與函數(shù)名相關(guān)的數(shù)據(jù),在這種情況下是函數(shù)reverse。這個(gè)代碼是(為了簡潔,省略了錯(cuò)誤處理):

<?php // Reverse Client Code $client = new GearmanClient(); $client->addServer(); print $client->do("reverse", "Hello World!");

此代碼初始化一個(gè)客戶端類,將其配置為使用帶有add_server(不帶參數(shù)表示使用127.0.0.1默認(rèn)端口)的作業(yè)服務(wù)器?,然后通知客戶端API以reverse工作負(fù)載“Hello world!”?運(yùn)行該功能。就Gearman而言,函數(shù)名稱和參數(shù)是完全任意的,所以您可以發(fā)送適合您應(yīng)用程序的任何數(shù)據(jù)結(jié)構(gòu)(文本或二進(jìn)制文件)。此時(shí),Gearman客戶端API將把該作業(yè)打包到一個(gè)Gearman協(xié)議數(shù)據(jù)包中,并將其發(fā)送到作業(yè)服務(wù)器以查找可以運(yùn)行該reverse?功能的合適的工作人員。現(xiàn)在讓我們看看工人代碼:

<?php // Reverse Worker Code $worker = new GearmanWorker(); $worker->addServer(); $worker->addFunction("reverse", function ($job) {return strrev($job->workload()); }); while ($worker->work());

這段代碼定義了一個(gè)函數(shù)my_reverse_function,它接受一個(gè)字符串并返回該字符串的反轉(zhuǎn)。它被一個(gè)工作對(duì)象用來注冊(cè)一個(gè)函數(shù),該函數(shù)reverse被設(shè)置為連接到與客戶端相同的本地作業(yè)服務(wù)器。當(dāng)作業(yè)服務(wù)器接收到要運(yùn)行的作業(yè)時(shí),它查看已經(jīng)注冊(cè)了該功能名稱reverse的工作人員列表,并將該作業(yè)轉(zhuǎn)發(fā)給其中一個(gè)空閑工作人員。然后,Gearman工作者API接受這個(gè)請(qǐng)求,運(yùn)行該功能my_reverse_function,并通過作業(yè)服務(wù)器將該功能的結(jié)果發(fā)送回客戶端。

如您所見,客戶端和工作者API(以及作業(yè)服務(wù)器)處理作業(yè)管理和網(wǎng)絡(luò)通信,因此您可以專注于應(yīng)用程序部分。有幾種不同的方法可以在Gearman中運(yùn)行作業(yè),包括異步處理和優(yōu)先作業(yè)的背景。有關(guān)詳細(xì)信息,請(qǐng)參閱可用于各種API?的?文檔。

Gearman如何有用?

上面的例子看起來像是很多工作來運(yùn)行一個(gè)函數(shù),但是有很多方法可以用。最簡單的答案是,你可以使用Gearman作為用不同語言編寫的客戶端和工作者之間的接口。如果您希望PHP Web應(yīng)用程序調(diào)用用C語言編寫的函數(shù),則可以將PHP客戶端API與C工作程序API配合使用,并在中間粘貼作業(yè)服務(wù)器。當(dāng)然,還有更高效的方式來做這件事(比如用C寫一個(gè)PHP擴(kuò)展),但是你可能需要一個(gè)PHP客戶端和一個(gè)Python工作者,或者一個(gè)MySQL客戶端和一個(gè)Perl工作者。您可以輕松地混合和匹配任何支持的語言界面,只需要所有應(yīng)用程序都能夠理解所發(fā)送的工作量。你最喜歡的語言是不是支持?獲得參與項(xiàng)目,對(duì)于你或者現(xiàn)有的Gearman開發(fā)人員來說,在C庫的頂部放置一個(gè)語言包裝可能相當(dāng)容易。

Gearman的另一個(gè)有用的方法是把工作代碼放在一個(gè)更適合工作的單獨(dú)的機(jī)器上(或者一組機(jī)器上)。假設(shè)您的PHP Web應(yīng)用程序想要進(jìn)行圖像轉(zhuǎn)換,但這是在Web服務(wù)器機(jī)器上運(yùn)行它的太多處理。您可以將映像發(fā)送到單獨(dú)的一組工作機(jī)器上進(jìn)行轉(zhuǎn)換,這樣負(fù)載不會(huì)影響Web服務(wù)器和其他PHP腳本的性能。通過這樣做,您也可以獲得一種自然形式的負(fù)載平衡,因?yàn)樽鳂I(yè)服務(wù)器僅向閑置的工作人員發(fā)送新作業(yè)。如果在特定機(jī)器上運(yùn)行的所有工作人員都很忙,則不必?fù)?dān)心在那里發(fā)送新工作。這使得多核服務(wù)器的擴(kuò)展非常簡單:工人機(jī)器上有16個(gè)核心嗎?啟動(dòng)你的工人的16個(gè)實(shí)例(或更多,如果他們沒有CPU綁定)。也可以無縫添加新機(jī)器來擴(kuò)展您的工作池,只需啟動(dòng)它們,安裝工作代碼,并將它們連接到現(xiàn)有的作業(yè)服務(wù)器。

現(xiàn)在你可能會(huì)問如果作業(yè)服務(wù)器死亡?您可以運(yùn)行多個(gè)作業(yè)服務(wù)器,并讓客戶端和工作人員連接到配置的第一個(gè)可用作業(yè)服務(wù)器。這樣,如果一個(gè)工作服務(wù)器死亡,客戶端和工作人員會(huì)自動(dòng)故障轉(zhuǎn)移到另一個(gè)工作服?你可能不想運(yùn)行太多的作業(yè)服務(wù)器,但有兩到三個(gè)是冗余的好主意。左圖顯示了一個(gè)簡單的Gearman集群的外觀。

從這里,您可以根據(jù)需要擴(kuò)展您的客戶和工作人員。作業(yè)服務(wù)器可以輕松處理一次連接數(shù)百個(gè)客戶端和工作人員。您可以在容量允許的情況下繪制自己的物理(或虛擬)機(jī)器生產(chǎn)線,可能將負(fù)載分配到任意數(shù)量的機(jī)器。有關(guān)具體使用和安裝的更多細(xì)節(jié),請(qǐng)參閱示例部分。

更新來。

?

2Gearman架構(gòu)中的三個(gè)角色

client:請(qǐng)求的發(fā)起者,工作任務(wù)的需求方(可以是C、PHP、Java、Perl、Mysql udf等等)

Job Server:請(qǐng)求的調(diào)度者,負(fù)責(zé)將client的請(qǐng)求轉(zhuǎn)發(fā)給相應(yīng)的worker(gearmand服務(wù)進(jìn)程創(chuàng)建)

worker:請(qǐng)求的處理者(可以是C、PHP、Java、Perl等等)

Gearman是如何工作的?

?

從上圖可以看出,Gearman Client API,Gearman Worker API,Gearman Job Server都是由gearman本身提供,我們?cè)趹?yīng)用中只需要調(diào)用即可。目前client與worker api都很豐富。

3Gearman的吞吐能力

經(jīng)過的測(cè)試,結(jié)果如下:

系統(tǒng)環(huán)境:ubuntu-14.0.4 1個(gè)CPU 4核 2G內(nèi)存 (虛擬機(jī))

默認(rèn)啟動(dòng):./gearmand -d

client.php

  • <?php
  • echo?"starting...",?microtime(true),?"n";
  • $gmc?=?new?GearmanClient();
  • $gmc->setCompleteCallBack(function($task){
  • //echo $task->data(), "n";
  • });
  • $gmc->addServer("127.0.0.1",?4730);
  • for?($i?=?0;?$i?<?100000;?$i++)?{
  • $gmc->addTaskBackground("reserve",?"just test it",?null,?$i);
  • }
  • $gmc->runTasks();
  • echo?"end...",?microtime(true),?"n";
  • worker.php

  • <?php
  • $gmw?=?new?GearmanWorker();
  • $gmw->addServer("127.0.0.1",?4730);
  • $gmw->addFunction("reserve",?function($job)?{
  • if?($job->unique()?==?99999)?{
  • echo microtime(true),?"n";
  • }
  • return?strrev($job->workload());
  • });
  • while($gmw->work());
  • 啟動(dòng)一個(gè)job server實(shí)例:job server IP:127.0.0.1 PORT:4730

    ?

    啟動(dòng)一個(gè)worker: php worker.php

    worker注冊(cè)reserve函數(shù),將client的job字符串反轉(zhuǎn)后返回。

    client工作任務(wù)的消息為:just test it(12字節(jié))

    同步:4100/s

    異步:25700/s

    memcached內(nèi)存準(zhǔn)持久化的吞吐能力測(cè)試

    ./gearmand -d -q libmemcached —libmemcached-servers=127.0.0.1:11211

    client投遞100000個(gè)工作任務(wù):16400/s

    Gearman典型的部署結(jié)構(gòu)

    ?

    Gearman支持的特性

    高可用

    啟動(dòng)兩個(gè)job server,他們是獨(dú)立的服務(wù)進(jìn)程,有各自的內(nèi)存隊(duì)列。當(dāng)一個(gè)job server進(jìn)程出現(xiàn)故障,另一個(gè)job server可以正常調(diào)度。(worker api與client api可以完成job server故障的切換)。在任何時(shí)候我們可以關(guān)閉某個(gè)worker,即使那個(gè)worker正在處理工作任務(wù)(Gearman不會(huì)讓正在被執(zhí)行的job丟失的,由于worker在工作時(shí)與Job server是長連接,所以一旦worker發(fā)生異常,Job server能夠迅速感知并重新派發(fā)這個(gè)異常worker剛才正在執(zhí)行的工作)

    負(fù)載均衡(附gearman協(xié)議會(huì)詳細(xì)解釋)

    job server并不主動(dòng)分派工作任務(wù),而是由worker從空閑狀態(tài)喚醒之后到j(luò)ob server主動(dòng)抓取工作任務(wù)。

    可擴(kuò)展

    松耦合的接口和無狀態(tài)的job,只需要啟動(dòng)一個(gè)worker,注冊(cè)到Job server集群即可。新加入的worker不會(huì)對(duì)現(xiàn)有系統(tǒng)有任何的影響。

    分布式

    gearman是分布式的任務(wù)分發(fā)框架,worker與job server,client與job server通信基于tcp的socket連接。

    隊(duì)列機(jī)制

    gearman內(nèi)置內(nèi)存隊(duì)列,默認(rèn)情況隊(duì)列最大容量為300W,可以配置最大支持2^32-1,即4 294 967 295。

    高性能

    作為Gearman的核心,Job server的是用C/C++實(shí)現(xiàn)的,由于只是做簡單的任務(wù)派發(fā),因此系統(tǒng)的瓶頸不會(huì)出在Job server上。

    兩種工作任務(wù)

    后臺(tái)工作任務(wù)Background job——時(shí)序圖

    ?

    由圖可知,client提交完job,job server成功接收后返回JOB_CREATED響應(yīng)之后,client就斷開與job server之間的鏈接了。后續(xù)無論發(fā)生什么事情,client都是不關(guān)心的。同樣,job的執(zhí)行結(jié)果client端也沒辦法通過Gearman消息框架 獲得。

    一般工作任務(wù)Non-background job——時(shí)序圖

    由圖可知,client端在job執(zhí)行的整個(gè)過程中,與job server端的鏈接都是保持著的,這也給job完成后job server返回執(zhí)行結(jié)果給client提供了通路。同時(shí),在job執(zhí)行過程當(dāng)中,client端還可以發(fā)起job status的查詢。當(dāng)然,這需要worker端的支持的。

    4關(guān)于持久化

    對(duì)于隊(duì)列持久化的問題,是一個(gè)值得考慮的問題。持久化必然影響高性能。gearman支持后臺(tái)工作任務(wù)的持久化,支持drizzle、mysql、memcached的持久化。對(duì)于client提交的background job,Job server除了將其放在內(nèi)存隊(duì)列中進(jìn)行派發(fā)之外,還會(huì)將其持久化到外部的持久化隊(duì)列中。一旦Job server發(fā)生問題重啟,外部持久化隊(duì)列中的background job將會(huì)被恢復(fù)到內(nèi)存中,參與Job server新的派發(fā)當(dāng)中。這保證了已提交未執(zhí)行的background job不會(huì)由于Job server發(fā)生異常而丟失。并且我測(cè)試發(fā)現(xiàn)如果開啟了持久化,那么后臺(tái)工作任務(wù)會(huì)先將工作任務(wù)寫到持久化介質(zhì),然后在入內(nèi)存隊(duì)列,再執(zhí)行。非后臺(tái)工作任務(wù),由于client與job server是保持長連接的狀態(tài),如果工作任務(wù)執(zhí)行異常,client可以靈活處理,所以無須持久化。

    Gearman框架中的一個(gè)問題

    從典型部署結(jié)構(gòu)看出,兩個(gè)Job server之間是沒有連接的。也就是Job server間是不共享background job的。如果通過讓兩個(gè)Job server指向同一個(gè)持久化隊(duì)列,可以讓兩個(gè)Job serer互相備份。但實(shí)際上,這樣是行不通的。因?yàn)镴ob server只有在啟動(dòng)時(shí)才會(huì)將持久化隊(duì)列中的background job轉(zhuǎn)入到內(nèi)存隊(duì)列。也就是說,Job server1如果宕機(jī)且永遠(yuǎn)不啟動(dòng),Job server2一直正常運(yùn)行,那么Job server1宕機(jī)前被提交到Job server1的未被執(zhí)行的background job將永遠(yuǎn)都呆在持久化隊(duì)列中,得不到執(zhí)行。另外如果多個(gè)job server實(shí)例指向同一個(gè)持久化隊(duì)列,同時(shí)重啟多個(gè)job server實(shí)例會(huì)導(dǎo)致持久隊(duì)列中的工作任務(wù)被多次載入,從而導(dǎo)致消息重復(fù)處理。

    我建議的部署結(jié)構(gòu)

    ?

    采用memcached做后臺(tái)工作任務(wù)的準(zhǔn)持久化隊(duì)列,最好memcached和job server在內(nèi)網(wǎng)的不同機(jī)器。兩個(gè)機(jī)器的兩個(gè)服務(wù)同時(shí)掛掉的可能性比較小,同時(shí)也保證了高性能。而且memcached應(yīng)該為兩個(gè)相互獨(dú)立實(shí)例,防止其上述的gearman框架中的問題。我們可以做一個(gè)監(jiān)控腳本,如果某個(gè)job server異常退出,可以重啟,也最大化的保證了job server的高可用。

    5關(guān)于Gearman的管理工具

    目前有一個(gè)現(xiàn)在的管理工具,https://github.com/brianlmoon/GearmanManager,但是只支持php-5.2,不過可以自行修改支持php-5.4,我建議如果使用PHP作為worker進(jìn)程,使用php-5.4以上的版本。該工具的設(shè)計(jì)方法可以借鑒,可以比較好的管理gearman worker。

    應(yīng)用場(chǎng)景

  • 結(jié)合linux crontab,php腳本負(fù)責(zé)產(chǎn)生job,將任務(wù)分發(fā)到多臺(tái)服務(wù)器周期性的并發(fā)執(zhí)行。可以取代目前我們比較多的crontab的工作任務(wù)。

  • 郵件短信發(fā)送

  • 異步log

  • 跨語言相互調(diào)用(對(duì)于密集型計(jì)算的需求,可以用C實(shí)現(xiàn),PHP直接調(diào)用)

  • 其他耗時(shí)腳本

  • Gearman安裝(unbuntu)

    下載

    ?

    $>wget https://launchpadlibrarian.net/165674261/gearmand-1.1.12.tar.gz

    安裝依賴包

    $>sudo apt-get install libboost1.55-all-dev gperf libevent libevent-dev uuid libmemcached-dev $>tar zxvf gearmand-1.1.12.tar.gz $>cd gearmand-1.1.12 $>/configure --prefix=/home/phpboy/Server/gearman $>make & make install

    啟動(dòng)

    a)默認(rèn)啟動(dòng)

    ?

    $>./gearman -d

    b)支持memcached準(zhǔn)持久化

    $>./gearmand -d -q libmemcached --libmemcached-servers=127.0.0.1:11211

    安裝php的Gearman擴(kuò)展

    $>wget http://pecl.php.net/get/gearman-1.1.2.tgz $>tar zxvf gearman-1.1.2.tgz#cd gearman-1.1.2 $>phpize $>./configure --with-php-config=php-config $>make & make install

    php client api與php worker api

    可以用上面我的測(cè)試的示例

    附Gearmand(job server的啟動(dòng)參數(shù)簡單說明)

    -b, –backlog=BACKLOG 連接請(qǐng)求隊(duì)列的最大值 -d, –daemon Daemon 守護(hù)進(jìn)程化 -f, –file-descriptors=FDS 可打開的文件描述符數(shù)量 -h, –help -l, –log-file=FILE Log 日志文件 -L, –listen=ADDRESS 開啟監(jiān)聽的地址 -p, –port=PORT 開啟監(jiān)聽的端口 -P, –pid-file=FILE File pid file -r,–protocol=PROTOCOL 使用的協(xié)議 -q, –queue-type=QUEUE 持久化隊(duì)列類型 -t, –threads=THREADS I/O線程數(shù)量 -u, –user=USER 進(jìn)程的有效用戶名 libdrizzle Options: --libdrizzle-host=HOST Host of server. --libdrizzle-port=PORT Port of server. --libdrizzle-uds=UDS Unix domain socket for server. --libdrizzle-user=USER User name for authentication. --libdrizzle-password=PASSWORD Password for authentication. --libdrizzle-db=DB Database to use. --libdrizzle-table=TABLE Table to use. --libdrizzle-mysql Use MySQL protocol. libmemcached Options: --libmemcached-servers=SERVER_LIST List of Memcached servers to use. libsqlite3 Options: --libsqlite3-db=DB Database file to use. --libsqlite3-table=TABLE Table to use. libpq Options: --libpq-conninfo=STRING PostgreSQL connection information string. --libpq-table=TABLE Table to use. http Options: --http-port=PORT Port to listen on.

    Gearman通信協(xié)議

    總括

    Gearman工作在TCP上,默認(rèn)端口為4730,client與job server、worker與job server的通信都基于此tcp的socket連接。client是工作任務(wù)的發(fā)起者,worker是可以注冊(cè)處理函數(shù)的工作任務(wù)執(zhí)行者,job server為工作的調(diào)度者。協(xié)議包含請(qǐng)求報(bào)文與響應(yīng)報(bào)文兩個(gè)部分,所有發(fā)向job server的數(shù)據(jù)包(TCP報(bào)文段的數(shù)據(jù)部分)認(rèn)為是請(qǐng)求報(bào)文,所有從job server發(fā)出的數(shù)據(jù)包(TCP報(bào)文段的數(shù)據(jù)部分)認(rèn)為是響應(yīng)報(bào)文。worker或者client與job server間的通信是基于二進(jìn)制數(shù)據(jù)流的,但在管理client也有基于行文本協(xié)議的通信。

    請(qǐng)求的報(bào)文體

    ?

    響應(yīng)的報(bào)文體

    后臺(tái)工作任務(wù)Background job

    一般工作任務(wù)Non-background job

    二進(jìn)制包

    請(qǐng)求報(bào)文與響應(yīng)報(bào)文是由二進(jìn)制包封裝。一個(gè)二進(jìn)制包由頭header和可選的數(shù)據(jù)部分data組成。

    header的組成

  • 報(bào)文類別,請(qǐng)求報(bào)文或者響應(yīng)報(bào)文,4個(gè)字節(jié)
    “�REQ” 請(qǐng)求報(bào)文
    “�RES” 響應(yīng)報(bào)文

  • 包類型,高(大)字節(jié)序(網(wǎng)絡(luò)字節(jié)序),4個(gè)字節(jié)可能的類型有

  • ?

    類型值 名稱 報(bào)文類型 發(fā)送者

    ?

    ?

    1 CAN_DO REQ Worker 2 CANT_DO REQ Worker 3 RESET_ABILITIES REQ Worker 4 PRE_SLEEP REQ Worker 5 (unused) - - 6 NOOP RES Worker 7 SUBMIT_JOB REQ Client 8 JOB_CREATED RES Client 9 GRAB_JOB REQ Worker 10 NO_JOB RES Worker 11 JOB_ASSIGN RES Worker 12 WORK_STATUS REQ Worker 13 WORK_COMPLETE REQ Worker 14 WORK_FAIL REQ Worker 15 GET_STATUS REQ Client 16 ECHO_REQ REQ Client/Worker 17 ECHO_RES RES Client/Worker 18 SUBMIT_JOB_BG REQ Client 19 ERROR RES Client/Worker 20 STATUS_RES RES Client 21 SUBMIT_JOB_HIGH REQ Client 22 SET_CLIENT_ID REQ Worker 23 CAN_DO_TIMEOUT REQ Worker 24 ALL_YOURS REQ Worker 25 WORK_EXCEPTION REQ Worker 26 OPTION_REQ REQ Client/Worker 27 OPTION_RES RES Client/Worker 28 WORK_DATA REQ Worker 29 WORK_WARNING REQ Worker 30 GRAB_JOB_UNIQ REQ Worker 31 JOB_ASSIGN_UNIQ RES Worker 32 SUBMIT_JOB_HIGH_BG REQ Client 33 SUBMIT_JOB_LOW REQ Client 34 SUBMIT_JOB_LOW_BG REQ Client 35 SUBMIT_JOB_SCHED REQ Client 36 SUBMIT_JOB_EPOCH REQ Client

    ?

  • 可選數(shù)據(jù)部分長度,高(大)字節(jié)序(網(wǎng)絡(luò)字節(jié)序),4個(gè)字節(jié),可表示的值為4294967295
  • 數(shù)據(jù)部分,數(shù)據(jù)部分的各個(gè)部分為null字符分隔。

    具體各包類型的說明

    client和worker可發(fā)送請(qǐng)求報(bào)文

    ECHO_REQ

    當(dāng)job server收到此包類型的請(qǐng)求報(bào)文時(shí),就簡單的產(chǎn)生一個(gè)包類型為ECHO_RES,同時(shí)將請(qǐng)求報(bào)文的數(shù)據(jù)部分作為響應(yīng)報(bào)文的數(shù)據(jù)部分的報(bào)文。主要用于測(cè)試或者調(diào)試

    如:

    Client -> Job Server 00 52 45 51 0REQ 報(bào)文類型 00 00 00 a0 16 (Packet type: ECHO_ERQ) 00 00 00 04 4 (Packet length) 74 65 73 74 test (Workload)

    ECHO_RESclient和worker可接收響應(yīng)報(bào)文

    當(dāng)job server響應(yīng)ECHO_REQ報(bào)文時(shí)發(fā)送的包類型為ECHO_RES的響應(yīng)報(bào)文

    如:

    Job Server -> Client 00 52 45 53 0RES 報(bào)文類型 00 00 00 a1 17 (Packet type: ECHO_ERS) 00 00 00 04 4 (Packet length) 74 65 73 74 test (Workload)

    當(dāng)job server發(fā)生錯(cuò)誤時(shí),需要通知client或者workerERROR

    client發(fā)送的請(qǐng)求報(bào)文:(僅能由client發(fā)送的請(qǐng)求報(bào)文)
    SUBMIT_JOB, SUBMIT_JOB_BG,SUBMIT_JOB_HIGH, SUBMIT_JOB_HIGH_BG,SUBMIT_JOB_LOW, SUBMIT_JOB_LOW_BG

    當(dāng)client有一個(gè)工作任務(wù)需要運(yùn)行,就會(huì)提交相應(yīng)的請(qǐng)求報(bào)文,job server響應(yīng)包類型為JOB_CREATED數(shù)據(jù)部分為job handle的響應(yīng)報(bào)文。SUBMIT_JOB為普通的工作任務(wù),client得到狀態(tài)更新及通知任務(wù)已經(jīng)完成的響應(yīng);SUBMIT_JOB_BG為異步的工作任務(wù),client不關(guān)心任務(wù)的完成情況;SUBMIT_JOB_HIGH為高優(yōu)先級(jí)的工作任務(wù),SUBMIT_JOB_HIGH_BG為高優(yōu)先級(jí)的異步任務(wù);SUBMIT_JOB_LOW為低優(yōu)先級(jí)的工作任務(wù),SUBMIT_JOB_LOW_BG為低優(yōu)先級(jí)的異步任務(wù)。

    如:

    1 2 3 4 5 6 7 8 9 10 11 12 13 Client -> Job Server 00 52 45 51 0REQ (報(bào)文類型) 00 00 00 07 7 (Packet type: SUBMIT_JOB) 00 00 00 0d 13 (Packet length) 72 65 76 65 72 73 65 00 reverse0 (Function) 00 � (Unique ID) 74 65 73 74 test (Workload)

    SUBMIT_JOB_SCHED

    和SUBMIT_JOB_BG類似,此類型的工作任務(wù)不會(huì)立即執(zhí)行,而在設(shè)置的某個(gè)時(shí)間運(yùn)行。

    如:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Client -> Job Server 00 52 45 51 0REQ (報(bào)文類型) 00 00 00 23 35 (Packet type: SUBMIT_JOB_SCHED) 00 00 00 0d 13 (Packet length) 72 65 76 65 72 73 65 00 reverse0 (Function) 00 � (Unique ID) 01 � (minute 0-59) 01 � (hour 0-23) 01 � (day of month 1-31) 01 � (day of month 1-12) 01 � (day of week 0-6) 74 65 73 74 test (Workload)

    SUBMIT_JOB_EPOCH

    和SUBMIT_JOB_SCHED作用一樣,只是將設(shè)置的時(shí)間定為了uinx時(shí)間戳GET_STATUS獲取某個(gè)工作任務(wù)執(zhí)行的狀態(tài)信息

    OPTION_REQ

    設(shè)置client與job server連接的選項(xiàng)

    client獲取的響應(yīng)報(bào)文:

    JOB_CREATED響應(yīng)包類型為SUBMIT_JOB*的請(qǐng)求報(bào)文,數(shù)據(jù)部分為job handle

    WORK_DATA, WORK_WARNING, WORK_STATUS, WORK_COMPLETE,WORK_FAIL, WORK_EXCEPTION

    對(duì)于后臺(tái)運(yùn)行的工作任務(wù),任務(wù)執(zhí)行信息可以通過包類型為上面的值來查看。

    STATUS_RES

    響應(yīng)包類型為GET_STATUS的請(qǐng)求報(bào)文,通常用來查看一個(gè)后臺(tái)工作任務(wù)是否已經(jīng)完成,以及完成的百分比。

    OPTION_RES

    響應(yīng)包類型為OPTION_REQ的請(qǐng)求報(bào)文

    worker發(fā)送的請(qǐng)求報(bào)文:

    CAN_DO

    通知job server可以執(zhí)行給定的function name的任務(wù),此worker將會(huì)放到一個(gè)鏈表,當(dāng)job server收到一個(gè)function name的工作任務(wù)時(shí),worker為被喚醒。

    CAN_DO_TIMEOUT

    和CAN_DO類似,只是針對(duì)給定的function_name的任務(wù)設(shè)置了一個(gè)超時(shí)時(shí)間。

    CANT_DO

    worker通知job server已經(jīng)不能執(zhí)行給定的function name的任務(wù)

    RESET_ABILITIES

    worker通知job server不能執(zhí)行任何function name的任務(wù)

    PRE_SLEEP

    worker通知job server它將進(jìn)入sleep階段,而之后此worker會(huì)被包類型為NOOP的響應(yīng)報(bào)文喚醒。

    GRAB_JOB

    worker向job server抓取工作任務(wù),job server將會(huì)響應(yīng)NO_JOB或者JOB_ASSIG

    NGRAB_JOB_UNIQ

    和GRAB_JOB類似,但是job server在有工作任務(wù)時(shí)將會(huì)響應(yīng)JOB_ASSIGN_UNIQ

    WORK_DATA

    worker請(qǐng)求報(bào)文的數(shù)據(jù)部分更新client

    WORK_WARNING

    worker請(qǐng)求報(bào)文代表一個(gè)warning,它應(yīng)該被對(duì)待為一個(gè)WARNING

    WORK_STATU

    Sworker更新某個(gè)job handle的工作狀態(tài),job server應(yīng)該儲(chǔ)存這些信息,以便響應(yīng)之后client的GET_STATUS請(qǐng)求

    WORK_COMPLETE

    通知job server及所有連接的client,數(shù)據(jù)部分為返回給client的數(shù)據(jù)

    WORK_FAIL

    通知job server及所有連接的client,工作任務(wù)執(zhí)行失敗

    WORK_EXCEPTION

    通知job server及所有連接的client,工作任務(wù)執(zhí)行失敗并給出相應(yīng)的異常

    SET_CLIENT_ID

    設(shè)置worker ID,從而job server的控制臺(tái)及報(bào)告命令可以標(biāo)識(shí)各個(gè)worker,數(shù)據(jù)部分為worker實(shí)例的標(biāo)識(shí)

    ALL_YOURS

    暫未實(shí)現(xiàn)

    worker獲取的響應(yīng)報(bào)文:

    NOOP

    job server喚醒sleep的worker,以便可以開始抓取工作任務(wù)

    NO_JOB

    job server響應(yīng)GRAB_JOB的請(qǐng)求,通知worker沒有等待執(zhí)行的工作任務(wù)

    JOB_ASSIGN

    job server響應(yīng)GRAB_JOB的請(qǐng)求,通知worker有需要執(zhí)行的工作任務(wù)

    JOB_ASSIGN_UNIQ

    job server響應(yīng)GRAB_JOB_UNIQ的請(qǐng)求,和JOB_ASSIGN一樣,只是為client傳遞了一個(gè)唯一標(biāo)識(shí)

    基于上述的協(xié)議描述一個(gè)完整的例子

    worker注冊(cè)可以執(zhí)行的工作任務(wù)

    Worker -> Job Server

    1 2 3 4 5 6 7 00 52 45 51 0REQ (Magic) 00 00 00 01 1 (Packet type: CAN_DO) 00 00 00 07 7 (Packet length) 72 65 76 65 72 73 65 reverse (Function)

    worker檢測(cè)或者抓取工作任務(wù)

    1 2 3 4 5 6 7 Worker -> Job Server 00 52 45 51 0REQ (Magic) 00 00 00 09 9 (Packet type: GRAB_JOB) 00 00 00 00 0 (Packet length)

    job server響應(yīng)worker的抓取工作(沒有工作任務(wù))

    1 2 3 4 5 00 52 45 53 0RES (Magic) 00 00 00 0a 10 (Packet type: NO_JOB) 00 00 00 00 0 (Packet length)

    worker通知job server開始sleep

    1 2 3 4 5 00 52 45 51 0REQ (Magic) 00 00 00 04 4 (Packet type: PRE_SLEEP) 00 00 00 00 0 (Packet length)

    client提交工作任務(wù)

    1 2 3 4 5 6 7 8 9 10 11 12 13 Client -> Job Server 00 52 45 51 0REQ (Magic) 00 00 00 07 7 (Packet type: SUBMIT_JOB) 00 00 00 0d 13 (Packet length) 72 65 76 65 72 73 65 00 reverse0 (Function) 00 � (Unique ID) 74 65 73 74 test (Workload)

    job server響應(yīng)client的SUBMIT_JOB請(qǐng)求,返回job handle

    1 2 3 4 5 6 7 00 52 45 53 0RES (Magic) 00 00 00 08 8 (Packet type: JOB_CREATED) 00 00 00 07 7 (Packet length) 48 3a 6c 61 70 3a 31 H:lap:1 (Job handle)

    job server喚醒worker

    1 2 3 4 5 6 7 Job Server -> Worker 00 52 45 53 0RES (Magic) 00 00 00 06 6 (Packet type: NOOP) 00 00 00 00 0 (Packet length)

    worker的抓取工作任務(wù)

  • Worker?->?Job?Server
  • ?
  • 00?52?45?51?\0REQ?(Magic)
  • ?
  • 00?00?00?09?9?(Packet?type:?GRAB_JOB)
  • ?
  • 00?00?00?00?0?(Packet?length)
  • job server分配工作任務(wù)給worker

  • Job?Server?->?Worker
  • ?
  • 00?52?45?53?\0RES?(Magic)
  • ?
  • 00?00?00?0b?11?(Packet?type:?JOB_ASSIGN)
  • ?
  • 00?00?00?14?20?(Packet?length)
  • ?
  • 48?3a?6c?61?70?3a?31?00?H:lap:1\0?(Job?handle)
  • ?
  • 72?65?76?65?72?73?65?00?reverse\0?(Function)
  • ?
  • 74?65?73?74?test?(Workload)
  • worker完成工作任務(wù)通知job server

  • 00?52?45?51?\0REQ?(Magic)
  • ?
  • 00?00?00?0d?13?(Packet?type:?WORK_COMPLETE)
  • ?
  • 00?00?00?0c?12?(Packet?length)
  • ?
  • 48?3a?6c?61?70?3a?31?00?H:lap:1\0?(Job?handle)
  • ?
  • 74?73?65?74?tset?(Response)
  • job server通知client完成了工作任務(wù)

    ?

    Job Server -> Client

  • 00?52?45?53?\0RES?(Magic)
  • ?
  • 00?00?00?0d?13?(Packet?type:?WORK_COMPLETE)
  • ?
  • 00?00?00?0c?12?(Packet?length)
  • ?
  • 48?3a?6c?61?70?3a?31?00?H:lap:1\0?(Job?handle)
  • ?
  • 74?73?65?74?tset?(Response)
  • 每個(gè)client與job server是全雙工通信,在一個(gè)socket可以完成多個(gè)工作任務(wù)的投遞,但是收到任務(wù)的執(zhí)行結(jié)果的順序可能與投遞的順序不一致。

    ?詳見:http://gearman.org/protocol/

    6總結(jié)worker的工作流程

  • Worker通過CAN_DO消息,注冊(cè)到Job server上。

  • 隨后發(fā)起GRAB_JOB,主動(dòng)要求分派任務(wù)。

  • Job server如果沒有job可分配,就返回NO_JOB。

  • Worker收到NO_JOB后,進(jìn)入空閑狀態(tài),并給Job server返回PRE_SLEEP消息,告訴Job server:”如果有工作來的話,用NOOP請(qǐng)求我先。”

  • Job server收到worker的PRE_SLEEP消息后,明白了發(fā)送這條消息的worker已經(jīng)進(jìn)入了空閑態(tài)。

  • 這時(shí)如果有job提交上來,Job server會(huì)給worker先發(fā)一個(gè)NOOP消息。

  • Worker收到NOOP消息后,發(fā)送GRAB_JOB向Job server請(qǐng)求任務(wù)。

  • Job server把工作派發(fā)給worker。

  • Worker干活,完事后返回WORK_COMPLETE給Job server。

  • 總結(jié)

    以上是生活随笔為你收集整理的分布式计算框架Gearman原理详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。