异步 mysql 客户端:async-mysql-php

jopen 9年前

PHP异步并发访问mysql简单实现。

在实际的开发过程中,我们常常会遇到需要操作多张表,多个库的情况。有时因为一些限制我们不能进行连表(例如,异地数据库),所以只能用php串行访问后再在php里进行合并,有时还需要模拟mysql对合并后的结果进行排序、归并等。

这里产生的一个问题就是串行带来的访问时间问题。由于传统的串行访问方式,我们只能等到一条sql执行完毕后才可以执行下一条,所以执行时间是累加的。PHP官方手册提供了一种可以异步并发访问mysql的方式,详见:http://php.net/manual/zh/mysqli.poll.php,参考资料:https://svn.osgeo.org/mapguide/sandbox/rfc94/Oem/php/ext/mysqli/tests/mysqli_poll.phpt,使用此种方式,我们可以对Mysql进行异步并发访问,访问时间不再是串行累加,而是取决于执行时间最长的sql。

项目地址:https://github.com/huyanping/async-mysql-php

代码示例:

try{                     $async_mysql=new\Jenner\Mysql\Async();                   $async_mysql->attach(                ['host'=>'127.0.0.1','user'=>'root','password'=>'','database'=>'test'],               'select * from stu'             );              $async_mysql->attach(              ['host'=>'127.0.0.1','user'=>'root','password'=>'','database'=>'test'],             'select * from stu limit 0, 3'          );            $result=$async_mysql->execute();            print_r($result);        }catch(Exception$e){                echo$e->getMessage();             }

async_mysql对象对mysql进行异步并发访问,attach方法接收每个请求必须的配置信息,execute方法为执行入口,其返回值是每条sql执行结果的数组,顺序与attach调用顺序一致。

当任何一个连接mysql出错或执行任何一条sql出错,都会引起异常抛出。这样设计主要是基于完整性的考虑,我们把所有需要执行的sql看做是一个整体事务,任何一个执行失败,则认为该事务失败。

composer信息:

"require":{             "jenner/async-mysql-php":"v0.1"         }

或者直接引入/path/to/async-mysql-php/autoload.php文件

最后在阿里云上做了一个简单的测试,测试结果如下:

# 同步           [root@iZ942077c78Z async-mysql-php]# php tests/performance_sync.php         ------------------------------------------             mark:[totaldiff]            time:4.2648551464081s  memory_real:18944KB  memory_emalloc:18377.171875KB  memory_peak_real:28416KB  memory_peak_emalloc:27560.3828125KB  [root@iZ942077c78Z async-mysql-php]# php tests/performance_sync.php  ------------------------------------------  mark:[totaldiff]  time:4.2285549640656s  memory_real:18944KB  memory_emalloc:18377.171875KB  memory_peak_real:28416KB  memory_peak_emalloc:27560.3828125KB  [root@iZ942077c78Z async-mysql-php]# php tests/performance_async.php   ------------------------------------------  mark:[totaldiff]  time:1.455677986145s  memory_real:38144KB  memory_emalloc:32574.015625KB  memory_peak_real:66816KB  memory_peak_emalloc:65709.7734375KB  # 异步  [root@iZ942077c78Z async-mysql-php]# php tests/performance_async.php  ------------------------------------------  mark:[totaldiff]  time:1.8936941623688s  memory_real:38144KB  memory_emalloc:32574.015625KB  memory_peak_real:66816KB  memory_peak_emalloc:65709.7734375KB  [root@iZ942077c78Z async-mysql-php]# php tests/performance_async.php  ------------------------------------------  mark:[totaldiff]  time:1.5208158493042s  memory_real:38144KB  memory_emalloc:32574.015625KB  memory_peak_real:66816KB  memory_peak_emalloc:65709.7734375KB

实际上以上测试结果并没有太大意义。因为理论上这种异步并发的访问方式会绝对优于传统的串行访问方式,再次需要说明的是,访问数据库的时间接近执行时间最长的SQL。

到了这一步,我们已经可以实现对mysql进行异步并发访问了。如果我们还需要做多个数组的归并,可以使用《PHP模拟SQL的GROUP BY算法》中介绍的方法。其中提供的归并方式非常灵活,更胜mysql原生的group by。

如果还需要对合并后的结果做排序,可以使用https://github.com/huyanping/Zebra-Tools/blob/master/src/Jenner/Zebra/Tools/CommonArray.php#L90这段代码实现,非常方便。改函数来源于php手册http://php.net/manual/zh/function.array-multisort.php

原文地址:PHP异步并发访问mysql简单实现


项目主页:
http://www.open-open.com/lib/view/home/1438524981579