HandlerSocket 是MySQL的一個插件,用于跳過MySQL的SQL層面,直接訪問內部的InnoDB存儲引擎,下面我們來看看MySQL HandlerSocket 插件安裝配置詳解.
系統信息約定:
系統版本:CentOS 6.3 X86
php安裝目錄:/usr/local/webserver/php5318
MySQL安裝目錄:/usr/local/webserver/mysql5520
HandlerSocket安裝路徑:/usr/local/webserver/handlersocket
安裝配置HandlerSocket
安裝之前建議你先安裝相關支持及需要的組件包:yum install gcc gcc-c++ libtool make openssl-devel perl-DBI perl-DBD-MySQL(如果為64bit OS注意perl-DBD-MySQL.x86_64).
yum install rpm-build gperf readline-devel ncurses-devel time perl-Time-HiRes
安裝:如果使用Percona Server版本的MySQL就簡單了,因為它已經內置了HandlerSocket支持,不過考慮到其內置的版本不夠新,存在一些早已修復的BUG,所以最好采用源代碼編譯,HandlerSocket是基于MySQL數據庫的,因此在安裝HanderSocket前需要先按照常規方式部署MySQL服務,同時需注意HandlerSocket時需要MySQL的源碼,因此還需要MySQL源碼編譯方式安裝.
- [root@iredmail opt]# git clone https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL.git --Vevb.com
- [root@iredmail opt]# cd HandlerSocket-Plugin-for-MySQL
- [root@iredmail HandlerSocket-Plugin-for-MySQL]# ./autogen.sh
- [root@iredmail HandlerSocket-Plugin-for-MySQL]#./configure --prefix=/usr/local/webserver/handlersocket --with-mysql-source=/opt/mysql-5.5.20 --with-mysql-bindir=/usr/local/webserver/mysql5520/bin --with-mysql-plugindir=/usr/local/webserver/mysql5520/lib/mysql/plugin
Tips:
--with-mysql-source 指定MySQL源碼所在目錄
--with-mysql-bindir 表示MySQL二進制可執行文件目錄
--with-mysql-plugindir 指定MySQL插件的存儲路徑,如果不清楚這個目錄在哪,可以按如下方法查詢:
- mysql> show variables like 'plugin%';
- +---------------+-------------------------------------------+
- | Variable_name | Value |
- +---------------+-------------------------------------------+
- | plugin_dir | /usr/local/webserver/mysql5520/lib/plugin |
- +---------------+-------------------------------------------+
- 1 row in set (0.00 sec) --Vevb.com
- [root@iredmail HandlerSocket-Plugin-for-MySQL]# make
常見錯誤:
- libtool: link: only absolute run-paths are allowed
- make[2]: *** [handlersocket.la] Error 1
- make[2]: Leaving directory `/opt/HandlerSocket-Plugin-for-MySQL/handlersocket'
- make[1]: *** [all-recursive] Error 1
- make[1]: Leaving directory `/opt/HandlerSocket-Plugin-for-MySQL'
- make: *** [all] Error 2
解決方法:
- [root@iredmail HandlerSocket-Plugin-for-MySQL]# vi handlersocket/Makefile
- line 301:
- $(handlersocket_la_LINK) -rpath $(pkgplugindir) $(handlersocket_la_OBJECTS) $(handlersocket_la_LIBADD) $(LIBS)
- -->
- $(handlersocket_la_LINK) -rpath /opt/HandlerSocket-Plugin-for-MySQL/handlersocket $( handlersocket_la_OBJECTS) $(handlersocket_la_LIBADD) $(LIBS)
- [root@iredmail HandlerSocket-Plugin-for-MySQL]#make install
完成后,mysql-plugindir目錄下應有handlersocket相關文件.
配置MySQL,修改my.cnf配置文件:
- [root@iredmail HandlerSocket-Plugin-for-MySQL]# vi /etc/my.cnf
- [mysqld]
- plugin-load=handlersocket.so(plugin-load可略過不配)
- 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 concurren connections, make open_files_limit as large as possible.
Tips:InnoDB的innodb_buffer_pool_size,或MyISAM的key_buffy_size等關系到緩存索引的選項盡可能設置大一些,這樣才能發揮HandlerSocket的潛力.
登陸MySQL并激活HandlerSocket插件:
- [root@iredmail HandlerSocket-Plugin-for-MySQL]# mysql -uroot -p
- mysql> install plugin handlersocket soname 'handlersocket.so';
- ERROR 1126 (HY000): Can't open shared library '/usr/local/webserver/mysql5520/lib/plugin/handlersocket.so' (errno: 2 cannot open shared object file: No such file or directory)
說明:這里提示沒有找到handlersocket.so擴展文件,請查看擴展文件是否存在.
- mysql> install plugin handlersocket soname 'handlersocket.so';
- Query OK, 0 rows affected (0.00 sec)
- mysql> quit;
至此,HandlerSocket插件安裝完畢.
重啟mysql服務:
[root@iredmail HandlerSocket-Plugin-for-MySQL]# service mysqld restart
HandlerSocket狀態測試
也可以通過查詢剛配置的端口是否已經被MySQL占用來確認是否安裝成功:
- [root@iredmail HandlerSocket-Plugin-for-MySQL]# lsof -i -P | grep mysqld --Vevb.com
- mysqld 26871 mysql 11u IPv4 72467 0t0 TCP *:9998 (LISTEN)
- mysqld 26871 mysql 29u IPv4 72469 0t0 TCP *:9999 (LISTEN)
- mysqld 26871 mysql 31u IPv4 72474 0t0 TCP *:3306 (LISTEN)
- Tips:If ports 9998 and 9999 don’t show up. Make sure SELinux is not running.
安裝配置 php-handlersocket 擴展模塊,安裝php-handlersocket擴展:
- [root@iredmail opt]# wget http://php-handlersocket.googlecode.com/files/php-handlersocket-0.3.1.tar.gz
- [root@iredmail opt]# tar -zxvf php-handlersocket-0.3.1.tar.gz
- [root@iredmail opt]# cd handlersocket/
- [root@iredmail handlersocket]# /usr/local/webserver/php5318/bin/phpize
- [root@iredmail handlersocket]# ./configure --with-php-config=/usr/local/webserver/php5318/bin/php-config
- ./configure可加參數:
- implemented configure options source file
- hsclient none (default) handlersocket.cc
- native --disable-handlersocket-hsclient handlersocet.c
- Tips:If you get an error:
- configure: error: Can't find hsclient headers,please install libhsclient first,Or ./configure--disable-handlersocket-hsclient --with-php-config=/usr/local/webserver/php5318/bin/php-config use native type.
- [root@iredmail handlersocket]#make && make install
- A successful install will have created handlersocket.so and put it into the PHP extensions directory. You'll need to and adjust php.ini and add an extension=handlersocket.so line before you can use the extension.
- [root@iredmail handlersocket]# vi /usr/local/webserver/php5318/etc/php.ini
- extension=handlersocket.so
至此php擴展安裝完成,放問php.info頁面,我們可以看到已經成功加載了handlersocket擴展.
php-handlersocket 使用示例
- <?php
- /*
- * String $host:MySQL ip;
- * String $port:handlersocket插件的監聽端口,它有兩個端口可選:一個用于讀、一個用于寫
- */
- $hs = new HandlerSocket($host, $port);
- 打開一個數據表:
- /*
- * Int $index:這個數字相當于文件操作里的句柄,HandlerSocket的所有其他方法都會依據這個數字來操作由這個 openIndex打開的表,
- * String $dbname:庫名
- * String $table:表名
- * String $key:表的“主鍵”(HandlerSocket::PRIMARY)或“索引名”作為搜索關鍵字段,這就是說表必須有主鍵或索引
- * 個人理解:要被當做where條件的key字段,這樣可以認為handlersocket只有一個where條件
- * String $column:'column1,column2' 所打開表的字段(以逗號隔開),就是說$table表的其他字段不會被操作
- */
- $hs->openIndex($index, $dbname, $table, $key, $column);
- 查詢:
- /*
- * Int $index: openIndex()所用的$index
- * String $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '< =', '>',and '< ';可以理解為where條件
- * Array $value
- * Int $number(默認是1):獲取結果的最大條數;相當于SQL中limit的第二個參數
- * Int $skip(默認是0):跳過去幾條;相當于SQL中limit的第一個參數
- */
- $retval = $hs->executeSingle($index, $operation, $value, $number, $skip);
- 插入(注意:此處的openIndex要用$port_wr,即讀寫端口):
- /*
- * Int $index: openIndex()所用的$index
- * Array $arr:數字元素數與openIndex的$column相同
- */
- $retval = $hs->executeInsert($index, $arr);
- 刪除(注意:此處的openIndex要用$port_wr,即讀寫端口):
- /*
- * Int $index: openIndex()所用的$index
- * String $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '< =', '>',and '< ';可以理解為where條件
- * Array $value
- * Int $number(默認是1):獲取結果的最大條數;相當于SQL中limit的第二個參數
- * Int $skip(默認是0):跳過去幾條;相當于SQL中limit的第一個參數
- */
- $retval = $hs->executeDelete($index, $operation, $value, $number, $skip);
- 更新(注意:此處的openIndex要用$port_wr,即讀寫端口):
- /*
- * Int $index: openIndex()所用的$index
- * String $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '< =', '>',and '< ';可以理解為where條件
- * Array $value
- * Int $number(默認是1):獲取結果的最大條數;相當于SQL中limit的第二個參數
- * Int $skip(默認是0):跳過去幾條;相當于SQL中limit的第一個參數
- */
- $retval = $hs->executeUpdate($index, $operation, $value, $number, $skip);
- Example:
- 測試庫 hstestdb,測試表hstesttbl:
- CREATE TABLE `hstesttbl` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `k` char(6) DEFAULT NULL,
- `v` char(6) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `idx_hstesttbl_k` (`k`)
- ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
- PHP test Code:
- $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();
- }
- ?>
Tips:理論上HandlerSocket支持MyISAM,InnoDB等各種引擎,不過推薦使用InnoDB。
Tips:To avoid the insert error,Please remember set storage engine:InnoDB.
Tips:對HandlerSocket一個常見的誤解是只能執行PRIMARY類型的KV查詢,實際上只要支持索引,一般的簡單查詢它都能勝任,這里就不多說了,官方文檔里有介紹.
HandlerSocket的缺陷:
1)寫操作并沒有淘汰查詢緩存——如果執行了寫操作通過HandlerSocket,由于沒有失效查詢緩存,那么你可能從MySQL讀到舊的數據.
2)不支持自動遞增——插入時無法從自增列上自動獲得增量值.
鑒于以上問題,揚長避短,使用其合并查詢操作,發揮其NoSQL性能獲取MySQL的InnoDB類型表數據.
寫在最后的:MySQL5.6提供原生的Memcached API,實際就是KV型NoSQL了,但HandlerSocket并不局限于KV形式,所以仍然有生存空間.
新聞熱點
疑難解答