gearman分布式负载均衡

本文介绍Gearman,一种用于分布式任务处理的轻量级框架,适用于日志保存、邮件发送等非主流程操作。Gearman由client、jobserver和worker组成,支持多种语言和持久化策略,如memcached和MySQL。

 1、简介

      gearman是一个分布式开发框架,适合处理一些必须处理但是不影响主流程的操作,比如保存日志、发送邮件、缩略图片等。最早是基于perl语言的,2008年发布的时候改为C++语言开发,其开发接口支持多种语言,如PHP、Java、Python、Ruby等等语言。其优点是部署轻便,并且有负载均衡和持久化的功能,除了一些大型场景需要消息队列来处理,一般的问题可以通过gearman来处理。在php官方网站有相应的api文档,gearman的主站也有一些相应的信息。

     gearman的架构主要分为3个角色: client、job server、worker,大致如下:

     1)client: 服务的发起方,请求个gearman处理某个操作,可以是PHP、Java、Python和Ruby等

     2)job server: 服务的调度方,有两个作用,接受worker的请求,注册worker的处理函数,接受client的请求,将处理转向相应的worker。

     3)worker: 服务的处理方,向job server注册本身提供的服务,并接受Job server转发过来的请求,进行处理,可以用PHP、Java、Python、Ruby实现。

     可以看出gearman的架构是个非常简单轻量,job server只负责转发,worker只负责处理,你可以启动多个相同的worker,job server会自动把请求在这些worker中均衡分配,并且它们都是通过网络访问,可以分布到不同的机器上,所以可以大大提高系统的性能和扩展性。默认情况下,gearman将接收的job保存到内存中,速度非常快,但是在意外宕机的情况下,就会丢失一些job,这可以通过持久化来解决,gearman支持的持久化策略有很多,常见的有mysql、sqllite、postgresql这些关系数据库,还支持memcached。需要注意的是,持久化会降低gearman的处理速度,所以较好的方法是用memcached做持久化,当然持久化必须部署在不同的机器上,否则没有任何意义。不过memcached宕机了也什么都没有,如果对Job要求非常高,可以使用关系数据库,速度要稍微慢一些。

2、环境

     老式的平板,8核cpu,32G内存,CentOS 7

3、安装

     1)预先准备

     $ yum install gcc gcc-c++ php php-devel boost-devel libevent-devel gperf libuuid-devel   

     //安装mysql

     $ yum install mariadb-*

     //安装memcached

     $ wget http://www.memcached.org/files/memcached-1.4.25.tar.gz

     $  tar xvf memcached-1.4.25.tar.gz

     $ ./configure

     $ make

     $ make install

     //安装libmemcached

     $ wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz

     $  tar xvf libmemcached-1.0.18.tar.gz

     $ cd libmemcached-1.0.18

     $ ./configure

     $ make

     $ make install

     2)gearman

     $ wget https://launchpad.net/gearmand/1.2/1.1.12/+download/gearmand-1.1.12.tar.gz

     $  tar xvf gearmand-1.1.12.tar.gz

     $  cd gearmand-1.1.12

     $  ./configure

     $ make 

     $ make install

     要注意./configure的输出,按照上面的安装应该不会有什么问题,如果有,直接yum安装就可以了

     其输入最后是

   * CPP Flags:                  -fvisibility=hidden

   * LIBS:

   * LDFLAGS Flags:

   * Assertions enabled:        no

   * Debug enabled:             no

   * Warnings as failure:       no

   * Building with libsqlite3   no

   * Building with libdrizzle   yes

   * Building with libmemcached yes

   * Building with libpq        no

   * Building with tokyocabinet no

   * Building with libmysql     yes

   * SSL enabled:               no

   * cyassl found:              no

   * openssl found:             yes

   * make -j:                   3

   * VCS checkout:              no

   * sphinx-build:              :

   需要注意后面的yes或者no,可以看出目前是支持libmemcached, libmysql,意味着持久化策略可以选择memcached和mysql

   //安装php扩展

   $ wget http://pecl.php.net/get/gearman-1.1.2.tgz

   $ cd gearman-1.1.2

   $ phpize

   $ ./configure

   $ make && make install

   $ vim /etc/php.ini

   [gearman]

   extension=gearman.so

   $ systemctl restart php-fpm

4、使用

   1)启动job server

   $ gearmand -d

   2)命令

   $ gearman -w -f wc -- wc -l

    //-w 代表启动worker模式, -f 代表函数,这里的名称是wc, --代表对应的函数为wc -l

   $ gearman -f wc </etc/passwd

    // 代表请求wc函数,参数是/etc/passwd的内容

   这里会返回/etc/passwd的行数,在97上是49

   这个命令其实和wc -l < /etc/passwd是一样的

   3)PHP使用

       来一个简单的例子,照搬官方文档

        //worker.php

<?php

$worker= new GearmanWorker();

$worker->addServer();

$worker->addFunction("reverse", "my_reverse_function");

while ($worker->work());

function my_reverse_function($job){

  $result = strrev($job->workload());

  echo $result."\n";

  return strrev($result);

}

?>

//client.php

<?php

$client= new GearmanClient();

$client->addServer();

print $client->doNormal("reverse", "Hello World!");

print "\n";

?>

先运行worker.php,然后运行client.php,显示结果如下

$ php worker.php

!dlroW olleH

$ php client.php

Hello World!

代码很容易看懂,在http://php.net/manual/zh/book.gearman.php有非常详细的解释,只简单说一下

GearmanWorker有个addServer和addServers方法,可以增加本worker关联的job server,无参数时是127.0.0.1:4730,可以手工指定,增加多个,同样GearmanClient也是一样,有这样的两个方法,也是一样的参数。

GearmanClient有doNormal和doBackground方法,前者会有返回值,后者是后台执行的,返回的是job handle,可以通过这个查询job的执行状态 。原理上前者是因为执行时client一直和job server保持了连接,后者在将要执行的服务增加到job server之后就断开了,不等待结果。

      这都是每次执行一个任务的方法,还有批量执行的方法,如下

      addTask()

      addTaskBackground()

      runTask();

      可以增加很多task,然后一直执行,增加task的方法较多,主要是区分优先级,具体可以参考官方文档。

5、压力测试和持久化存储

     gearman的使用很简单,基本已经说完了,其他的查查文档就可以了。

     测试程序

     //client1.php

<?php

$start = microtime(true);

echo "starting...", $start , "\n";

$gmc = new GearmanClient();

$gmc->addServer("127.0.0.1", 4730);

for ($i = 0; $i < 100000; $i++) {

     $gmc->addTaskBackground("reserve", "just test it", null, $i);

}

$gmc->runTasks();

$end =  microtime(true);

echo "end...", $end, "\n";

echo $end-$start,"\n";

//worker1.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());

     1)无持久化

      $php worker1.php

      $php client1.php

      多次运行之后,可以看出提交10万个任务,大约需要1.2秒,即每秒8.5万次,还可以看出worker反应要慢一些,因为他要执行之后才会有返回。

    2)memcached持久化

       $ memcached -d -u root

       $ pkill gearmand

       $ gearmand -d -q libmemcached --libmemcached-servers=127.0.0.1:11211

       $ php worker1.php

       $ php client1.php

       多次运行之后,发现运行的很不稳定,从2秒到6秒都有,不过运行10次以上基本稳定在1.5秒到2秒之间,可以看出确实持久化会影响稳定性,对速度也有一定的影响。

   3)mysql持久化

       mysql> create database gearman;

       mysql> use gearman; 

       mysql> create table `gearman_queue` ( `unique_key` varchar(64) NOT NULL, `function_name` varchar(255) NOT NULL, `priority` int(11) NOT NULL, `data` LONGBLOB NOT NULL, `when_to_run` INT, PRIMARY KEY  (`unique_key`) );

       $ pkill gearmand

       $ gearmand -d -q MySQL --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=YoTs97 --mysql-db=gearman --mysql-table=gearman_queue --verbose=INFO

       $ php worker1.php

       $ php client1.php

       多次运行之后,发现时间在2.7-3秒之间,每秒3-4万条,不过不稳定,运行一段时间之后,时间在20秒上下,每秒只有5000条,相当的慢,如果在不是很繁忙的情况下,考虑到持久化带来的好处,可以考虑用mysql做持久化。

    需要注意一下,gearmand只是在启动时检查持久化存储中的队列,如果持久化存储问题了,gearmand不会重新连接,会直接报错,所以需要密切关注持久化存储的状态。

6、较好的部署方式

   job server最好进行持久化,较好的选择是另一台机器上的memcache,worker可以分布到不同的机器上,可以针对worker的繁重程度,启动多个worker,job Server会自动将请求分配到不同的worker上。为避免单点问题,可以启动多个job server,woker同时多个job server上注册,可以通过失败转移的方式,及时切换到另外的Job server上,如果还有性能问题,可以考虑互相隔离的job server或者启用消息队列来处理。

 

7、supervisor解决进程意外中断,自动重启的问题

     可以看出在这个场景中,worker、job server、和memcached以及mysql都可能会出现问题,但是其功能很单一,只要重启就可以解决问题,可以用supervisor来解决。

     supervisor是一个python程序,也有nodejs版的,nodejs版主要是为了解决nodejs单线程模型出现问题则整个服务就中断的问题,这里的应用比较简单,用supervisor足矣。

     $ yum install python-setuptools

     $ easy_install supervisor

     $ echo_supervisord_conf > /etc/supervisord.conf

     在/etc/supervisord.conf最后增加如下内容

[program:memcached]

command=memcached -u root

user=root

autostart=true

autorestart=true

startsecs=1

[program:gearmand]

command=gearmand

user=root

autostart=true

autorestart=true

startsecs=1

[program:worker]

command=php /data/html/worker.php

user=root

autostart=true

autorestart=true

startsecs=1

[program:worker1]

command=php /data/html/worker.php

user=root

autostart=true

autorestart=true

startsecs=1

 

$ supervisord

$ supervisorctl status

gearmand                         RUNNING   pid 14124, uptime 0:00:05

memcached                        RUNNING   pid 14126, uptime 0:00:05

worker                           RUNNING   pid 14123, uptime 0:00:05

worker1                          RUNNING   pid 14125, uptime 0:00:05

为了让supervisord开机启动,在/etc/rc.local增加一行

/usr/bin/supervisord

 

需要注意的是,supervisord无法监控守护进程,会出现错误。

8、监控gearman: 使用Gearman Monitor

     下载文件到web服务器根目录,解压,composer安装模块,具体如下

     $ wget https://github.com/yugene/Gearman-Monitor/archive/master.zip

     $ unzip master.zip

     $ mv Gearman-Monitor-master/ gmm

     $ cd gmm

     $ composer install 

     浏览器访问:http://172.16.8.97:800/gmm,可以看到worker,client,queue的信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值