什麼是讀寫分離html
在數據庫集羣架構中,讓主庫負責處理事務性查詢,而從庫只負責處理select查詢,讓二者分工明確達到提升數據庫總體讀寫性能。固然,主數據庫另一個功能就是負責將事務性查詢致使的數據變動同步到從庫中,也就是寫操做。java
讀寫分離的好處mysql
1)分攤服務器壓力,提升機器的系統處理效率
讀寫分離適用於讀遠比寫的場景,若是有一臺服務器,當select不少時,update和delete會被這些select訪問中的數據堵塞,等待select結束,併發性能並不高,而主從只負責各自的寫和讀,極大程度的緩解X鎖和S鎖爭用;
假如咱們有1主3從,不考慮上述1中提到的從庫單方面設置,假設如今1分鐘內有10條寫入,150條讀取。那麼,1主3從至關於共計40條寫入,而讀取總數沒變,所以平均下來每臺服務器承擔了10條寫入和50條讀取(主庫不承擔讀取操做)。所以,雖然寫入沒變,可是讀取大大分攤了,提升了系統性能。另外,當讀取被分攤後,又間接提升了寫入的性能。因此,整體性能提升了,說白了就是拿機器和帶寬換性能;
2)增長冗餘,提升服務可用性,當一臺數據庫服務器宕機後能夠調整另一臺從庫以最快速度恢復服務linux
Mycat原理
Mycat是一個開源的分佈式數據庫系統,可是由於數據庫通常都有本身的數據庫引擎,而Mycat並無屬於本身的獨有數據庫引擎,全部嚴格意義上說並不能算是一個完整的數據庫系統,只能說是一個在應用和數據庫之間起橋樑做用的中間件。git
在Mycat中間件出現以前,MySQL主從複製集羣,若是要實現讀寫分離,通常是在程序段實現,這樣就帶來了一個問題,即數據段和程序的耦合度過高,若是數據庫的地址發生了改變,那麼個人程序也要進行相應的修改,若是數據庫不當心掛掉了,則同時也意味着程序的不可用,而對於不少應用來講,並不能接受;github
引入Mycat中間件能很好地對程序和數據庫進行解耦,這樣,程序只需關注數據庫中間件的地址,而無需知曉底層數據庫是如何提供服務的,大量的通用數據聚合、事務、數據源切換等工做都由中間件來處理;
Mycat中間件的原理是對數據進行分片處理,從原有的一個庫,被切分爲多個分片數據庫,全部的分片數據庫集羣構成完成的數據庫存儲,有點相似磁盤陣列中的RAID0.web
Mycat配置安裝sql
環境準備:保證多實例/data/3306/和/data/3307已經實現簡單異步主從複製
1)安裝JDK
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
#注意版本必須JDK7或者更高版本數據庫
[root@db02 tools]# rpm -ivh jdk-8u91-linux-x64.rpm
Preparing... ########################################### [100%]
1:jdk1.8.0_91 ########################################### [100%]
#我這裏下載的rpm包,安裝比較方便vim
2)下載Mycat
https://github.com/MyCATApache/Mycat-download#
# 這裏測試用的是Mycat-server-1.4-release版本
解壓拷貝到/application/mycat目錄
3)建立用戶
主庫,web用戶有增刪改查權限
mysql> grant select,update,delete,insert on lilongzi.* to web@'172.16.2.%' identified
by'123456';
從庫因爲只負責讀數據,全部web只有select權限
mysql> grant select on lilongzi.* to web@'172.16.2.%' identified by '123456';
4)修改配置文件
[root@db02 conf]# vim /application/mycat/conf/server.xml #MyCAT對外的「虛擬數據庫」配置文件
s">32</property> -->
</system>
<user name="web"> #web爲主庫和分庫剛創建的用戶
<property name="password">123456</property> #用戶密碼
<property name="schemas">lilongzi</property> #數據庫名稱
</user>
<user name="web_r"> #web_r表示只給讀權限
<property name="password">123456</property>
<property name="schemas">lilongzi</property>
<property name="readOnly">true</property>
</user>
[root@db02 conf]# vim /application/mycat/conf/server.xml #詳細主庫及讀寫分離模式配置文件
<schema name="lilongzi" checkSQLschema="false" sqlMaxLimit="100"
dataNode="dn1">
#name=你的數據庫名 ,添加dataNode="dn1" 表示數據庫只在dn1上,沒有分庫
<table name="test" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
#table修改成你的表名,若是有多張表,能夠按照這個格式添加
</schema>
<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
/> -->
<dataNode name="dn1" dataHost="localhost1" database="lilongzi" />
<dataNode name="dn2" dataHost="localhost1" database="lilongzi" />
<dataNode name="dn3" dataHost="localhost1" database="lilongzi" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="172.16.2.10:3306" user="web"
password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS1" url="172.16.2.10:3307" user="web"
password="123456" />
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root"
password="123456"/> -->
</dataHost>
這裏面,有兩個參數須要注意,balance和 switchType。
其中,balance指的負載均衡類型,目前的取值有4種:
1. balance="0", 不開啓讀寫分離機制,全部讀操做都發送到當前可用的writeHost上。
2. balance="1",所有的readHost與stand by writeHost參與select語句的負載均衡,簡單的說,當雙主雙從模式(M1->S1,M2->S2,而且M1與 M2互爲主備),正常狀況下,M2,S1,S2都參與select語句的負載均衡。
3. balance="2",全部讀操做都隨機的在writeHost、readhost上分發。
4. balance="3",全部讀請求隨機的分發到wiriterHost對應的readhost執行,writerHost不負擔讀壓力
writeType表示寫模式
writeType="0",全部的操做發送到配置的第一個writehost
writeType="1",隨機發送到配置的全部writehost
writeType="2",不執行寫操做
switchType指的是切換的模式,目前的取值也有4種:
1. switchType='-1' 表示不自動切換
2. switchType='1' 默認值,表示自動切換
3. switchType='2' 基於MySQL主從同步的狀態決定是否切換,心跳語句爲 show slave status
4. switchType='3'基於MySQL galary cluster的切換機制(適合集羣)(1.4.1),心跳語句爲 show status like 'wsrep%'。
5)啓動Mycat
[root@db02 bin]# ./mycat console &
Running Mycat-server...
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
jvm 1 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 | log4j 2016-07-09 06:04:28 [./conf/log4j.xml] load completed.
jvm 1 | MyCAT Server startup successfully. see logs in logs/mycat.log
[root@db02 bin]# lsof -i:{8066,9066}
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 87340 root 46u IPv6 212352 0t0 TCP *:9066 (LISTEN) #虛擬schema管理端口
java 87340 root 50u IPv6 212354 0t0 TCP *:8066 (LISTEN) #虛擬schema登錄端口
#能看到這個說明我們的Mycat已經啓動成功了
6)接下來咱們就要驗證一下否真的已經實現讀寫分離...
方法:
停掉從庫的SQL線程,讓從庫雖然讀取到了主庫的binlog,可是不能發起SQL線程寫入到本身的數據庫中,這樣咱們模擬訪問,插入一條數據,在主庫中應該能看到新插入的數據,可是模擬訪問的客戶端卻看不到,就說明讀寫分離成功。
咱們在其餘主機A上模擬web用戶訪問登錄查看數據
[root@m01 ~]# mysql -uweb -p123456 -h172.16.2.10 -P8066 #注意這裏使用虛擬schema的登錄端口8066
mysql> show databases;
+----------+
| DATABASE |
+----------+
| lilongzi |
+----------+
1 row in set (0.00 sec)
mysql> use lilongzi;
Database changed
mysql> show tables;
+--------------------+
| Tables in lilongzi |
+--------------------+
| customer |
| customer_addr |
| employee |
| goods |
| hotnews |
| orders |
| order_items |
| test | #test爲咱們改過的表
| travelrecord |
+--------------------+
9 rows in set (0.00 sec)
mysql> select * from test;
+----+--------+
| id | name |
+----+--------+
| 1 | 小明 |
+----+--------+
1 row in set (0.00 sec)
咱們停掉從庫3307的SQL線程
mysql> stop slave sql_thread;
Query OK, 0 rows affected (0.00 sec)
在主機A遠程插入一條數據test
mysql> insert into test values(2,'test2');
ERROR 1105 (HY000): Duplicate entry '2' for key 'PRIMARY'
mysql> select * from test;
+----+--------+
| id | name |
+----+--------+
| 1 | 小明 | #立馬查一下發現是看不到的
+----+--------+
1 row in set (0.01 sec)
可是在主庫上面
mysql> select * from test;
+----+--------+
| id | name |
+----+--------+
| 1 | 小明 |
| 2 | test2 | #顯示已經寫入成功
+----+--------+
2 rows in set (0.00 sec)
從庫這邊
mysql> select * from test;
+----+--------+
| id | name |
+----+--------+
| 1 | 小明 | #一樣看不到
+----+--------+
1 row in set (0.00 sec)
MyCAT實現MySQL讀寫分離實踐 http://www.linuxidc.com/Linux/2016-01/127957.htm
MyCAT實現MySQL的讀寫分離 http://www.linuxidc.com/Linux/2016-01/127555.htm
MyCAT ER分片的驗證 http://www.linuxidc.com/Linux/2016-02/128636.htm
LVS+Keepalived搭建MyCAT高可用負載均衡集羣 http://www.linuxidc.com/Linux/2016-03/129231.htm