环境:gearman简介:         Gearman是一个支持分布式的任务分发框架。设计简洁,获得了非常广泛的支持。一个典型的Gearman应用包括以下这些部分:     Gearman Job Server:Gearman核心程序,以守护进程形式运行在后台    Gearman Client:可以理解为任务的收件员,比如我要在后台执行一个发送邮件的任务,可以在程序中调用一个Gearman Client并传入邮件的信息,然后就可以将执行结果立即展示给用户,而任务本身会慢慢在后台运行。    Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。   了 lib_mysqludf_json和 gearman-mysql-udf的组合实现 )在mysql中的数据发生改变时触动触发器将数据传入Gearman中,这时的mysql相当于Gearman的clinet。然后运行自己编写的php程序作为worker,将Gearman中的数据传到Redis中去,这时的Redis相当于是Gearman的consumer。1、安装gearman      实验中的系统yum源在centos6.5自带的网络yum源的基础上,增加了epel的源,EPEL (Extra Packages for Enterprise Linux,企业版Linux的额外软件包) 是Fedora小组维护的一个软件仓库项目,为RHEL/CentOS提供他们默认不提供的软件包。使用这个源可以免去很多麻烦,省去源码编译的麻烦,需要注意的是,不论是使用centos自带的网络yum源还是epel扩展源,都需要你的IP能够访问到公网。     安装gearman、php、php的gearman扩展、nc工具 yum install -y php-pecl-gearman libgearman  libgearman-devel gearmand nc    启动gearman服务 /etc/init.d/gearmand start    验证gearman是否成功启动,如果返回的结果中有4730端口,那么表示服务已经正常启动了 [root@hadoop1 ~]# netstat -alnutp |grep gearman2、模拟Gearman的工作原理:     使用下列命令查看Gearman的队列 watch -n 1 "(echo status; sleep 0.1) | nc 127.0.0.1 4730"     结果如下writeLog    0     0     0<?php
  $client = new GearmanClient();
  $client->addServer();
  $client->doBackground('writeLog', 'Log content');
  echo '文件已经在后台操作';
  echo "\n";php client.phpwriteLog    1     0     0<?php
  $worker = new GearmanWorker();
  $worker->addServer();
  $worker->addFunction('writeLog', 'writeLog');
  while($worker->work());
  function writeLog($job)
  {
    $log = $job->workload();
    file_put_contents(__DIR__ . '/gearman.log', $log . "\n", FILE_APPEND | LOCK_EX);
  }nohup php worker.php &writeLog    0     0     1[root@hadoop1 ~]# cat gearman.log 
Log contentyum install -y mysql-server mysql php-mysql/etc/init.d/mysql startlib_mysqludf_json wget  https://github.com/mysqludf/lib_mysqludf_json/archive/master.zip
mv master master.zip
unzip master.zip
cd lib_mysqludf_json-master
rm -rf lib_mysqludf_json.so 
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c[root@hadoop1 ~]# mysql -u root -pupbjsxt --execute="show variables like '%plugin%';"  
+---------------+--------------------------+
| Variable_name | Value          |
+---------------+--------------------------+
| plugin_dir  | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+[root@hadoop1 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/gearman-mysql-udf wget https://launchpad.net/gearman-mysql-udf/trunk/0.6/+download/gearman-mysql-udf-0.6.tar.gz   
tar xf gearman-mysql-udf-0.6.tar.gz -C ./
cd gearman-mysql-udf-0.6
./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/
make && make install[root@hadoop1 ~]# mysql -u root -p****** 
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so'
## 为javashop中的test表建立触发器
mysql> use javashop;
mysql> describe test;
+-------+----------+------+-----+---------+-------+
| Field | Type   | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id  | int(11)  | YES  |   | NULL  |     |
| name  | char(20) | YES  |   | NULL  |     |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> source trigger.sql
## 设置gearman server信息
mysql>SELECT gman_servers_set('127.0.0.1:4730');DELIMITER $$
CREATE TRIGGER datatoredis AFTER UPDATE ON test  FOR EACH ROW BEGIN
  SET @ret=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`)); 
  END$$
DELIMITER ;mysql> update test set name='redis' where id=10;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0writeLog    0     0     1
syncToRedis   1     0     0yum install php-pecl-redis redis -y/etc/init.d/redis   start[root@hadoop1 ~]# redis-cli 
redis 127.0.0.1:6379> keys *
(empty list or set)<?php
  $worker = new GearmanWorker();
  $worker->addServer();
  $worker->addFunction('syncToRedis', 'syncToRedis');
  $redis = new Redis();
  $redis->connect('127.0.0.1');
  while($worker->work());
  function syncToRedis($job)
  {
    global $redis;
    $workString = $job->workload();
    $work = json_decode($workString);
    if(!isset($work->id)){
        return false;
    }
    $redis->set($work->id, $workString);
  }nohup php redis_worker.php &writeLog    0     0     1
syncToRedis   0     0     1[root@hadoop1 ~]# redis-cli 
redis 127.0.0.1:6379> keys *
1) "10"
redis 127.0.0.1:6379> get 10
"{"id":10,"name":"redis"}"<?php  
  $stime=microtime(true); //获取程序开始执行的时间  
  $redis = new Redis(); 
  $redis->connect('127.0.0.1'); 
  echo $redis->get('10');  
  echo "\n";
  $redis->close(); 
  $etime=microtime(true);//获取程序执行结束的时间  
  $total=$etime-$stime;   //计算差值  
  echo "$total".'秒';  
  echo "\n";
?><?php
  $stime=microtime(true); //获取程序开始执行的时间  
  $con = mysql_connect("127.0.0.1","root","******");
  $r2 = mysql_select_db("javashop");
  $result = mysql_query("SELECT * FROM test limit 1");
  while ($row = mysql_fetch_array($result)) {
    echo $row['id'] . " --> " . $row['name'];
    echo "\n";
  }
  mysql_close($con);
  $etime=microtime(true);//获取程序执行结束的时间  
  $total=$etime-$stime;   //计算差值  
  echo "$total".'秒';  
  echo "\n"
?>[root@hadoop1 ~]# php php_redis.php 
{"id":10,"name":"redis"}
0.00059199333190918秒
[root@hadoop1 ~]# php php_mysql.php 
10 --> redis
0.0043718814849854秒
[root@hadoop1 ~]# bc <<< 0.0043718814849854/0.00059199333190918
7echo  "SELECT gman_servers_set('127.0.0.1:4730');" > /var/lib/mysql/init_file.sqlinit-file=/var/lib/mysql/init_file.sql