MySQL下的NoSQL解決方案HandlerSocket
來源:易賢網(wǎng) 閱讀:682 次 日期:2015-03-05 14:05:29
溫馨提示:易賢網(wǎng)小編為您整理了“MySQL下的NoSQL解決方案HandlerSocket”,方便廣大網(wǎng)友查閱!

目前使用MySQL的網(wǎng)站,多半同時使用Memcache作為鍵值緩存。雖然這樣的架構(gòu)極其流行,有眾多成功的案例,但過于依賴Memcache,無形中讓Memcache成為故障的根源:

Memcache數(shù)據(jù)一致性的問題:當(dāng)MySQL數(shù)據(jù)變化后,如果不能及時有效的清理掉過期的數(shù)據(jù),就會造成數(shù)據(jù)不一致。這在強調(diào)即時性的Web2.0時代,不可取。

Memcache崩潰后的雪崩效應(yīng):作為緩存的Memcache一旦崩潰,MySQL很可能在短時間內(nèi)承受高負載而宕機。據(jù)說前段時間新浪微博就遭遇了這樣的問題。

注:關(guān)于清理過期數(shù)據(jù)的問題,可以在程序架構(gòu)上想辦法,如果數(shù)據(jù)操作有統(tǒng)一DAO封裝的話,可以利用Observer模式來清理過期數(shù)據(jù),非主題內(nèi)容,資料自查。

面對這些問題,HandlerSocket項目是個不錯的解決方案,它通過插件的方式賦予MySQL完整的NoSQL功能,從原理上講,它跳過MySQL中最耗時的語法解析,查詢計劃等步驟,直接讀取數(shù)據(jù),如果內(nèi)存夠大,能裝下索引,MySQL的查詢效率能提高若干倍!

性能測試實例:Using MySQL as a NoSQL – A story for exceeding 750,000 qps (GFW)

因為HandlerSocket的性能足夠好,所以就沒有必要使用Memcache了,能節(jié)省大量的硬件資源,相當(dāng)?shù)吞?!而且HandlerSocket操作的是MySQL放在內(nèi)存中的索引,沒有額外的緩存,所以自然就不存在數(shù)據(jù)一致性的問題。

安裝

如果使用Percona Server版本的MySQL就簡單了,因為它已經(jīng)內(nèi)置了HandlerSocket支持,不過考慮到其內(nèi)置的版本不夠新,存在一些早已修復(fù)的BUG,所以最好采用源代碼編譯。

官方已經(jīng)有了一份簡單的安裝文檔,但在我實際安裝時,遇到了一些其他未說明的問題,所以這里就把相應(yīng)的安裝過程再寫一遍。

首先要確保已經(jīng)安裝了MySQL5.1以上的版本,我用的是Ubuntu操作系統(tǒng),事先已經(jīng)用apt安裝了MySQL5.1.37,同時還需要相應(yīng)的mysql_config,如果是Ubuntu的話,可以:

shell> aptitude install libmysqld-dev

注:如果你用的MySQL是從源代碼編譯的或官方提供的二進制版本,可以略過此步。

接著下載一份和系統(tǒng)MySQL版本一致的MySQL源代碼和HandlerSocket源代碼:

mysql-5.1.37.tar.gz

ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-76-gf5f7443.tar.gz

shell> tar zxf mysql-5.1.37.tar.gz

shell> tar zxf ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-76-gf5f7443.tar.gz

shell> cd ahiguti-HandlerSocket-Plugin-for-MySQL-f5f7443

shell> ./autogen.sh

shell> ./configure --with-mysql-source=../mysql-5.1.37 \

--with-mysql-bindir=/usr/bin \

--with-mysql-plugindir=/usr/lib/mysql/plugin

其中的參數(shù)含義如下:with-mysql-source表示MySQL源代碼目錄,with-mysql-bindir表示MySQL二進制可執(zhí)行文件目錄(也就是mysql_config所在目錄),with-mysql-plugindir表示MySQL插件目錄,如果不清楚這個目錄在哪,可以按如下方法查詢:

mysql> SHOW VARIABLES LIKE 'plugin%';

+---------------+-----------------------+

| Variable_name | Value |

+---------------+-----------------------+

| plugin_dir | /usr/lib/mysql/plugin |

+---------------+-----------------------+

運行命令后,如果你使用的是MySQL5.1.37版本的話,會遇到如下錯誤信息:

MySQL source version does not match MySQL binary version

明明我們的MySQL源代碼版本和二進制版本都是5.1.37,為什么還會出現(xiàn)這個錯誤呢?通過查詢HandlerSocket的編譯腳本,發(fā)現(xiàn)原來它會檢索MySQL源代碼目錄中的VERSION文件,可MySQL5.1.37的源代碼目錄里不知何故竟然沒有這個文件,所以就報錯了,既然知道了原因,那我們就照貓畫虎做一個VERSION文件放到MySQL源代碼目錄,內(nèi)容如下:

MYSQL_VERSION_MAJOR=5

MYSQL_VERSION_MINOR=1

MYSQL_VERSION_PATCH=37

MYSQL_VERSION_EXTRA=

再次運行configure腳本,應(yīng)該就OK了,把剩下的步驟進行完:

shell> make

shell> make install

接著需要配置一下HandlerSocket,編輯MySQL配置文件,加入如下內(nèi)容:

[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 = 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.

此外,InnoDB的innodb_buffer_pool_size,或MyISAM的key_buffy_size等關(guān)系到緩存索引的選項盡可能設(shè)置大一些,這樣才能發(fā)揮HandlerSocket的潛力。

注:apt包管理下的配置文件一般是/etc/mysql/my.cnf,否則一般是/etc/my.cnf

最后登陸MySQL并激活HandlerSocket插件:

mysql> INSTALL PLUGIN handlersocket soname 'handlersocket.so';

如果沒有問題的話,就能在MySQL里看到HandlerSocket的線程了:

mysql> SHOW PROCESSLIST;

也可以通過查詢剛配置的端口是否已經(jīng)被MySQL占用來確認是否安裝成功:

shell> lsof -i :9998

shell> lsof -i :9999

完活兒!現(xiàn)在你的MySQL已經(jīng)具備NoSQL的能力了!

實戰(zhàn)

首先創(chuàng)建一個測試用的表:

CREATE TABLE IF NOT EXISTS `test`.`t` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`a` varchar(10) NOT NULL,

`b` varchar(10) NOT NULL,

PRIMARY KEY (`id`),

KEY `a_b` (`a`,`b`)

) ENGINE=InnoDB;

注:理論上HandlerSocket支持MyISAM,InnoDB等各種引擎,不過推薦使用InnoDB。

HandlerSocket的協(xié)議非常簡單,指令通過TAB分割,一行就是一個請求。

打開索引:P <索引標識> <數(shù)據(jù)庫> <表> <索引> <字段>

插入數(shù)據(jù):<索引標識> ‘+’ <參數(shù)個數(shù)> <參數(shù)1> … <參數(shù)N>

讀取數(shù)據(jù):<索引標識> <操作> <參數(shù)個數(shù)> <參數(shù)1> … <參數(shù)N> <條數(shù)> <偏移>

SQL原型:INSERT INTO test.t (id, a, b) VALUES (1, ‘a(chǎn)1′, ‘b1′), (2, ‘a(chǎn)2′, ‘b2′)

shell> telnet localhost 9999

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

P 1 test t PRIMARY id,a,b

0 1

1 + 3 1 a1 b1

0 1 0

1 + 3 2 a2 b2

0 1 0

注:使用HandlerSocket時,因為沒有實際運行SQL,所以Binlog記錄的是Row格式。

SQL原型:SELECT id, a, b FROM test.t WHERE id = 1 LIMIT 1

shell> telnet localhost 9999

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

P 1 test t PRIMARY id,a,b

0 1

1 = 1 1 1 0

0 3 1 a1 b1

SQL原型:SELECT id, a, b FROM test.t WHERE id >=1 LIMIT 2

shell> telnet localhost 9999

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

P 1 test t PRIMARY id,a,b

0 1

1 >= 1 1 2 0

0 3 1 a1 b1 2 a2 b2

SQL原型:SELECT id, a, b FROM test.t WHERE a = ‘a(chǎn)1′ AND b = ‘b1′ LIMIT 1

shell> telnet localhost 9999

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

P 1 test t a_b id,a,b

0 1

1 = 2 a1 b1 1 0

0 3 1 a1 b1

對HandlerSocket一個常見的誤解是只能執(zhí)行PRIMARY類型的KV查詢,實際上只要支持索引,一般的簡單查詢它都能勝任,篇幅所限,這里就不多說了,如果你覺得直接操作telnet有些吃力,也可以使用自己熟悉的客戶端來測試,官方文檔里有介紹。

更多信息請查看IT技術(shù)專欄

更多信息請查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機網(wǎng)站地址:MySQL下的NoSQL解決方案HandlerSocket

2025國考·省考課程試聽報名

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)