mysql讀寫分離

1、流程圖

2、要實現讀寫分離必須是主從同步

2.一、環境設定mysql

主機名 IP
master 192.168.182.129
slave 192.168.182.130
mysql-proxy 192.168.182.131

2.二、實現主從同步git

2.2.一、原理:github

1)主從同步過程當中主服務器有一個工做線程I/O dump thread從服務器有兩個工做線程I/O thread和SQL threadsql

2)主庫把外界接收的SQL請求記錄到本身的binlog日誌中,從庫的I/O thread去請求主庫的binlog日誌,並將binlog日誌寫到中繼日誌中,而後從庫重作中繼日誌的SQL語句。主庫經過I/O dump thread從庫I/O thread傳送binlog日誌。數據庫

3)異步複製是MySQL默認的複製方式,主庫寫入binlog日誌後便可成功返回客戶端,無須等待binlog日誌傳遞給從庫的過程,可是一旦主庫宕機,就有可能出現丟失數據的狀況。apache

4)複製原理vim

4.1 )異步複製後端

  異步複製是MySQL默認的複製方式,主庫寫入binlog日誌後便可成功返回客戶端,無須等待binlog日誌傳遞給從庫的過程,可是一旦主庫宕機,就有可能出現丟失數據的狀況。安全

4.2) 半同步複製服務器

  MySQL默認的複製方式是異步複製,可是當主庫宕機,在高可用架構坐準備切換,就會形成新的主庫丟失數據的現象。

  MySQL5.5版本以後引入了半同步複製,可是主從服務器必須同時安裝半同步複製插件。在該功能下,確保從庫接收完成主庫傳遞過來的binlog內容已經寫入到本身的relay log後纔會通知主庫上面的等待線程。若是等待超時(超時參數:rpl_semi_sync_master_timeout),則關閉半同步複製,並自動轉換爲異步複製模式,直到至少有一臺從庫通知主庫已經接收到binlog信息爲止。

半同步複製提高了主從之間數據的一致性,讓複製更加安全可靠,在5.7 版本中又增長了rpl_semi_sync_master_wait_point參數,用來控制半同步模式下主庫返回給session事務成功以前的事務提交方式。

  該參數有兩個值:

  1)AFTER_COMMIT5.6版本的默認值,主庫將每一個事務寫入binlog,並傳遞給從庫,刷新到中繼日誌中,同時主庫提交事務。以後主庫開始等待從庫的反饋,只有收到從庫的回覆以後,master纔將commit OK的結果反饋給客戶端。

  2)AFTER_SYNC5.7版本新增,也是默認的半同步複製方式。主庫將每一個事務寫入binlog並傳遞給從庫,刷新到中繼日誌中,主庫開始等待從庫的反饋,接收到從庫的回覆以後,再提交事務而且返回commit OK結果給客戶端。

注意:能夠經過rpl_semi_sync_master_wait_for_slave_count參數來控制主庫接收多少個從庫寫事務成功反饋,才返回成功給客戶端。生產環境中使用半同步複製方式,當從庫出現故障,等待超時的時間又很長,致使主庫沒法接收從庫信息而沒法正常寫入時,可經過該參數剔除故障從庫。另外rpl_semi_sync_master_timeout單位是毫秒,它表示若是主庫等待從庫回覆消息的時間超過該值,就自動切換爲異步複製模式,建議調整爲很大,禁止向異步複製切換來保證數據複製的安全性。MySQL 5.7默認的半同步複製方式是after_sync模式。

  在AFTER_SYNC模式下,即便主庫宕機,全部在主庫上已經提交的事務都能保證已經同步到從庫的中繼日誌中,不會丟任何數據。

原理圖:

 2.2.二、主從配置:

注意:這裏使用的是mysql5.6版本,若是其它版本的話,配置可能會有點不同,例如:"log_bin" 對應 "log-bin",只是把"_"換成了"-"了,區別不大,注意一下就行
#
=======================master配置(my.cnf)=====================
# 設置優先級,主必須小於從
server-id=1
# bin log文件前綴
log_bin=mysql-bin
# 對應要同步的數據庫
binlog_do_db=tuling
binlog_do_db=zabbix
# 不須要同步的數據庫
binlog_ignore_db=information_schema
binlog_ignore_db=mysql
binlog_ignore_db=performance_schema
binlog_ignore_db=test
#=======================slave配置(my.cnf)=====================
# 實例ID,不能喝集羣忠的其它mysql實例相同,惟一性
server-id=2
# 對應要同步的數據庫,若是沒有向其它數據庫同步的要求的話,能夠不寫
# log_bin=mysql-bin

# 須要同步的數據庫
replicate_do_db=tuling
replicate_do_db=zabbix

# 設定須要複製的表
# replicate_do_table=tuling.tab1
# 設定須要忽略的複製表 
# replicate_ignore_table=tuling.tab2

# 增長通配符的兩個配置
# replicate_wild_do_table=tuling.%   只複製哪一個庫的哪一個表
# replicate_wild_ignore_table=tuling.%   忽略哪一個庫的哪一個表

# replicate_do_table 跟 replicate_wild_do_table 同樣,只不過replicate_wild_do_table能夠加通配符
# replicate_ignore_table 跟 replicate_wild_ignore_table 同樣,只不過replicate_wild_ignore_table能夠加通配符

# 不須要同步的數據庫
replicate_ignore_db=information_schema
replicate_ignore_db=mysql
replicate_ignore_db=performance_schema
replicate_ignore_db=test
# 在master上建立一個同步權限的帳戶 用來同步數據
grant replication slave on *.* to 'master'@'%' identified by '123456';
show master status\G;


# 配置從庫
stop slave
reset slave;
change master to master_host='192.168.182.129',master_user='master',master_password='123456',master_port=3306,master_log_file='mysql-bin.000018',master_log_pos=326;
start slave;
show slave status\G;

# 當Slave_IO_Running和Slave_SQL_Running線程都爲yes是主從複製配置成功!

2.三、錯誤及解決辦法

問題: 從數據庫沒法同步

Slave_SQL_Running 值爲 NO,或 Seconds_Bebind_Master 值爲 Null

緣由:

  1. 程序有可能在 slave 上進行了寫操做

  2. 也有多是 slave 機器重啓後,事務回滾形成的

解決方法一:

msyql> stop slave;

msyql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

msyql> start slave;

解決方法二:

msyql> stop slave; 

#查看主服務器上當前的 bin-log 日誌名和偏移量

msyql> show master status;

#獲取到以下內容:

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

| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000005 |      286 |              |                  |

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

#而後到從服務器上執行手動同步

msyql> change master to

    ->master_host="192.168.10.1",

    ->master_user="user",

    ->master_password="123456",

    ->master_post=3306,

    ->master_log_file="mysql-bin.000005",

    ->master_log_pos=286;
msyql> start slave;

3、經過Atlas實現讀寫分離

Atlas 是由 Qihoo 360公司Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了不少功能特性。

3.一、Atlas配置

下載Atlas會有兩個版本,其中有個分表的版本,可是這個須要其餘的依賴,我這邊不須要分表這種需求,因此安裝普通的版本

首先進入Linux的Home目錄下,下載非分表的安裝包

[root@localhost ~]# cd /home/
[root@localhost home]# wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm

下載好了以後,進行安裝

[root@localhost home]# rpm -ivh Atlas-2.2.1.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:Atlas                  ########################################### [100%]

安裝好了,它會默認在」/usr/local/mysql-proxy」下給你生成4個文件夾,以及須要配置的文件,以下:

[root@localhost home]# ll /usr/local/mysql-proxy/
total 16
drwxr-xr-x. 2 root root 4096 Dec 28 10:47 bin
drwxr-xr-x. 2 root root 4096 Dec 28 10:47 conf
drwxr-xr-x. 3 root root 4096 Dec 28 10:47 lib
drwxr-xr-x. 2 root root 4096 Dec 17  2014 log
bin目錄下放的都是可執行文件 1. 「encrypt」是用來生成MySQL密碼加密的,在配置的時候會用到

2. 「mysql-proxy」是MySQL本身的讀寫分離代理

3. 「mysql-proxyd」是360弄出來的,後面有個「d」,服務的啓動、重啓、中止。都是用他來執行的

conf目錄下放的是配置文件 1. 「test.cnf」只有一個文件,用來配置代理的,可使用vim來編輯

lib目錄下放的是一些包,以及Atlas的依賴

log目錄下放的是日誌,如報錯等錯誤信息的記錄

進入bin目錄,使用encrypt來對數據庫的密碼進行加密,個人MySQL數據的用戶名是root,密碼是root,我須要對密碼進行加密

[root@localhost bin]# ./encrypt root
DAJnl8cVzy8=

配置Atlas,使用vim進行編輯

[root@localhost conf]# cd /usr/local/mysql-proxy/conf/
[root@localhost conf]# vim test.cnf

進入後,能夠在Atlas進行配置,360寫的中文註釋都很詳細,根據註釋來配置信息,其中比較重要,須要說明的配置以下:

這是用來登陸到Atlas的管理員的帳號與密碼,與之對應的是「#Atlas監聽的管理接口IP和端口」,也就是說須要設置管理員登陸的端口,才能進入管理員界面,默認端口是2345,也能夠指定IP登陸,指定IP後,其餘的IP沒法訪問管理員的命令界面。方便測試,我這裏沒有指定IP和端口登陸。
#管理接口的用戶名
admin-username = user

#管理接口的密碼
admin-password = pwd
 
 

這是用來配置主數據的地址與從數據庫的地址,這裏配置的主數據庫是135,從數據庫是134

#Atlas後端鏈接的MySQL主庫的IP和端口,可設置多項,用逗號分隔
proxy-backend-addresses = 192.168.182.129:3306

#Atlas後端鏈接的MySQL從庫的IP和端口,@後面的數字表明權重,用來做負載均衡,若省略則默認爲1,可設置多項,用逗號分隔
proxy-read-only-backend-addresses = 192.168.182.130:3306@1

這個是用來配置MySQL的帳戶與密碼的,個人MySQL的用戶是root,密碼是root,剛剛使用Atlas提供的工具生成了對應的加密密碼

#用戶名與其對應的加密過的MySQL密碼,密碼使用PREFIX/bin目錄下的加密程序encrypt加密,下行的user1和user2爲示例,將其替換爲你的MySQL的用戶名和加密密碼!
pwds = root:DAJnl8cVzy8=
這是設置工做接口與管理接口的,若是ip設置的」0.0.0.0」就是說任意IP均可以訪問這個接口,固然也能夠指定IP和端口,方便測試我這邊沒有指定,工做接口的用戶名密碼與MySQL的帳戶對應的,管理員的用戶密碼與上面配置的管理員的用戶密碼對應。
#Atlas監聽的工做接口IP和端口
proxy-address = 0.0.0.0:1234

#Atlas監聽的管理接口IP和端口
admin-address = 0.0.0.0:2345

啓動Atlas

[root@localhost bin]# ./mysql-proxyd test start
OK: MySQL-Proxy of test is started

測試一下Atlas服務器的MySQL狀態,要確認它是關閉狀態,而且使用mysql命令,進不去數據庫

[root@localhost bin]# /etc/init.d/mysqld status
mysqld is stopped
[root@localhost bin]# mysql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

確認系統中自帶的MySQL進不去了,使用以下命令,進入Atlas的管理模式「mysql -h127.0.0.1 -P2345 -uuser -ppwd 」,能進去說明Atlas正常運行着呢,由於它會把本身當成一個MySQL數據庫,因此在不須要數據庫環境的狀況下,也能夠進入到MySQL數據庫模式。

[root@localhost bin]# mysql -h127.0.0.1 -P2345 -uuser -ppwd
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-admin

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

能夠訪問「help」表,來看MySQL管理員模式都能作些什麼。可使用SQL語句來訪問

mysql> select * from help;
+----------------------------+---------------------------------------------------------+
| command                    | description                                             |
+----------------------------+---------------------------------------------------------+
| SELECT * FROM help         | shows this help                                         |
| SELECT * FROM backends     | lists the backends and their state                      |
| SET OFFLINE $backend_id    | offline backend server, $backend_id is backend_ndx's id |
| SET ONLINE $backend_id     | online backend server, ...                              |
| ADD MASTER $backend        | example: "add master 127.0.0.1:3306", ...               |
| ADD SLAVE $backend         | example: "add slave 127.0.0.1:3306", ...                |
| REMOVE BACKEND $backend_id | example: "remove backend 1", ...                        |
| SELECT * FROM clients      | lists the clients                                       |
| ADD CLIENT $client         | example: "add client 192.168.1.2", ...                  |
| REMOVE CLIENT $client      | example: "remove client 192.168.1.2", ...               |
| SELECT * FROM pwds         | lists the pwds                                          |
| ADD PWD $pwd               | example: "add pwd user:raw_password", ...               |
| ADD ENPWD $pwd             | example: "add enpwd user:encrypted_password", ...       |
| REMOVE PWD $pwd            | example: "remove pwd user", ...                         |
| SAVE CONFIG                | save the backends to config file                        |
| SELECT VERSION             | display the version of Atlas                            |
+----------------------------+---------------------------------------------------------+
16 rows in set (0.00 sec)

mysql>

也可使用工做接口來訪問,使用命令「mysql -h127.0.0.1 -P1234 -uroot -proot」

[root@localhost bin]# mysql -h127.0.0.1 -P1234 -uroot -proot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.81-log

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

若是工做接口能夠進入了,就能夠在Windows平臺下,使用Navicat來鏈接數據庫,填寫對應的host,Port,用戶名,密碼就能夠

3.二、讀寫分離測試

這裏測試讀寫分離須要使用到Jmeter了,它是Java寫第一套開源的壓力測試工具,由於這個比較方便。他有專門測試MySQL的模塊,須要使用MySQL的JDBC驅動jar包,配置很簡單,東西很好很強大很好用。

Jmeter下載地址:http://jmeter.apache.org/download_jmeter.cgi

MySQL的JDBC  :http://dev.mysql.com/downloads/connector/j/

下載下來後,分別都解壓開來,打開Jmeter ( 在bin路面下的jmeter.bat ) ,在測試計劃中,致使JDBC的jar包

配置JDBC的驅動

 分別作查詢與插入語句

配置好了之後,就先運行查詢操做,而後分別監控主數據庫與從數據庫所在機器的流量,來肯定是否讀寫,使用在主備Linux命令行輸入「sar -n DEV 1 10000」命令來監控讀寫

先來測試寫,目前數據庫裏面一條信息都沒有,開啓配置好了的Jmeter,進行寫入數據測試

sar命令查看網卡流量

sar這個工具RHEL5自帶有,默認也安裝。
一個強大的工具(好像這些工具都蠻強的),參數不少,有時間man一下。
 
-n參數頗有用,他有6個不一樣的開關:DEV | EDEV | NFS | NFSD | SOCK | ALL 。DEV顯示網絡接口信息,EDEV顯示關於網絡錯誤的統計數據,NFS統計活動的NFS客戶端的信息,NFSD統計NFS服務器的信息,SOCK顯示套 接字信息,ALL顯示全部5個開關。它們能夠單獨或者一塊兒使用。咱們如今要用的就是-n DEV了。
 
輸入命令:sar –n DEV 1 4
命令後面 1 4 意思是:每一秒鐘取一次值,取四次。

主數據庫 ( 192.168.182.129 )

從數據庫 ( 192.168.182.130)

批量插入數據語句

delimiter //
DROP PROCEDURE IF EXISTS proc_batch_insert;
CREATE PROCEDURE proc_batch_insert()
BEGIN
DECLARE pre_name BIGINT;
DECLARE ageVal INT;
DECLARE i INT;
SET pre_name=187635267;
SET ageVal=100;
SET i=1;
WHILE i <= 1000000 DO
        INSERT INTO tt(descpro) VALUES(NOW());
SET pre_name=pre_name+100;
SET i=i+1;
END WHILE;
END //
 
delimiter ;
call proc_batch_insert();

能夠看到測試插入數據的操做時,主(192.168.182.129)數據庫的網卡有些指標流量很大而從數據庫的流量很小,是應爲主數據是主要負責寫入的,而從(192.168.182.130)數據庫主要是負責同步的。

 

參數說明:

IFACE:LAN接口

rxpck/s:每秒鐘接收的數據包

txpck/s:每秒鐘發送的數據包

rxbyt/s:每秒鐘接收的字節數

txbyt/s:每秒鐘發送的字節數

rxcmp/s:每秒鐘接收的壓縮數據包

txcmp/s:每秒鐘發送的壓縮數據包

rxmcst/s:每秒鐘接收的多播數據包

rxerr/s:每秒鐘接收的壞數據包

txerr/s:每秒鐘發送的壞數據包

coll/s:每秒衝突數

rxdrop/s:由於緩衝充滿,每秒鐘丟棄的已接收數據包數

txdrop/s:由於緩衝充滿,每秒鐘丟棄的已發送數據包數

txcarr/s:發送數據包時,每秒載波錯誤數

rxfram/s:每秒接收數據包的幀對齊錯誤數

rxfifo/s:接收的數據包每秒FIFO過速的錯誤數

txfifo/s:發送的數據包每秒FIFO過速的錯誤數

查看數據庫,發現已經插入了100w條數據了

 

進行讀取數據的測試,只須要執行查詢就好,執行「select *from tt;」來查詢數據表

主數據庫 ( 192.168.182.129 )

從數據庫 ( 192.168.182.130 )

能夠看到130數據庫的流量很是大,129沒有什麼流量,這下就能夠肯定了數據是從數據庫讀取的。已經實現了讀寫分離。

相關文章
相關標籤/搜索