mysql主從複製讀寫分離

mysql主從複製讀寫分離



一、MYSQL讀寫分離的概述

Mysql作爲目前世界上使用最廣泛的免費數據庫,相信所有從事系統運維的工程師都一定接觸過。但在實際的生產環境中,由單臺Mysql作爲獨立的數據庫是完全不能滿足實際需求的,無論是在安全性,高可用性以及高併發等各個方面。
因此,一般來說都是通過 主從複製(Master-Slave)的方式來同步數據,再通過讀寫分離(MySQL-Proxy/Amoeba)來提升數據庫的併發負載能力 這樣的方案來進行部署與實施的。
讀寫分離工作原理:
基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操作。數據庫複製被用來把事務性操作導致的變更同步到集羣中的從數據庫。

數據內部交換過程:


爲什麼要讀寫分離:

面對越來越大的訪問壓力,單臺的服務器的性能成爲瓶頸,需要分擔負載

1、        主從只負責各自的寫和讀,極大程度的緩解X鎖和S鎖爭用

2、        從庫可配置myisam引擎,提升查詢性能以及節約系統開銷

3、        增加冗餘,提高可用性

實現讀寫分離的方式:

一般有兩種方式實現

應用程序層實現,網站的程序實現

應用程序層實現指的是在應用程序內部及連接器中實現讀寫分離



優點:
A:應用程序內部實現讀寫分離,安裝既可以使用
B:減少一定部署難度
C:訪問壓力在一定級別以下,性能很好
缺點:
A:架構一旦調整,代碼要跟着變
B:難以實現高級應用,如自動分庫,分表
C:無法適用大型應用場景
中間件層實現
中間件層實現是指在外部中間件程序實現讀寫分離
常見的中間件程序:
Mysql-proxy    amoeba    Atlas (360)  Cobar(Alibaba)  TDDL(Taobao)
優點:
A:架構設計更靈活
B:可以在程序上實現一些高級控制,如:透明化水平拆分,failover,監控
C:可以依靠些技術手段提高mysql性能,
D:對業務代碼的影響小,同時也安全
缺點:
需要一定的開發運維團隊的支持

MYSQL-PROXY概述

MySQL Proxy是一個處於你的client端和MySQL server端之間的簡單程序,它可以監測、分析或改變它們的通信。它使用靈活,沒有限制,常見的用途包括:負載平衡,故障、查詢分析,查詢過濾和修改等等。
MySQL Proxy就是這麼一箇中間層代理,簡單的說,MySQL Proxy就是一個連接池,負責將前臺應用的連接請求轉發給後臺的數據庫,並且通過使用lua腳本,可以實現複雜的連接控制和過濾,從而實現讀寫分離和負載平衡。對於應用來說,MySQL Proxy是完全透明的,應用則只需要連接到MySQL Proxy的監聽端口即可。當然,這樣proxy機器可能成爲單點失效,但完全可以使用多個proxy機器做爲冗餘,在應用服務器的連接池配置中配置到多個proxy的連接參數即可。

MySQL Proxy更強大的一項功能是實現“讀寫分離”,基本原理是讓主數據庫處理事務性查詢,讓從庫處理SELECT查詢。數據庫複製被用來把事務性查詢導致的變更同步到集羣中的從庫


Lua概述:
Lua 是一個小巧的腳本語言。
Lua的速度是最快的。這一切都決定了Lua是作爲嵌入式腳本的最佳選擇。
Lua由標準C編寫而成,幾乎在所有操作系統和平臺上都可以編譯,運行。Lua並沒有提供強大的庫,這是由它的定位決定的。所以Lua不適合作爲開發獨立應用程序的語言。
lua官網:http://www.lua.org/
下載: mysql-proxy
http://dev.mysql.com/downloads/mysql-proxy/


二、安裝環境

系統環境:CentOS release 6.9 64bit  
軟件名稱:mysql-5.7.18

軟件用戶:mysql

軟件安裝位置:/usr/bin/、/usr/share/、/usr/local/mysql-proxy

數據存放位置:/var/lib/mysql

日誌存放位置:/var/log/mysqld.log



三、主從設計
首先設計主從的安裝分配方式,共需要3臺服務器,服務器分配如下:

    master節點:        192.168.99.35
    mysql-proxy節點:    192.168.99.36
    slave節點:           192.168.99.37



四、安裝部署

1、三臺服務器在線安裝mysql

root@centos-6 mysql]# rpm –Uvh https://repo.mysql.com//mysql57-community-release-el6-11.noarch.rpm

root@centos-6 mysql]# yum -y install mysql-community-server mysql-community-client mysql-community-common mysql-community-libs


網速慢可以先下載rpm包本地rpm或yum安裝

[root@centos-6 home]# mkdir /home/mysql/

[root@centos-6 home]# cd /home/mysql/

[root@centos-6 mysql]# ls

mysql-community-client-5.7.18-1.el6.x86_64.rpm

mysql-community-common-5.7.18-1.el6.x86_64.rpm

mysql-community-libs-5.7.18-1.el6.x86_64.rpm

mysql-community-server-5.7.18-1.el6.x86_64.rpm

root@centos-6 mysql]# yum -y install mysql-community-server mysql-community-client mysql-community-common mysql-community-libs


2、修改密碼策略配置簡單密碼便於測試

第一次通過#grep "password" /var/log/mysqld.log 命令獲取MySQL的臨時密碼

用該密碼登錄到服務端後,必須馬上修改密碼,不然操作查詢時報錯誤

剛開始設置的密碼必須符合長度,且必須含有數字,小寫或大寫字母,特殊字符。

如果想設置簡單密碼,如下操作:

首先,修改validate_password_policy參數的值

[root@centos-6 mysql]# grep "password" /var/log/mysqld.log 

2017-05-28T23:15:52.739913Z 1 [Note] A temporary password is generated for root@localhost: xnzb:ff-h1G_

mysql> set global validate_password_policy=0;  #定義複雜度

mysql> set global validate_password_length=1;  #定義長度 默認是8

mysql>set password for 'root'@'localhost'=password('123456');


通過my.cnf 配置文件設置密碼策略的級別

validate_password_policy=2

最後一行 validate_password_policy 設置mysql啓動的時候密碼策略級別。 如果設置爲3 ,那麼需要指定字典文件。


當然你也可以通過 my.cnf 配置文件關閉 validate_password 插件。只需要添加一行 

validate_password = off


MySQL 新版本默認監聽在IPv6的地址族上。

更改爲監聽IPv4地址族,修改 my.cnf 添加一行配置:

bind-address = 0.0.0.0


3、在99.36上安裝lua

[root@Centos-6-99 ~]# yum -y install lua


4、在99.36上安裝mysql-proxy

推薦採用已經編譯好的二進制版本,因爲採用源碼包進行編譯時,最新版的MySQL-Proxy對automake,glib以及libevent的版本都有很高的要求,而這些軟件包都是系統的基礎套件,不建議強行進行更新。並且這些已經編譯好的二進制版本在解壓後都在統一的目錄內,因此建議選擇以下版本:

1)下載安裝mysql-proxy

[root@Centos-6-99 home]# wget http://dev.mysql.com/get/Downloads/MySQL-Proxy/mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz

[root@Centos-6-99 mysql-proxy]# tar -xvf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local/ && cd /usr/local/ && mv mysql-proxy-0.8.5-linux-el6-x86-64bit/ ./mysql-proxy && cd /usr/local/mysql-proxy

2)修改系統環境變量

vim /etc/profile

export PATH=/usr/local/mysql-proxy/bin/:/usr/local/mysql/bin:$PATH    //增加這個變量

[root@xuegod62 local]# source !$    //使系統環境變量生效

source /etc/profile

3)修改mysql-proxy配置文件實現讀寫分離

vim /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua

將默認配置

min_idle_connections = 4,

max_idle_connections = 8,

修改爲

min_idle_connections = 1,

max_idle_connections = 8,

修改默認連接,進行快速測試,默認最小4個以上的客戶端連接纔會實現讀寫分離,最大鏈接數爲8。 
注:爲了驗證試驗效果將他改成1 .就是當有一個鏈接的時候,就實現讀寫分離的功能。

4)分別在99.35和99.37上創建數據庫和表,分別用於實現寫和讀操作

mysql -uroot -p123456

mysql> create database db;

mysql> use db;

mysql> create table test(id int);

mysql> insert into test values(35);

mysql> grant all on db.* to user1@'%' identified by '123456';

mysql>flush privileges;


mysql -uroot -p123456

mysql> create database db;

mysql> use db;

mysql> create table test(id int);

mysql> insert into test values(37);

mysql> grant all on db.* to user1@'%' identified by '123456';

mysql>flush privileges;


5)在99.36啓動MYSQL-PROXY服務

[root@Centos-6-99 local]# mysql-proxy --proxy-read-only-backend-addresses=192.168.99.37:3306 --proxy-backend-addresses=192.168.99.35:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua &

[1] 2551

[root@Centos-6-99 local]# 2017-06-11 10:34:09: (critical) plugin proxy 0.8.5 started

6)參數說明

--proxy-read-only-backend-addresses=192.168.99.37:3306  # 定義後端只讀服務器 
--proxy-backend-addresses=192.168.99.35:3306   #定義後端mysql主服務器地址,指定mysql寫主服務器的端口

--proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua &  #指定lua腳本,在這裏,使用的是rw-splitting腳本,用於讀寫分離


當有多個只讀服務器時,可以寫多個以下參數:

當有多個只讀服務器時,可以寫多個以下參數:
--proxy-read-only-backend-addresses=192.168.1.64:3306  # 定義後端只讀服務器
--proxy-read-only-backend-addresses=192.168.1.65:3306  # 定義後端只讀服務器
#--proxy-address=192.168.1.62:3307 指定mysql proxy的監聽端口,默認爲:4040


完整的參數可以運行以下命令查看

mysql-proxy --help-all


7)查看mysql-proxy是否啓動

[root@Centos-6-99 local]# lsof -i :4040

COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysql-pro 3144 root    9u  IPv4  19597      0t0  TCP *:yo-main (LISTEN)

8)測試讀寫分離

第一臺服務器登錄99.36查詢

[root@localhost ~]# mysql -uuser1 -p123456 -P4040 -h192.168.99.36

mysql> use db;

Database changed

mysql> select * from test;

+------+

| id   |

+------+

|   35 |

+------+

1 row in set (0.00 sec)

mysql> 

插入後再進行查詢

mysql> insert into test values(36);

Query OK, 1 row affected (0.04 sec)


mysql> select * from test;

+------+

| id   |

+------+

|   35 |

|   36 |

+------+

1 row in set (0.00 sec)


mysql> 

第二臺服務器登錄99.36查詢

[root@localhost ~]# mysql -uuser1 -p123456 -P4040 -h192.168.99.36

mysql> use db;

Database changed

mysql> select * from test;

+------+

| id   |

+------+

|   37 |

+------+

1 row in set (0.00 sec)

mysql>

說明讀寫分離已成功;

9)查看客戶端理解狀態

mysql> show processlist;

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

| Id | User  | Host                | db   | Command | Time | State    | Info             |

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

|  5 | user1 | 192.168.99.36:45314 | db   | Sleep   |    2 |          | NULL             |

|  6 | user1 | 192.168.99.36:45316 | db   | Query   |    0 | starting | show processlist |

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

2 rows in set (0.00 sec)

mysql> 

10)狀態參數說明;

每列參數說明:
第一列, id ,一個標識 
user列, 顯示當前用戶,如果不是 root ,這個命令就只顯示你權限範圍內的 sql 語 句。 
host 列,顯示這個語句是從哪個 ip 的哪 個端口上發出的。可以用來追蹤出問題語句的用戶。 
db 列,顯示這個進程目前連接的是哪個數據庫 。 
command 列,顯示當前連接的執行的命令,一般就是休眠( sleep ),查詢( query ),連接( connect )。 
time 列,此這個狀態持續的時間,單位是秒。 
state 列,顯示使用當前連接的 sql 語句的狀態,很重要的列, state 只是語句執行中的某一個狀態,一個 sql 語句,以查詢爲例,可能需要經過 copying to tmp table ,Sorting result , Sending data 等狀態纔可以完成。 

info 列,顯示這個 sql 語句,因爲長度有限,所以長的 sql 語句就顯示不全,但是一個判斷問題語句的重要依據。


5、在99.35配置mysql master並在99.37配置mysql slave實現主從複製

1)配置主服務器配置文件,啓用log-bin功能

[root@centos-6 mysql]#vim /etc/my.cnf

log-bin=mysql-bin-master  #啓用二進制日誌

server-id=1   #本機數據庫ID 標示

binlog-do-db=db #可以被從服務器複製的庫。二進制需要同步的數據庫名

binlog-ignore-db=mysql  #不可以被從服務器複製的庫

2)授權允許slave 37訪問35

mysql> grant replication slave on *.* to [email protected]  identified by "123456"; 

Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

查看mster狀態

mysql> show master status;

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

| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

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

| mysql-bin-master.000001 |      154 | db           | mysql            |                   |

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

1 row in set (0.00 sec)

3)配置服務器37爲slave

[root@Centos-6-99 ~]# vim /etc/my.cnf

server-id=2   #本機數據庫ID 標示

4)配置37根據master變化

mysql -uroot -p123456

mysql> change master to master_host='192.168.99.35',master_user='slave',master_password='123456';

mysql> flush privileges;

5)啓動slave並查看狀態

mysql> start slave;

Query OK, 0 rows affected (0.01 sec)

mysql> show slave status \G

6)在35上插入數據

mysql -uroot -p123456

mysql> use db;

Database changed

mysql> insert into test values(36);

Query OK, 1 row affected (0.08 sec)


mysql> select * from test;

+------+

| id   |

+------+

|   35 |

|   36 |

+------+

2 rows in set (0.00 sec)

mysql> 

7)在37上進行查看

[root@Centos-6-99 ~]# mysql -u root -p123456

mysql> use db;

Database changed

mysql> select * from test;

+------+

| id   |

+------+

|   37 |

|   36 |

+------+

2 rows in set (0.00 sec)


mysql> 

可以看到新插入的36已同步過去;

8)外部登錄99.36查詢也可以看到分別的主備數據已同步

[root@localhost ~]# mysql -uuser1 -p123456 -P4040 -h192.168.99.36

mysql>use db;

mysql> select * from test;

+------+

| id   |

+------+

|   35 |

|   36 |

+------+

2 rows in set (0.00 sec)

mysql> 

另外一臺服務器登錄99.36的查詢情況

[root@localhost ~]# mysql -uuser1 -p123456 -P4040 -h192.168.99.36

mysql> use db;

Database changed

mysql> select * from test;

+------+

| id   |

+------+

|   37 |

|   36 |

+------+

2 rows in set (0.00 sec)

9)外部登錄99.36插入及查詢情況

[root@localhost ~]# mysql -uuser1 -p123456 -P4040 -h192.168.99.36

mysql> use db;

Database changed

mysql> insert into test values(100);

Query OK, 1 row affected (0.07 sec)

mysql> insert into test values(101);

Query OK, 1 row affected (0.08 sec)

mysql> select * from test;

+------+

| id   |

+------+

|   37 |

|   36 |

|  100 |

|  101 |

+------+

4 rows in set (0.00 sec)

mysql> 

在99.35上查詢確認數據已插入並且同步;

mysql> select * from test;

+------+

| id   |

+------+

|   35 |

|   36 |

|  100 |

|  101 |

+------+

4 rows in set (0.00 sec)

mysql> 

10)解決插入的35和37不一致問題

在99.35上禁用同步功能

[root@centos-6 mysql]# vim /etc/my.cnf

#log-bin=mysql-bin-master  #不啓用二進制日誌

重啓mysql

[root@centos-6 mysql]# /etc/init.d/mysqld restart

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

刪除35

[root@centos-6 mysql]# mysql -u root -p123456

mysql> delete from test where id=35;

Query OK, 1 row affected (0.06 sec)


mysql> select * from test;

+------+

| id   |

+------+

|   36 |

|  100 |

|  101 |

+------+

3 rows in set (0.00 sec)

在99.37上禁用salve並刪除37

mysql> stop slave;

Query OK, 0 rows affected (0.02 sec)

mysql> delete from test where id=37;

Query OK, 1 row affected (0.04 sec)

mysql> select * from test;

+------+

| id   |

+------+

|   36 |

|  100 |

|  101 |

+------+

3 rows in set (0.00 sec)

重新啓動同步功能即可

在99.35上啓用同步功能

[root@centos-6 mysql]# vim /etc/my.cnf

log-bin=mysql-bin-master  #啓用二進制日誌

重啓mysql

[root@centos-6 mysql]# /etc/init.d/mysqld restart

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

在99.37上啓動slave即可

mysql> stop slave;

外部插入和查詢即可正常





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章