[转] 使用 Gearman 实现分布式处理

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

 

因为近来在研究 Mogilefs 的分布文件系统,在读读这个的源码,另外,为公司新设计了一个下载的系统,所以更加要深入研究一下,因为这个好东西是 Perl 写的,真不容易,在读这个的时间发现了几个好东西,其中一个就是我现在要提到的 Gearman ,这是个分布的任务分发的框架.使用 Perl 写的.后来用 C 重写了其中一些部分.作者 Brad Fitzpatrick 大神开发的 Gearman, 他原来是 livejournal 的成员,设计最初也是用于LiveJournal的图片 resize 功能,目前是 Google 的成员.

        简单的讲, Gearman 就是一个用 Perl 写的任务调度程序,它能提供一个服务器端进行任务调度,自己就不做其它任何事了.客户端同时也提供了多种语言接口.Gearman 这个框架系统主要的工作是用来委派任务给其他机器,Mogilefs 的分布文件系统的核心就是用的这个.所以我们可以基于这个做一个自己的 Cluster 出来.

        这个软件的应用场景可以很多,比如 Web 2.0 的项目中,比如常用的视频网站的视频处理,分布式日志处理,电子邮件处理,文件同步处理,图片处理等等,只要是可以放开,不影响体验和响应的场景,需要并 行进行大量计算和处理的程序,都是可以的.不要因为 Gearman 是 Perl 写的而认为通用性就不行,因为设计时就是独立于语言和平台的.所以客户端可以是任何语言,象 Perl,PHP,Python,Ruby之类.就算是 Shell 也行

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上.

简单来讲,就是下面的流程

  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/

posted @ 2014-06-21 19:18  zflinux21  阅读(230)  评论(0编辑  收藏  举报