主流NoSQL數(shù)據(jù)庫評測之HandlerSocket
NoSQL是伴隨著web2.0的迅猛發(fā)展而在2009年被提出的一個概念,一般可以通俗的理解為高性能的Key Value存儲結(jié)構(gòu)的數(shù)據(jù)庫,當(dāng)然也有其他更廣泛的類型。它基于CAP和BASE理論,強調(diào)最終一致性,具有數(shù)據(jù)結(jié)構(gòu)靈活、擴展方便、大數(shù)據(jù)量下讀寫性能高效等特點,在互聯(lián)網(wǎng)行業(yè)被廣泛采用。本系列文章將評測廣受關(guān)注的幾個NoSQL數(shù)據(jù)庫產(chǎn)品。本文關(guān)注的是HandlerSocket Plugin for MySQL。
HandlerSocket是日本DeNA公司的架構(gòu)師Yoshinori開發(fā)的一個NoSQL產(chǎn)品,以MySQL Plugin的形式運行。其主要的思路是在MySQL的體系架構(gòu)中繞開SQL解析這層,使得應(yīng)用程序直接和Innodb存儲引擎交互,通過合并寫入、協(xié)議簡單等手段提高了數(shù)據(jù)訪問的性能,在CPU密集型的應(yīng)用中這一優(yōu)勢尤其明顯。
另外,HandlerSocket還幫我們解決了緩存的問題,因為Innodb已經(jīng)有了成熟的解決方案,通過參數(shù)可以配置用于緩存數(shù)據(jù)的內(nèi)存大小,這樣只要我們分配合理的參數(shù),就能在應(yīng)用程序無需干涉的情況下實現(xiàn)熱點數(shù)據(jù)的緩存,降低緩存維護(hù)的開發(fā)成本。
因為HandlerSocket是MySQL的一個Plugin,集成在mysqld進(jìn)程中,對于NoSQL無法實現(xiàn)的復(fù)雜查詢等操作,仍然可以使用MySQL自身的關(guān)系型數(shù)據(jù)庫功能來實現(xiàn)。在運維層面,原來廣泛使用的MySQL主從復(fù)制等經(jīng)驗可以繼續(xù)發(fā)揮作用,相比其他或多或少存在一些bug的NoSQL產(chǎn)品,數(shù)據(jù)安全性更有保障。
可以說這是一個很有創(chuàng)意的產(chǎn)品,因此HandlerSocket的作者在2010年10月在博客上宣稱這一產(chǎn)品能達(dá)到75K QPS的時候,在業(yè)界引起了廣泛的關(guān)注,包括MySQL官方在新的5.6版本中推出的Memcached API,相信也是受了HandlerSocket的啟發(fā)。
測試說明:
一、測試環(huán)境
Handlersocket部署在一臺PC 服務(wù)器上,配置如下:
CPU為Xeon 2.80GHz *4
內(nèi)存為4G
硬盤為一塊400G SATA盤
操作系統(tǒng)為64位CentOS 5.3版本
二、測試方法
Handlersocket的客戶端幾乎涵蓋了各種語言,都實現(xiàn)了通過以上兩個端口對數(shù)據(jù)讀寫的操作,其中查詢操作必須通過建立有索引的列來進(jìn)行。
考慮到NoSQL在互聯(lián)網(wǎng)行業(yè)應(yīng)用較為廣泛,采用PHP實現(xiàn)客戶端程序的做法,通過一定的并發(fā)去讀寫數(shù)據(jù),觀測每秒讀寫的記錄數(shù)作為主要的衡量指標(biāo)。當(dāng)然也可以利用Java的多線程進(jìn)行并發(fā)測試,但由于篇幅和時間所限,本文不再涉及此方面的內(nèi)容。
這里采用第三方實現(xiàn)的一個PHP客戶端,網(wǎng)址為http://code.google.com/p/php-handlersocket/,可以編譯到PHP運行環(huán)境中。
為了不對測試服務(wù)器產(chǎn)生額外的影響,測試客戶端部署在另外一臺獨立的服務(wù)器上,運行的PHP的版本是5.3.5,web server是Nginx 0.8.54,通過fastcgi的方式調(diào)用PHP服務(wù)。使用apache ab工具實現(xiàn)多個請求和并發(fā)操作。
測試分為兩個步驟,首先是寫操作,通過500個請求,每個請求寫入10000條記錄,并發(fā)度為2來共寫入500萬條數(shù)據(jù),數(shù)據(jù)的key為數(shù)字1到5000000,value大小為100個字節(jié)。然后是讀操作,也是用500個請求,每個請求隨機根據(jù)key值讀出10000條記錄,并發(fā)度為10共讀出500萬條記錄,評測的重點是寫入和讀出數(shù)據(jù)的時間,以及在此過程中服務(wù)器的資源使用情況。
MySQL 數(shù)據(jù)庫安裝:
一、安裝MySQL
通過編譯源碼的方式安裝MySQL,這里選擇的版本是5.5.8版本。由于這不是本文的重點,這里只簡單的提及一下要點。
首先到MySQL的官網(wǎng)http://dev.mysql.com/downloads/mysql/下載源碼,要注意的是從MySQL 5.5版本開始需要Cmake編譯工具和bison。然后開始安裝:
安裝完成后配置my.cnf文件,最重要的參數(shù)是分配給innodb存儲引擎的內(nèi)存大小,也就是innodb_buffer_pool_size參數(shù),這里設(shè)置為2G。
- [root@localhost mysql558]# vi my.cnf
- ……
- innodb_buffer_pool_size = 2G
- ……
二、安裝HandlerSocket
首先到以下地址下載代碼:
https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL
開始安裝HandlerSocket:
- [root@localhost handlersocket]# tar -zxvf ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-67-g25f4957.tar.gz
- [root@localhost handlersocket]# cd handlersocket/
- [root@localhost handlersocket]# ./autogen.sh
- [root@localhost handlersocket]# ./configure --with-mysql-source=/home/handlersocket/mysql-5.5.8 --with-mysql-bindir=/home/handlersocket/mysql558/bin --with-mysql-plugindir=/home/handlersocket/mysql558/lib/plugin
- [root@localhost handlersocket]# make
- [root@localhost handlersocket]# make install
三、修改MySQL配置
在my.cnf配置文件增加以下內(nèi)容:
- [root@localhost mysql558]# vi my.cnf
- [mysqld]
- ......
- 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 = 16
- # 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.
這里增加的這些主要是針對handlersocket的配置,它有2個端口,9998用來讀數(shù)據(jù),9999讀寫均可,但是通過9998來讀的效率更高。這里我們設(shè)置處理讀寫的線程數(shù)均為16個,另外為了處理更多的并發(fā)連接,設(shè)置能打開的文件描述符個數(shù)為65535。
四、安裝MySQL授權(quán)表并啟動數(shù)據(jù)庫:
- [root@localhost mysql558]# scripts/mysql_install_db --user=mysql
- [root@localhost mysql558]# bin/mysqld_safe --user=mysql &
五、登錄MySQL安裝HandlerSocket Plugin:
- [root@localhost mysql558]# bin/mysql -u root -p
- mysql> install plugin handlersocket soname 'handlersocket.so';
- Query OK, 0 rows affected (0.01 sec)
通過以下命令查看也可見handlersocket已經(jīng)成功安裝到MySQL中:
- mysql> show processlist;
- mysql> show plugins;
測試結(jié)果:
一、寫操作
成功寫入500萬條記錄,共耗時4300秒,平均每秒寫入數(shù)據(jù)1163筆。
寫入過程中,服務(wù)器比較穩(wěn)定,CPU使用率平穩(wěn),Idle值穩(wěn)定在70到72之間,等待時間穩(wěn)定在14到19之間。內(nèi)存分配上的變化較大,free部分從1.3G下降到25M,buffer部分從630M下降到65M,cache部分從1.5G上升到2.9G,虛擬內(nèi)存從0上升到376K,但是沒有交換區(qū)到內(nèi)存的換入換出。磁盤IO表現(xiàn)平穩(wěn),每秒寫入的塊數(shù)穩(wěn)定在10000到12000之間。
二、讀操作
成功讀出500萬條記錄,共耗時193秒,平均每秒讀出數(shù)據(jù)25906筆。
讀數(shù)據(jù)過程中沒有發(fā)生磁盤IO。CPU較繁忙,Idle在39到51之間,等待CPU資源的進(jìn)程一直在1到6個之間。內(nèi)存表現(xiàn)平穩(wěn)沒有波動。
通過以上測試結(jié)果可以說明,寫入的數(shù)據(jù)完全緩存到了文件系統(tǒng)中,所以cache部分占用的內(nèi)存大量增加,這也是讀取數(shù)據(jù)的時候沒有發(fā)生磁盤IO的原因。
總結(jié):
要說明的是,雖然這是一份真實的測試數(shù)據(jù),但是并不一定具有普遍意義。因為應(yīng)用場景是千差萬別的,服務(wù)器的資源配置、數(shù)據(jù)記錄的多少、單條數(shù)據(jù)的大小、讀寫的比例、客戶端程序的質(zhì)量等因素都會影響測試結(jié)果,甚至差別會非常大,對我們來說,更重要的是了解這個NoSQL產(chǎn)品的特性,知道它的適用場景,并且能夠根據(jù)自己實際的應(yīng)用場景針對性的進(jìn)行測試,這樣才能做到針對性的選型,只有最適合自己需求的產(chǎn)品才是最好的產(chǎn)品。
【編輯推薦】
- 數(shù)據(jù)庫日常維護(hù)常用的腳本部分收錄
- SQL與NoSQL——MySQL與NoSQL的融合
- MySQL中的NoSQL插件
- HandlerSocket是神馬
- 微軟WP7本地數(shù)據(jù)庫之Sterling編程技巧