使用 Gearman 實現分佈式處理

 由於近來在研究 Mogilefs 的分佈文件系統,在讀讀這個的源碼,另外,爲公司新設計了一個下載的系統,因此更加要深刻研究一下,由於這個好東西是 Perl 寫的,真不容易,在讀這個的時間發現了幾個好東西,其中一個就是我如今要提到的 Gearman ,這是個分佈的任務分發的框架.使用 Perl 寫的.後來用 C 重寫了其中一些部分.做者 Brad Fitzpatrick 大神開發的 Gearman, 他原來是 livejournal 的成員,設計最初也是用於LiveJournal的圖片 resize 功能,目前是 Google 的成員.php

        簡單的講, Gearman 就是一個用 Perl 寫的任務調度程序,它能提供一個服務器端進行任務調度,本身就不作其它任何事了.客戶端同時也提供了多種語言接口.Gearman 這個框架系統主要的工做是用來委派任務給其餘機器,Mogilefs 的分佈文件系統的核心就是用的這個.因此咱們能夠基於這個作一個本身的 Cluster 出來.html

        這個軟件的應用場景能夠不少,好比 Web 2.0 的項目中,好比經常使用的視頻網站的視頻處理,分佈式日誌處理,電子郵件處理,文件同步處理,圖片處理等等,只要是能夠放開,不影響體驗和響應的場景,須要並行進行大量計算和處理的程序,都是能夠的.不要由於 Gearman 是 Perl 寫的而認爲通用性就不行,由於設計時就是獨立於語言和平臺的.因此客戶端能夠是任何語言,象 Perl,PHP,Python,Ruby之類.就算是 Shell 也行web

Gearman 的做者 Eric Day 介紹,Yahoo! 在 60 或更多的服務器上使用 Gearman 天天處理 600 萬個做業.新聞聚合器 Digg 也已構建了一個相同規模的 Gearman 網絡,天天可處理 400,000 個做業.Gearman 的一個出色例子能夠在 Narada 這個開源搜索引擎中找到.服務器

 

Gearman 的架構
一個鏈接客戶機和 Workerer 鏈接在 Gearman 上組成一個網絡,也就是 Gearman 請求的處理過程涉及三個部分:Client -> Job -> Worker.這種實際網絡中是很是經常使用的.而後咱們的應用提交程序來作客戶端的程度,提交任務.到了 Job Server 的隊列中,由 Worker 的服務器來取下來,並處理這個任務,因此咱們能夠看出  Gearman 自己從客戶機收集工做請求並充當一個註冊器這二個事.網絡

  • Gearman 守護進程:    這個是主體,進行任務的調度分配,狀態的記錄
  • Gearman 客戶(Client):      請求的發起者,用於向 Gearman 服務提交請求的客戶機
  • Gearman 工做者(Worker):  對任務的處理者

如圖架構

 

Gearman 怎麼樣工做負載均衡

Gearman 不但能夠作爲任務分發,還能夠作爲應用方面是負載均衡,咱們可讓 Workerer 放在不一樣的一堆服務器上,也能夠啓動放在同一個 CPU 的多個核上,好比,以咱們經常使用的應用視頻轉換程序,可是不但願 Web 的服務器來處理視頻的格式處理的過程,這時,咱們就能夠在這一堆服務器上進行任務分發,在上面加載 Workerer 處理視頻格式處理和轉換.這樣對外的 web 服務器將不會被視頻轉換的過程影響,同時也能不少的讓全部服務器負載均衡的工做來處理,也很是方便擴展,加一個機器到任務調度中心,註冊成 Workerer 就行,這時 Job Server 會在請求到來的時候,將這個請求發給空閒的這個 Workerer. 另外你還能夠運行多個Job Server.能夠組成一個 HA 的架構,若是一個Job Server 的進程 down了,client 和 Workerer 會自動遷移到另外一臺Job Server上.框架

簡單來說,就是下面的流程dom

  1. 啓動 Gearman ,監聽 7003
  2. 啓動 Worker , 註冊功能到服務器上.
  3. 啓動 Client ,請求註冊的功能,並提供輸入的數據
  4. Gearman 的服務發送"功能請求"到 Worker.並給 Client 輸入的數據傳送給 Worker.
  5. Worker 接收到"功能請求"和輸入的數據.並處理輸入的數據內容.
  6. Worker 返回處理的數據結果,服務轉發這個結果給客戶端.
  7. Client 客戶端接收處處理的結果,並顯示結果給用戶


如圖異步


從上面能夠看出來 Worker 是可擴展的.若是你有須要 Worker 是能夠運行任意多個的.
另外,咱們對 Application 是不用過多在乎的.一樣也是能夠多個的. Application 的客戶只有一個任務,就是加入任務到 Gearman 中來.

 

安裝 Gearman 的環境
安裝 Gearman::Server 的 Job Server ,若是沒有安裝 Client 就須要 Client 和 Worker 都裝上.若是不會使用 cpanm 的話,參考我之前寫過的 使用CPANMinus 來安裝Perl 模塊

1
2
3
$ cpanm Gearman::Server
$ cpanm Gearman::Client
$ cpanm Gearman::Worker

 

使用 Gearman 的功能 
Gearman 整體上來看看,分 4 大步的功能.

  1. 啓動 Gearman 的 Job Server 的服務
  2. 使用 Worker 加入和註冊一個可使用的功能
  3. Worker 等待功能任務被運行
  4. Client 鏈接啓動任務和提供任務須要的參數

Gearman 的 Job Server 調度程序的使用

(1. 啓動Job:

1
$ gearmand -d -L 127.0.0.1 -p 7003
  • -d deamon
  • -L 監聽 IP
  • -p 端口(2. Gearman 的狀態查看

 

1
2
$ telnet localhost 7003
status

給你們看個實際的輸出.

1
2
3
4
5
6
7
$  telnet 127.0.0.1 7003
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]' .
status
convertVideo    0     0     1
echo             1      0     0

 

 能夠見到如上的輸出,分 4 個部分.
已知任務  –  運行的任務  –  隊列中的任務  –  可用的 Worker.
如 convertVideo 0 0 1 .這個部分,註冊的任務名爲 convertVideo,0 個正常在運行,隊列爲空,有一個可用的 Worker.

1
2
3
4
5
6
7
8
9
10
11
12
$ telnet 127.0.0.1 4730
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]' .
worker
ERR unknown_command Unknown+server+command
workers
30 61.139.15.xxx eolxkmntdgalfedjyptoppbphmudgl : getImage
31 61.139.15.xxx ztixxiwqnfhnghzfbeoyktuvrdylin : convert
34 61.139.15.xxx ruqcfefjwuwrsmnalqcsbnoustswxj : convert
33 61.139.15.xxx wfhfphvefnxynlsdpoduiyxlirkrqd : convert
32 61.139.15.xxx hckjonjakmmdtfmrbcyeexozfwxdqr : convert

也是 4 個部分
ID –  鏈接的主機的IP  –  識別碼  –  註冊的功能

管理協議

Gearman 的任務服務器也支持一個基於文本的協議,來取得一些信息和執行一些管理任務.
他是運行在二進制協議相同的端口上,二者之間的區別在於發送的第一個字符. 若是它是一個  NULL (\0), 那麼它是二進制的,若是它不爲 NULL,它試圖分析文本命令.支持下面的命令:

workers

    這會將會列出全部的 woker 信息,有文件描述符,IP地址,ID 和註冊的函數的列表.該列表被終止行包含一個單一的'.'(句點).其格式爲:

    FD IP-ADDRESS CLIENT-ID : FUNCTION …

    Arguments:
    – None.

status

這會將列出全部已註冊的功能的列表.每一個函數在隊列中的任務數量,正在運行的 woker, 有多少可用的woker.列表是以製表符分隔的,並且該列表最後包含一個單一的行"."(句點).
其格式爲:

    FUNCTION\tTOTAL\tRUNNING\tAVAILABLE_WORKERS

    Arguments:
    – None.

maxqueue

    這臺任務管理器功能調用的最大隊列大小.若是沒有給定大小,則使用缺省值.若是是沒有參數,則該隊列被設定爲無限數量.在結束時送 "OK" 字符.

    Arguments:
    – Function name.
    – Optional maximum queue size.

shutdown

    關掉服務,若是加了  "graceful" 的參數.在關掉監聽的 socket 時會等所有的鏈接完成時才關

    Arguments:
    – Optional "graceful" mode.

version

    發送這個服務器的版本.

    Arguments:
    – None.

若是是 Perl 版本的話,還有一個 'gladiator' 的命令.是用 'Devel::Gladiator' Perl 模塊實現的,能夠用來 debug.
 

 

Gearman 作爲 worker 來測試
咱們能夠啓動 Gearman 而後使用 -w 來指定工做在 worker 模式, -f 是用來指定註冊的功能名 — 後面是命令行

1
$ gearman -w -f passwd -- xargs -I '{}' sh -c "grep '{}' /etc/passwd | tr -d '\n'"

 

 

Gearman::Worker 的基本語法和使用

這個沒有什麼好講的,鏈接到主 Gearman 調度服務器.而後是經過內部的 register_function  函數來註冊一個功能,到 Gearman 的主調度服務器上去.好讓調度服務器知道這個 Worker 能處理的任務是什麼.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/perl
use strict;
use warnings;
use Gearman::Worker;
 
my $worker = Gearman::Worker->new;
$worker ->job_servers( '127.0.0.1' );
 
# Worker 註冊可使用的功能,若是視頻轉換...
$worker ->register_function( convertVideo => \&convertVideo ); 
 
# 等待鏈接的任務
$worker ->work while 1; 
 
sub convertVideo{
     my $job = shift ;
     # TODO 作你要實現的事情,任務
     return $job ->arg;
}

 

Gearman::Client 的基本語法和使用

Gearman::Client  工做分同步和異步二種,默認我打開的是異步的功能,注掉的部分打開就是使用同步調用任務.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/perl
use strict;
use warnings;
use Gearman::Client;
 
my $client = Gearman::Client->new;
$client ->job_servers( '127.0.0.1' );
 
# 設置異步任務
my $tasks = $client ->new_task_set;
$tasks ->add_task(
         # 開始任務
         convertVideo    => 'new.flv' ,
         # 註冊回調函數
         { on_complete   => \&complete }, 
         ); 
# 等待任務結束
$tasks -> wait ;
 
sub complete{
     my $result = shift ;
     print $ $result . "\n" ;
}
 
# 設置同步任務
#my $resultRef = $client->do_task( "convertVideo", "new.flv" );
#print "$$resultRef\n";
 
#$client->dispatch_background( "convertVideo","new.flv" );

擴展協議

在 0.8 的版本的時候, 這個 Gearman job server 加入了協議的插件支持.第一個支持的是原生的 HTTP 來使用 Gearman protocol. 這個協議的接口能夠接收的 send 和 recieve 功能.核心的讀和寫的功能可使用這個協議插件來支持.

HTTP

協議插件是給 HTTP 請求映射成 Gearman 的任務.它當前只支持 client 任務的提交,但它可能在將來進行擴展以支持其餘類型的請求. 這個插件可使用 GET and POST 來提交, 而後會給這些任務放入給  job server.這個 URL 的請求會被轉成功能的調用.象下面這個例子的請求:

1
2
3
4
POST / reverse HTTP/1.1
Content- Length : 12
 
Hello world!

上面這個會給使用 「reverse」這個功能,工做爲 「Hello world!」的參數. 這會返回:

1
2
3
4
5
6
HTTP/1.0 200 OK
X-Gearman-Job-Handle: H:lap:4
Content- Length : 12
Server: Gearman/0.8
 
!dlrow olleH


下面的這些 header 能夠傳送過去來作爲高級的 job 調用:

  • X-Gearman-Unique: <unique key>
  • X-Gearman-Background: true
  • X-Gearman-Priority: <high|low>

象這下面這個的例子中, 它運行在低級別的後臺做業,只須要象這樣發送請求:

1
2
3
4
5
6
POST / reverse HTTP/1.1
Content- Length : 12
X-Gearman-Background: true
X-Gearman-Priority: low
 
Hello world!

這個請求的響應將不會有任何數據,由於它是一個後臺做業:

1
2
3
4
HTTP/1.0 200 OK
X-Gearman-Job-Handle: H:lap:6
Content- Length : 0
Server: Gearman/0.8

相關文檔 http://search.cpan.org/~dormando/Gearman-Server-1.11/

 

來源:

http://www.php-oa.com/2010/09/05/perl-gearman-distributed.html

相關文章
相關標籤/搜索