relay fetch解決mysql replication主從延遲 Mysql復制單線程的本質意味著從服務器效率的降低,即使從服務器有很多磁盤、cpu、和內存,也很容易落後於主服務器,因為從服務器的單線程只能有效的使用一個cpu和磁盤。 從服務器上的鎖定也是一個問題,運行在從服務器上的另外的查詢也會加鎖並阻塞復制線程。復制是單線程,復制線程(sql_thread)除了等待也不能做別的事情。 為了解決這個問題,業界開發了一些補丁解決這類問題,一個思路是由復制單線程改進為多線程。另外一種是在從服務器上通過並行IO把數據預先提取到內存中。 這個主意的想法是通過程序,讓他比從服務器的sql線程稍微提前一點在中繼日志中讀取到查詢語句,並將其作為select語句來執行,這導致服務器把一些數據從磁盤讀取到內存,因此當從服務器的sql線程從中繼日志中執行命令的時候,它就不需要等待從磁盤讀取數據。Select並行處理從服務器必須串行處理的I/O。 程序應該在sql線程前多久執行這個是要確定的問題。提前太多,提取到緩存到的數據會被清空。可以嘗試幾秒鐘,或者中繼日志中相同的字節數 Io密集型從服務器利用這個方案將取得明顯效果。 廣泛分布的單行update命令和delete命令操作,數據預熱效果明顯,大批量的insert命令可能不會有太大明顯提高。 基本思路原理 在備庫sql線程執行更新之前,預先將相應的數據加載到內存中,並不能提高sql_thread線程執行sql的能力,也不能加快io_thread線程讀取日志的速度。 限制 1 目前僅支持主庫binlog ROW模式 2 表需要有主鍵或唯一索引 3 忽略test和mysql數據庫 4 如果數據庫中存在類似tbname_1、tbname_2這樣命名的多個表,但其表模式卻不相同時,請加上-t選項,例如:tb_1 tb_2 tb_3這樣命名的三個表,默認情況下,被認為是同樣模式的表,這個特點是淘寶為了適應他們自己的數據庫環境 5 默認最多支持10000個用戶表,如果學員支持更多表,可以通過修改宏MAX_TABLE_NUM來進行調整。 獲取源碼 安裝svn客戶端從下列地址獲取源碼: svn checkout http://relay-fetch.googlecode.com/svn/trunk/ 安裝編譯: make make的時候需要根據mysql安裝環境修改Makefile配置文件,relay-fetch依賴mysql的lib庫文件等,gcc編譯的時候指定,如下紅色標示部分: #locate your libmysqlclient_r.so all: gcc -g -O0 -Wall-o relayfetch relayfetch.c -I/usr/local/mysql/include/-L/usr/local/mysql/lib -lmysqlclient_r -lpthread clean: rm -rf *.orelayfetch 32位系統安裝有warning ,如下 relayfetch.c: In function ‘daemon_rf’: relayfetch.c:2599: warning: format ‘%lu’ expects type ‘longunsigned int’, but argument 4 has type ‘long long unsigned int’ relayfetch.c:2599: warning: format ‘%lu’ expects type ‘longunsigned int’, but argument 4 has type ‘long long unsigned int’ 不是錯誤error,沒有太多影響 安裝完畢,在安裝目錄下運行./relayfetch –h,了解一下relayfetch 常用參數,如果報如下錯誤error while loading shared libraries: libmysqlclient.so.16/18:cannot open shared object file 應該是mysql的lib庫文件引用問題,建立如下類似軟鏈接 32位 ln -s /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib/ 64位 ln -s /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib64/ 使用 運行: ./relayfetch -h來獲取選項 主要選項包括: -d debug -D 後台運行 -p 密碼 -u 用戶名,請以root用戶運行 -P mysqld端口號 -s 整數,單位為M,當read線程超過sql線程position這麼多字節數時,會等待sql線程,默認為1M -S mysql sock文件路徑 -n worker線程數目。默認為5 -a 當seconds_behind_master大於這個值時,會喚醒relayfetch,默認為1s -t 當使用該選項時,表明不使用分表規則(例如,表name_1 和表name_2會被視為同一類表) 我們可以通過端口號來運行 ./relayfetch-uroot -t -P3306 或者通過sock來運行 ./relayfetch-S /u01/mysql/run/mysql.sock -uroot 測試效果