HandlerSocket是日本人akira higuchi 寫的一個MySql的插件。通過這個插件,你可以直接跟MySQL後端的存儲引擎做key-value式的交互,省去了MySQL上層的SQL解釋、打開關閉表、創建查詢計劃等CPU開銷。按照作者給出的數據可以在數據全部在內存的情況下可以達到75W的QPS查詢。
適用場景:
Innodb引擎、按主鍵、unique key或索引搜索也就是說它的SQL的where條件必須是這些);支持limit 語句、IN、INSERT/UPDATE/DELETE。
閒話少說,直接上安裝和測試結果。
安裝:
需要為MySQL安裝插件、PHP安裝擴展。這裡就不再贅述,可以參考此篇文章http://blog.1984fox.com/read.php?30#entrymore,很詳細。
API:
谷歌codehttp://code.google.com/p/php-handlersocket/)中提供了PHP擴展作者的API,這裡我將每個方法的參數具體說明一下也可以去https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/blob/master/docs-en/perl-client.en.txt參考一下perl擴展的API說明,其實實現都是一樣的,只不過是不同語言):
實例化:
- /*
- * 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);
測試:
新建一個1000w條數據的用戶表,id為主鍵,包括uname、email、add_time字段,使用兩台不同的機器做ab壓力測試:
讀測試:
並發50,5000次壓力測試:
MySQL: min: 0.504740953445 max:13.1727859974 average: 1.05 CPU:0.7%us, 0.3%sy use:111s
HandlerSocket:min: 0.302443981171 max:9.37712621689 average:0.736 CPU:0.4%us, 0.3%sy use:77s
並發70,5000次壓力測試:
MySQL: min: 0.504750013351 max:10.4482009411 average: 1.094 CPU:0.9%us, 0.4%sy use:85s
HandlerSocket:min: 0.302488803864 max:10.3345310688 average: 0.788 CPU:0.5%us, 0.4%sy use:62s
並發110,5000次壓力測試:
MySQL: min:0.505280017853 max:21.3242678642 average:1.095 CPU:1.5%us, 0.7%sy use:55s
HandlerSocket:min: 0.30281996727 max:10.6022770405 average:0.786 CPU:1.1%us, 0.7%sy use:39s
並發150,5000次壓力測試:
MySQL: min: 0.505041122437 max:28.8087069988 average:1.073 CPU:1.8%us, 0.9%sy use:61s
HandlerSocket:min: 0.302739143372 max:12.878344059 average:0.774 CPU:1.0%us, 0.9%sy use:30s
總結:
共同點:並發越高,性能越好
hs系統占用和執行時間都少於MySQL 性能約好30%~40%
寫測試:
並發50,5000次壓力測試:
MySQL: min: 0.507106781006 max: 4.95259904861 average: 0.594 CPU:0.76%us, 0.49%sy use:62s
HandlerSocket:min: 0.303457021713 max: 7.0854101181 average: 0.383 CPU:0.4%us, 0.2%sy use:43s
並發70,5000次壓力測試:
MySQL: min: 0.508066892624 max: 12.8451189995 average: 0.659 CPU:1.0%us, 0.6%sy use:51s
HandlerSocket:min: 0.30427312851 max: 12.4244120121 average: 0.417 CPU:0.53%us, 0.29%sy use:32s
並發90,5000次壓力測試:
MySQL: min: 0.507676839828 max: 12.8466610909 average: 0.689 CPU:1.3%us, 0.72%sy use:45s
HandlerSocket:min: 0.304312229156 max: 12.4680581093 average: 0.465 CPU:0.66%us, 0.38%sy use:29s
並發110,5000次壓力測試:
MySQL: min: 0.507092952728 max: 11.7785778046 average: 0.775 CPU:1.34%us, 0.82%sy use:45s 13條未寫入)
HandlerSocket:min: 0.219769954681 max: 12.6269509792 average: 0.556 CPU:0.63%us, 0.37%sy use:32s 15條未寫入)
並發150,5000次壓力測試:
MySQL: min: 0.507570981979 max: 13.4538660049 average: 0.75 CPU:1.9%us, 1.1%sy use:29s 寫多1條)
HandlerSocket:min: 0.304651975632 max: 16.3402500153 average: 0.555 CPU:0.7%us, 0.43%sy use:26s 8條未寫入)
總結:
共同點:並發越高,性能越好
hs系統占用和執行時間都少於MySQL 性能約好50%~60%
測試結果確實比較明顯,HandlerSocket可以在高並發、簡單表操作的環境下替代MySQL。