MySQL數據讀寫分離
一、讀寫分離概述
1.1、MySQL讀寫分離
-
什麼是數據讀寫分離)
數據存儲服務結構,把客戶端查詢數據的select 訪問和 寫入數據的insert update delete 訪問 分別給不同的數據庫服務器處理。 -
爲什麼要使用數據讀寫分離結構存儲數據?
分析:減輕主服務器的工作壓力 -
如何實現數據讀寫分離???
客戶端實現:程序員編寫訪問數據庫的網站腳本實現( PHP JAVA)
服務器端實現: 通過實現數據讀寫分離的服務軟件。部署服務器實現 -
MySQL中間件
(mysql-proxy 、 mycat 、 maxscale )
1.2、讀寫分離原理
- 添加一個MySQL代理
接受客戶端訪問,爲客戶端提供訪問數據接口 - 由MySQL代理面向客戶端提供服務
- 收到SQL寫請求時,交給master服務器處理
- 收到SQL讀請求時,交給slave服務器處理
二、構建讀寫分離
2.1、拓撲結構
本次實驗基於主從結構。
MySQL主從同步實驗參考
2.2、部署MySQL代理服務器
2.2.1、部署maxscale服務
[root@pxysvr ~]# rpm -ivh maxscale-2.1.2-1.rhel.7.x86_64.rpm
2.2.2、備份配置文件
[root@pxysvr ~]# cp /etc/maxscale.cnf /root/maxscale.cnf
2.2.3、修改配置文件
[root@pxysvr ~]# vim /etc/maxscale.cnf
- 定義線程個數
[maxscale] //定義線程個數
threads=auto
- 定義數據庫服務器
[server1] //master主機
type=server
address=192.168.4.51 //master主機IP地址
port=3306
protocol=MySQLBackend
[server2] //slave主機
type=server
address=192.168.4.52 //slave主機IP地址
port=3306
protocol=MySQLBackend
- 定義要監視的數據庫節點
[MySQL Monitor]
type=monitor
module=mysqlmon
servers=server1,server2 //主、從數據庫的主機名
user=haha //監控用戶
passwd=123456 //密碼必須符合server1和server2的密碼策略
monitor_interval=10000
- 把只讀服務相關的全部註釋掉
#[Read-Only Service] //註釋掉
#type=service
#router=readconnroute
#servers=server1
#user=myuser
#passwd=mypwd
#router_options=slave
- 定義讀寫分離的數據庫節點
路由用戶
用來連接server1和server2,
驗證客戶端訪問自己時,使用的用戶名密碼在server1和server2上是否存在
[Read-Write Service]
type=service
router=readwritesplit
servers=server1,server2 //主、從數據庫的主機名
user=hehe //路由用戶
passwd=123456 //必須符合server1和server2的密碼策略
max_slave_connections=100%
- 定義管理服務
[MaxAdmin Service] //管理服務
type=service
router=cli
//默認就好
- 把只讀服務相關的全部註釋掉
#[Read-Only Listener]
#type=listener
#service=Read-Only Service
#protocol=MySQLClient
#port=4008
- 定義讀寫分離服務端口號
[Read-Write Listener]
type=listener
service=Read-Write Service
protocol=MySQLClient
port=4006 //端口號可以自定義
- 定義管理服務端口號
[MaxAdmin Listener]
type=listener
service=MaxAdmin Service
protocol=maxscaled
socket=default
port=4016 //端口號可以自定義
2.2.4、創建監控用戶和路由用戶
在server1和server2上創建這兩個用戶
- 監控用戶haha
密碼123456 - 路由用戶hehe
密碼123456
- 在主服務器上創建
mysql> grant replication slave,
-> replication client
-> on *.* to haha@"%" identified by "123456";
mysql> grant select on mysql.* to hehe@"%" identified by "123456" ;
- 在從服務器上查詢
mysql> select user from mysql.user where user in ("haha","hehe");
2.2.5、啓動讀寫分離服務
- 啓動服務
[root@pxysvr ~]# maxscale -f /etc/maxscale.cnf
- 查看進程
[root@pxysvr ~]# ps -C maxscale
- 查看端口號
[root@pxysvr ~]# netstat -utnlp | grep maxscale
tcp6 0 0 :::4006 :::* LISTEN 1938/maxscale
tcp6 0 0 :::4016 :::* LISTEN 1938/maxscale
- 日誌文件存儲位置
由於服務啓動沒有任何的提示,所以查不到端口和進程就去看日誌。
/var/log/maxscale/maxscale.log
- 停止服務
kill -9 pid號
- 排錯方法
服務起不來時,使用killall maxscale 的方式結束掉所有進程
tail -f /var/log/maxscale/maxscale.log
//動態查看日誌信息
另開一終端執行
maxscale -f /etc/maxscale.cnf
2.3、測試配置
- 登錄
默認用戶admin,密碼mariadb
[root@pxysvr ~]# maxadmin -uadmin -pmariadb -P4016
- 查看服務器列表
MaxScale> list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server | Address | Port | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
server1 | 192.168.4.51 | 3306 | 0 | Master, Running
server2 | 192.168.4.52 | 3306 | 0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------
- 在主服務器上添加訪問數據的連接用戶
mysql> grant select , insert on buydb2.* to dachui@"%" identified by "123456";
Query OK, 0 rows affected, 1 warning (0.10 sec)
mysql> create database buydb2;
Query OK, 1 row affected (0.00 sec)
mysql> create table buydb2.t1(id int);
Query OK, 0 rows affected (0.01 sec)
- 在從服務器查看是否同步授權用戶
mysql> desc buydb2.t1
mysql> select user from mysql.user where user="dachui";
- 客戶端使用授權用戶訪問代理主機
[root@client ~]# mysql -h192.168.4.57 -P4006 -udachui -p123456
mysql> insert into buydb2.t1 values(999);
mysql> insert into buydb2.t1 values(998);
mysql> select * from buydb2.t1;
+------+
| id |
+------+
| 999 |
| 998 |
+------+
2 rows in set (0.00 sec)
- 驗證57主機可以實現數據讀寫分離
再從服務器上單獨插入一條數據,讓主從數據不一致。
從服務器插入數據
mysql> insert into buydb2.t1 values(123);
主服務器
mysql> select * from buydb2.t1;
+------+
| id |
+------+
| 999 |
| 998 |
+------+
2 rows in set (0.00 sec)
從服務器
mysql> select * from buydb2.t1;
+------+
| id |
+------+
| 999 |
| 998 |
| 123 |
+------+
3 rows in set (0.00 sec)
客戶端訪問
mysql> select * from buydb2.t1;
+------+
| id |
+------+
| 999 |
| 998 |
| 123 |
+------+
3 rows in set (0.00 sec)