前段时间偶然的机会了解到Handlersocket,并在自己的一个demo中得以应用,在此做下总结。
一、HandlerSocket是什么?
HandlerSocket是akira higuchi 写的一个MySql的插件。以MySQL Daemon Plugin的形式提供类似NoSQL的网络服务,通过这个插件,你可以直接跟MySQL后端的存储引擎做key-value式的交互,省去了MySQL上层的SQL解释、打开关闭表、创建查询计划等CPU开销。
二、安装配置
1. 安装
由于HandlerSocket是基于MySQL数据库的,因此在安装HanderSocket前需要先按照常规方式部署MySQL服务,同时需注意HandlerSocket时需要MySQL的源码,因此还需要MySQL源码编译方式安装。
# tar xvfz HandlerSocket-Plugin-for-MySQL-Master.tar.gz # cd HandlerSocket-Plugin-for-MySQL-Master/ # ./autogen.sh # ./configure --with-mysql-source=/data/software/mysql-5.5.12 \ --with-mysql-bindir=/usr/local/mysql55/bin \ --with-mysql-plugindir=/usr/local/mysql55/lib/plugin
其中:
--with-mysql-source:指定MySQL源码所在目录
--with-mysql-bindir:指定mysql_config所在目录
--with-mysql-plugindir:指定MySQL插件的存储路径
执行make编译安装:
#make && make install
完成后,mysql-plugindir目录下应有handlersocket相关文件
2. 配置
#*********** HandlerSocket setting *********** loose_handlersocket_port = 9998 # the port number to bind to (for read requests) loose_handlersocket_port_wr = 9999 # the port number to bind to (for write requests) loose_handlersocket_threads = 16 # the number of worker threads (for read requests) loose_handlersocket_threads_wr = 1 # the number of worker threads (for write requests) open_files_limit = 65535 # to allow handlersocket accept many concurrent # connections, make open_files_limit as large as # possible.
启动MySQL服务,在MySQL中安装HandlerSocket插件:
mysql> install plugin handlersocket soname ¨handlersocket.so¨; Query OK, 0 rows affected (0.01 sec)
至此,HandlerSocket插件安装完毕。
三、PHP应用
<?php $host = 'localhost'; $port = 9998; $port_wr = 9999; $dbname = 'hstestdb'; $table = 'hstesttbl'; //GET $hs = new HandlerSocket($host, $port); if (!($hs->openIndex(1, $dbname, $table, HandlerSocket::PRIMARY, 'k,v'))) { echo $hs->getError(), PHP_EOL; die(); } $retval = $hs->executeSingle(1, '=', array('k1'), 1, 0); var_dump($retval); $retval = $hs->executeMulti( array(array(1, '=', array('k1'), 1, 0), array(1, '=', array('k2'), 1, 0))); var_dump($retval); unset($hs); //UPDATE $hs = new HandlerSocket($host, $port_wr); if (!($hs->openIndex(2, $dbname, $table, '', 'v'))) { echo $hs->getError(), PHP_EOL; die(); } if ($hs->executeUpdate(2, '=', array('k1'), array('V1'), 1, 0) === false) { echo $hs->getError(), PHP_EOL; die(); } unset($hs); //INSERT $hs = new HandlerSocket($host, $port_wr); if (!($hs->openIndex(3, $dbname, $table, '', 'k,v'))) { echo $hs->getError(), PHP_EOL; die(); } if ($hs->executeInsert(3, array('k2', 'v2')) === false) { echo $hs->getError(), PHP_EOL; } if ($hs->executeInsert(3, array('k3', 'v3')) === false) { echo 'A', $hs->getError(), PHP_EOL; } if ($hs->executeInsert(3, array('k4', 'v4')) === false) { echo 'B', $hs->getError(), PHP_EOL; } unset($hs); //DELETE $hs = new HandlerSocket($host, $port_wr); if (!($hs->openIndex(4, $dbname, $table, '', ''))) { echo $hs->getError(), PHP_EOL; die(); } if ($hs->executeDelete(4, '=', array('k2')) === false) { echo $hs->getError(), PHP_EOL; die(); }
HandlerSocket的缺陷:
(1)写操作并没有淘汰查询缓存——如果执行了写操作通过HandlerSocket,由于没有失效查询缓存, 那么你可能从MySQL读到旧的数据;
(2)不支持自动递增——插入时无法从自增列上自动获得增量值。
鉴于以上问题,扬长避短,使用其合并查询操作,发挥其NoSQL性能获取MySQL的InnoDB类型表数据,具体操作如下:
<?php // 通过handlersocket获取数据 $hs = new HandlerSocket(HS_HOST, HS_PORT); if (!($hs->openIndex(1, 'database', 'table', HandlerSocket::PRIMARY, 'id,content,create_uid,create_user,created,state'))){ echo $hs->getError(), PHP_EOL; die(); } $dataList = array(); foreach ($ids as $id) { $dataList[] = array(1, "=", array($id)); } $data = $hs->executeMulti($dataList);
参考文档:
https://code.google.com/p/php-handlersocket/
http://www.5ienet.com/note/html/handlersocket/mysql_nosql_handlersocket_configure.shtml