環境描述:
操做系統:CentOS6.5 64 位
mysql主服務器 Master:172.25.17.19
mysql
mysql從服務器 Slave1:172.25.17.20
linux
mysql從服務器 Slave2:172.25.17.21sql
調度服務器 MySQL-Proxy:172.25.17.7
數據庫
1、安裝 mysql-proxy
實現讀寫分離是有 lua 腳本實現的,如今 mysql-proxy 裏面已經集成,無需再安裝
下載:http://dev.mysql.com/downloads/mysql-proxy/ 必定要下載對應的版本
[root@proxy ~]# rpm -ivh mysql-proxy-0.8.1-1.el6.x86_64.rpm
二、將rw-splitting.lua 腳本複製到/lib 下
[root@proxy ~]# cp rw-splitting.lua /lib
三、修改mysql-proxy主配置文件/etc/sysconfig/mysql-proxy
vim
[root@proxy ~]# vim /etc/sysconfig/mysql-proxy ADMIN_USER="proxy" #主從 mysql 共有的用戶 ADMIN_PASSWORD="123456" #用戶的密碼 ADMIN_LUA_SCRIPT="/lib/rw-splitting.lua" #指定管理腳本 PROXY_USER="root" #運行 mysql-proxy用戶 #添加以下代碼:[如下代碼需寫在一行內] PROXY_OPTIONS="--proxy-address=172.25.17.7:4040 --proxy-read-only-backend-addresses=172.25.17.20:3306--proxy-read-only-backend-addresses=172.25.17.21:3306--proxy-backend-addresses=172.25.17.19:3306--proxy-lua-script=/lib/rw-splitting.lua --daemon" #mysql-proxy 運行 ip 和端口,不加端口,默認 4040
四、修改讀寫分離配置文件緩存
[root@proxy ~]# vim /lib/rw-splitting.lua if not proxy.global.config.rwsplit then proxy.global.config.rwsplit = { min_idle_connections = 1, #默認超過 4個鏈接數時,纔開始讀寫分離,改成 1 max_idle_connections = 1, #默認 8,改成1 is_debug = false } end #這裏的 4 、8 是指定連接數,作測試時調整爲 1
五、設置mysql-proxy 開機啓動,並啓動mysql-proxy
安全
[root@proxy ~]# chkconfig mysql-proxy on [root@proxy ~]# service mysql-proxy start [root@proxy ~]# netstat -tnlp | grep mysql-proxy tcp 0 0 172.25.17.7:4040 0.0.0.0:* LISTEN 27352/mysql-proxy tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 27352/mysql-proxy
六、在master數據庫受權mysql-proxy訪問
[root@master ~]# mysql -puplooking
grant all on *.* to 'proxy'@'172.25.17.7' identified by '123456';
grant all on *.* to 'proxy'@'rhel6' identified by '123456';
flush privileges;bash
7 、測試讀寫分離服務器
測試讀寫分離,要讓兩臺服務器數據有偏差才行,因此暫停slave1(172.25.17.20)上的從服務:網絡
mysql -puplooking > stop slave;
在 master(172.25.17.19) 服務器上修改數據:
mysql> create tabletest.t1(id int);
mysql> insert intotest.t1 values (1);mysql> insert into test.t1 values (3);
mysql> insert intotest.t1 values (2);mysql> insert into test.t1 values (4);
在 slave1(172.25.17.20) 服務器上修改數據:
mysql> create tabletest.t1(id int);
mysql> insert into test.t1values (5);
mysql> insert intotest.t1 values (6);
在 調度服務器mysql-proxy 上打開若干個終端遠程訪問數據庫,讀取數據:
[root@proxy ~]# yum -y install mysql #安裝數據庫添加mysql啓動命令 [root@proxy ~]# mysql -uproxy -p123456 -h172.25.17.7 -P4040 #遠程訪問數據庫 mysql> select * from test1.t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | +------+ 4 rows in set (0.00 sec) mysql> select * from test01.t1; +------+ | id | +------+ | 5 | | 6 | +------+ 2 rows in set (0.00 sec)
顯示結果不同,證實配置成功。屢次嘗試以上兩行代碼直到顯示不一樣結果。
試驗結束在slave1服務器上slave start恢復主從同步。
#####################################################
讀寫分離,延遲是個大問題
在 slave 服務器上執行 show slave status,
能夠看到不少同步的參數,要注意的參數有:
Master_Log_File:slave 中的 I/O 線程當前正在讀取的 master 服務器二進制式日誌文件名.
Read_Master_Log_Pos:在當前的 master 服務器二進制日誌中,slave 中的 I/O 線程已經讀取的位置
Relay_Log_File:SQL 線程當前正在讀取與執行中繼日誌文件的名稱
Relay_Log_Pos:在當前的中繼日誌中,SQL 線程已讀取和執行的位置
Relay_Master_Log_File:由 SQL 線程執行的包含多數近期事件的 master 二進制日誌文件的名稱
Slave_IO_Running:I/O 線程是否被啓動併成功鏈接到 master
Slave_SQL_Running:SQL 線程是否被啓動
Seconds_Behind_Master:slave 服務器 SQL 線程和從服務器 I/O 線程之間的差距,單位爲秒計
slave 同步延遲狀況出現:
1.Seconds_Behind_Master 不爲了,這個值可能會很大
2.Relay_Master_Log_File 和 Master_Log_File 顯示 bin-log 的編號相差很大,說明 bin-log 在 slave 上
沒有及時同步,因此近期執行的 bin-log 和當前 I/O 線程所讀的 bin-log 相差很大
3.mysql 的 slave 數據庫目錄下存在大量的 mysql-relay-log 日誌,該日誌同步完成以後就會被系統自動
刪除,存在大量日誌,說明主從同步延遲很厲害
mysql 主從同步原理
主庫針對讀寫操做,順序寫 binlog,從庫單線程去主庫讀"寫操做的 binlog",從庫取到 binlog 在本地原
樣執行(隨機寫),來保證主從數據邏輯上一致.
mysql 的主從複製都是單線程的操做,主庫對全部 DDL 和 DML 產生 binlog,binlog 是順序寫,因此
效率很高,slave 的 Slave_IO_Running 線程到主庫取日誌,效率比較高,下一步問題來 了,slave 的
slave_sql_running 線程將主庫的 DDL 和 DML 操做在 slave 實施。DML,DDL 的 IO 操做是隨即的,
不能順序的,成本高不少,還有可能 slave 上的其餘查詢產生 lock,因爲 slave_sql_running 也是單線
程的,因此 一個 DDL 卡住了,需求需求執行一段時間,那麼全部以後的 DDL 會等待這個 DDL 執行完
纔會繼續執行,這就致使了延遲.因爲 master 能夠併發,Slave_sql_running 線程卻不能夠,因此主庫執
行 DDL 需求一段時間,在 slave 執行相同的 DDL 時,就產生了延遲.
主從同步延遲產生緣由
當主庫的 TPS 併發較高時,產生的 DDL 數量超過 Slave 一個 sql 線程所能承受的範圍,那麼延遲就產
生了,固然還有就是可能與 slave 的大型 query 語句產生了鎖等待
首要緣由:數據庫在業務上讀寫壓力太大,CPU 計算負荷大,網卡負荷大,硬盤隨機 IO 過高
次要緣由:讀寫 binlog 帶來的性能影響,網絡傳輸延遲
主從同步延遲解決方案
架構方面
1.業務的持久化層的實現採用分庫架構,mysql 服務可平行擴展分散壓力
2.單個庫讀寫分離,一主多從,主寫從讀,分散壓力。
3.服務的基礎架構在業務和 mysql 之間加放 cache 層
4.不一樣業務的 mysql 放在不一樣的機器
5.使用比主加更了的硬件設備做 slave
反正就是 mysql 壓力變小,延遲天然會變小
硬件方面:
採用好的服務器
mysql 主從同步加速
1、sync_binlog 在 slave 端設置爲 0
2、–logs-slave-updates 從服務器從主服務器接收到的更新不記入它的二進制日誌。
3、直接禁用 slave 端的 binlog
4、slave 端,若是使用的存儲引擎是 innodb,innodb_flush_log_at_trx_commit =2
從文件系統自己屬性角度優化
master 端
修改 linux、Unix 文件系統中文件的 etime 屬性, 因爲每當讀文件時 OS 都會將讀取操做發生的時間回
寫到磁盤上,對於讀操做頻繁的數據庫文件來講這是不必的,只會增長磁盤系統的負擔影響 I/O 性能。
能夠 經過設置文件系統的 mount 屬性,組織操做系統寫 atime 信息,在 linux 上的操做爲:
打開/etc/fstab,加上 noatime 參數
/dev/sdb1 /data reiserfs noatime 1 2
而後從新 mount 文件系統
#mount -oremount /data
主庫是寫,對數據安全性較高,好比 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設
置是須要的
而 slave 則不須要這麼高的數據安全,徹底能夠講 sync_binlog 設置爲 0 或者關閉
binlog,innodb_flushlog 也能夠設置爲 0 來提升 sql 的執行效率
1、sync_binlog=1 o
MySQL 提供一個 sync_binlog 參數來控制數據庫的 binlog 刷到磁盤上去。
默認,sync_binlog=0,表示 MySQL 不控制 binlog 的刷新,由文件系統本身控制它的緩存的刷新。這
時候的性能是最好的,可是風險也是最大的。一旦系統 Crash,在 binlog_cache 中的全部 binlog 信息都
會被丟失。
如 果 sync_binlog>0,表示每 sync_binlog 次事務提交,MySQL 調用文件系統的刷新操做將緩存刷下
去。最安全的就是 sync_binlog=1 了,表示每次事務提交,MySQL 都會把 binlog 刷下去,是最安全但
是性能損耗最大的設置。這樣的話,在數據庫所在的主機 操做系統損壞或者忽然掉電的狀況下,系統才
有可能丟失 1 個事務的數據。
可是 binlog 雖然是順序 IO,可是設置 sync_binlog=1,多個事務同時提交,一樣很大的影響 MySQL
和 IO 性能。
雖然能夠經過 group commit 的補丁緩解,可是刷新的頻率太高對 IO 的影響也很是大。對於高併發事務
的系統來講,
「sync_binlog」設置爲 0 和設置爲 1 的系統寫入性能差距可能高達 5 倍甚至更多。
因此不少 MySQL DBA 設置的 sync_binlog 並非最安全的 1,而是 2 或者是 0。這樣犧牲必定的一致
性,能夠得到更高的併發和性能。
默 認狀況下,並非每次寫入時都將 binlog 與硬盤同步。所以若是操做系統或機器(不只僅是 MySQL
服務器)崩潰,有可能 binlog 中最後的語句丟失 了。要想防止這種狀況,你可使用 sync_binlog 全局
變量(1 是最安全的值,但也是最慢的),使 binlog 在每 N 次 binlog 寫入後與硬盤同 步。即便
sync_binlog 設置爲 1,出現崩潰時,也有可能表內容和 binlog 內容之間存在不一致性。
2、innodb_flush_log_at_trx_commit (這個很管用)
抱怨 Innodb 比 MyISAM 慢 100 倍?那麼你大概是忘了調整這個值。默認值 1 的意思是每一次事務提交
或事務外的指令都須要把日誌寫入(flush)硬盤,這是很費時的。特別是使用電 池供電緩存(Battery
backed up cache)時。設成 2 對於不少運用,特別是從 MyISAM 錶轉過來的是能夠的,它的意思是不
寫入硬盤而是寫入系統緩存。
日誌仍然會每秒 flush 到硬 盤,因此你通常不會丟失超過 1-2 秒的更新。設成 0 會更快一點,但安全方
面比較差,即便 MySQL 掛了也可能會丟失事務的數據。而值 2 只會在整個操做系統 掛了時纔可能丟數
據。
3.進行分庫分表處理,這樣減小數據量的複製同步操做