目前使用MySQL的網站,多半同時使用Memcache作為索引值緩衝。雖然這樣的架構極其流行,有眾多成功的案例,但過於依賴Memcache,無形中讓Memcache成為故障的根源:
Memcache資料一致性的問題:當MySQL資料變化後,如果不能及時有效清理掉到期的資料,就會造成資料不一致。這在強調即時性的Web2.0時代,不可取。
Memcache崩潰後的雪崩效應:作為緩衝的Memcache一旦崩潰,MySQL很可能在短時間內承受高負載而宕機。據說前段時間新浪微博就遭遇了這樣的問題。
註:關於清理到期資料的問題,可以在程式架構上想辦法,如果資料操作有統一DAO封裝的話,可以利用Observer模式來清理到期資料,非主題內容,資料自查。
面對這些問題,HandlerSocket項目是個不錯的解決方案,它通過外掛程式的方式賦予MySQL完整的NoSQL功能,從原理上講,它跳過MySQL中最耗時的文法解析,查詢計劃等步驟,直接讀取資料,如果記憶體夠大,能裝下索引,MySQL的查詢效率能提高若干倍!
效能測試執行個體:Using MySQL as a NoSQL – A story for exceeding 750,000 qps (GFW)
因為HandlerSocket的效能足夠好,所以就沒有必要使用Memcache了,能節省大量的硬體資源,相當低碳!而且HandlerSocket操作的是MySQL放在記憶體中的索引,沒有額外的緩衝,所以自然就不存在資料一致性的問題。
安裝
如果使用Percona Server版本的MySQL就簡單了,因為它已經內建了HandlerSocket支援,不過考慮到其內建的版本不夠新,存在一些早已修複的BUG,所以最好採用原始碼編譯。
官方已經有了一份簡單的安裝文檔,但在我實際安裝時,遇到了一些其他未說明的問題,所以這裡就把相應的安裝過程再寫一遍。
首先要確保已經安裝了MySQL5.1以上的版本,我用的是Ubuntu作業系統,事先已經用apt安裝了MySQL5.1.37,同時還需要相應的mysql_config,如果是Ubuntu的話,可以:
shell> aptitude install libmysqld-dev
|
註:如果你用的MySQL是從原始碼編譯的或官方提供的二進位版本,可以略過此步。
接著下載一份和系統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
|
其中的參數含義如下:with-mysql-source表示MySQL原始碼目錄,with-mysql-bindir表示MySQL二進位可執行檔目錄(也就是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,為什麼還會出現這個錯誤呢?通過查詢HandlerSocket的編譯指令碼,發現原來它會檢索MySQL原始碼目錄中的VERSION檔案,可MySQL5.1.37的原始碼目錄裡不知何故竟然沒有這個檔案,所以就報錯了,既然知道了原因,那我們就照貓畫虎做一個VERSION檔案放到MySQL原始碼目錄,內容如下:
MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=1 MYSQL_VERSION_PATCH=37 MYSQL_VERSION_EXTRA=
|
再次運行configure指令碼,應該就OK了,把剩下的步驟進行完:
shell> make shell> make install
|
接著需要配置一下HandlerSocket,編輯MySQL設定檔,加入如下內容:
[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.
|