Gearman介绍
Gearman是一个用来把工作委派给其他机器、分布式的调用更适合做某项工作的机器、并发的做某项工作在多个调用间做负载均衡、或用来在调用其它语言的函数的系统。
通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用 WebService 的方式来处理此类集成问题,但不管采用何种风格的WebService,如 RPC 风格,或者 REST 风格,其本身都有一定的复杂性。相比之下,Gearman 也能实现类似的作用,而且更简单易用。
对于分布式网络环境或者有大量任务的应用,我们需要将任务在不同的服务器之间进行分布,这个时候正好是Gearman发挥实力的时候。虽然我们也可以使用MQ队列再加一些自己实现的调度算法来将任务进行分发,但是既然已经有了成熟的产品,为什么不使用下呢。
Gearman提供了一种通用的程序框架来将你的任务分发到不同的机器或者不同的进程当中。它提供了你进行并行工作的能力、负载均衡处理的能力,以及在不同程序语言之间沟通的能力。Gearman能够应用的领域非常广泛,从高可用的网站到数据库的复制任务。总之,Gearman就是负责分发处理的中枢系统,它的优点包括:
开源:Gearman免费并且开源而且有一个非常活跃的开源社区,如果你想来做一些贡献,请点击 。
多语言支持:Gearman支持的语言种类非常丰富。让我们能够用一种语言来编写Worker程序,但是用另外一种语言编写Client程序。
灵活:不必拘泥于固定的形式。您可以采用你希望的任何形式,例如 Map/Reduce。
快速:Gearman的协议非常简单,并且有一个用C语言实现的,经过优化的服务器,保证应用的负载在非常低的水平。
可植入:因为Gearman非常小巧、灵活。因此您可以将他置入到现有的任何系统中。
没有单点:Gearman不仅可以帮助扩展系统,同样可以避免系统的失败。
Gearman架构和工作原理
使用Gearman的应用通常有三部分组成:一个Client、一个Worker、一个任务服务器。 Client的作用是提出一个 Job 任务 交给 Job Server 任务服务器。Job Server 会去寻找一个 合适的 Worker 来完成这项任务。Worker 执行由 Client 发送过来的 Job,并且将结果通过 Job Server 返回给 Client。Gearman 提供了 Client 和 Worker 的 API,利用这些API 应用可以同 Gearman Job Server来进行通信。Gearman 内部 Client 和 Worker 之间的通信都是通过 TCP 连接来进行的。工作的流程如下图所示:
一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。
Gearman client:提供gearman client API给应用程序调用。API可以使用C,PHP,PERL,MYSQL UDF等待呢个语言,它是请求的发起者。
Gearman job server:将客户端的请求分发到各个gearman worker的调度者,相当于中央控制器,但它不处理具体业务逻辑。
Gearman worker:提供gearman worker API给应用程序调用,具体负责客户端的请求,并将处理结果返回给客户端。
因为 Client,Worker 并不限制用一样的语言,所以有利于多语言多系统之间的集成。
甚至我们通过增加更多的 Worker,可以很方便的实现应用程序的分布式负载均衡架构。
Gearman基本使用方法
Gearman首先提供了一个多语言通讯的接口,当然还有比这个更简单有效的办法。Gearman可以将工作的负载分担到不同的机器中,如下图所示:
Gearman不但可以做为任务分发,还可以做为应用方面的负载均衡。可以让worker放在不同的一堆服务器上,也可以启动放在同一个cpu的多个核上。比如,应用视频转换程序,不希望web服务器来处理视频格式转换,这时,可以在这一堆服务器上进行任务分发,在上面加载worker处理视频格式,对外的web服务器就不会被视频转换过程影响。而且扩展方便,加一台服务器到任务调度中心,注册成worker即可,这时job server会在请求到来的时候,将请求发送给空闲的worker。
Job Server 可以开启多个实例,组成HA架构,这样在其中一个发生故障的时候,client和worker会自动 Failover 到其他的机器上。
简单来讲,就是下面的流程
- 启动 Gearman ,监听 7003
- 启动 Worker , 注册功能到服务器上.
- 启动 Client ,请求注册的功能,并提供输入的数据
- Gearman 的服务发送"功能请求"到 Worker.并给 Client 输入的数据传送给 Worker.
- Worker 接收到"功能请求"和输入的数据.并处理输入的数据内容.
- Worker 返回处理的数据结果,服务转发这个结果给客户端.
- Client 客户端接收到处理的结果,并显示结果给用户
如图
从上面可以看出来 Worker 是可扩展的.如果你有需要 Worker 是可以运行任意多个的.
另外,我们对 Application 是不用过多在意的.同样也是可以多个的. Application 的客户只有一个任务,就是加入任务到 Gearman 中来.
下面是一个例子,可以详细解释Gearman的工作方式。 下面是一个PHP的反转字符串的例子。
我们首先写一个client,它负责发送job并等待处理结果,拿到结果后,直接打印出来。这个小程序,使用了Gearman的client API, 把function name和参数一同发送出去,function name是reverse。(省略了错误处理):
// Reverse Client Code
$client= new GearmanClient();
$client->addServer();
print $client->do("reverse", "Hello World!");
上边的代码初始化了一个client类,添加了一个job server(没有参数表示使用127.0.0.1的默认端口),然后告知API执行"reverse" function, workload为 "Hello world". Function name 和 参数不受限制, 所以发送任意的数据结构。从这一点来看,Gearman client API会把job打包为一个Gearman协议数据包,然后发送给job server, 找到一个能够执行reverse的worker。
现在我们来看下worker的代码:
# Reverse Worker Code
$worker= new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", "my_reverse_function");
while ($worker->work());
function my_reverse_function($job)
{
return strrev($job->workload());
}
以上代码定义了一个function “my_reverse_function”,输入一个字符串,输出反转的字符串。我们把他注册给GearmanWorker的实例,注册的 function name 为"reverse",之后它会被连接到job server(与之前的client连接的是同一个)。 当job server收到执行请求时,会查找worker list,看谁注册了"reverse"function, 然后把请求转发给一个闲置的worker. Gearman worker API会获取这个请求,然后调用注册过的php函数"my_reverse_function",php函数处理的结果会通过server返给客户端。
如你所见,client和worker APIs 处理job管理和网络通信,所以我们能把精力集中到应用本身。这里有几种不同的执行Gearman job的方法,包括后台异步处理和任务排序。
上边反转的例子看起来花了很大的力气去执行了一个function, 但这其实是有意义的。 一方面,gearman能够让你能够在client和worker使用不同的语言。如果你希望用PHP应用调用C的实现,你可以用PHP client API和C的worker API,然后搞一个job server放在中间。当然,跨语言调用有很多解决方案(比如用C写PHP扩展)。
我们再举一个例子,我们需要用PHP client去调Python的worker,或者用MySQL client和Perl worker...总之能很容易地实现混搭。如果你心爱的语言还没有API支持,可以参与项目,你或者Gearman的开发者可以很简单的搞一个C lib的封装。
“Gearman很有用”的第二个理由是,我们可以把worker扔到其他机器(或集群)上来干活。比如你的PHP web 应用需要做大量的图片处理,但web机没有足够的资源来处理,这样我们可以搞一台单独的机器来做图片处理,这样,图片处理的负担就不会对web服务器的执 行效率和响应速度造成影响。另外,这样做我们还能够实现负载均衡,因为job server总是把jobs发给闲置worker.在多核系统上,它的实现也很简单:如果你有一台16核的机器,开启16个worker就可(也许可以开 更多)。添加新机器也是无缝的,在新机器上部署worker 代码,然后把它们连到job server即可。
现在,你可能会问,job server挂了怎么办? 我们可以起多个job server,让clients和workers连接到配置好的可用的第一个job server. 如果一个job server挂掉,clients和workers自动找其他的可用的job server。开2-3个job server是不错的选择。上图是一个简单的集群的样子。
这样子,你就可以方便地扩张clients和workers了。job server可以轻松抗住上百个clients和workers同时连接。