MyCat做MySQL讀寫分離

     

轉載:http://bokek.cn/mycat-do-mysql-separate-read-and-write.html


前言:現在普遍的公司都是在用MySQL做數據持久化,但是稍微有點規模的網站就會發現,web應用做負載均衡什麼的,so easy,加臺機器,加個nginx前端代理服務器,可能稍微有一點點複雜的是使用redis或者memcache做一個session會話集中管理罷了,加了負載均衡後,瞬間感覺高大上了,兩個web應用負載分流龐大的用戶流量,然而然並卵,網站還是依舊的慢如蝸牛。。。,那個這個是什麼問題呢?可以解決嗎?

of course,像這種加了web負載沒效果的,我想定是mysql爆了,需要下點功夫在mysql或者是緩存上下點功夫了。

下面我就從mysql數據庫(架構)方便優化這個問題。

優化mysql的話,就需要考慮到mysql的集羣,做mysql的讀寫分離,就會使用到mysql的主從複製機制,和使用第三方中間件來實現了。

下面我就跟大家介紹其中一種中間件--mycat來實現mysql的讀寫分離。


1.參與機器

10.0.4.80 3306 主數據庫

10.0.4.101 3306 從數據庫,主80

10.0.4.105 3306 從數據庫,主101

10.0.4.102   mycat部署機器

2.搭建主從

1主2從,採用的是鏈式主從方案,可以詳細看上面的機器列表,就做了簡單的標記,已經配置好主從複製的,請跳過,沒有配置好的,請移步~~~

3.部署mycat

arc

mycat架構圖

Shell
1
2
3
4
5
6
#創建mycat部署目錄
mkdir /home/mycat
#下載mycat壓縮包
wget https://github.com/MyCATApache/Mycat-download/blob/master/1.5-RELEASE/Mycat-server-1.5.1-RELEASE-20160518143538-linux.tar.gz
#解壓mycat
tar zxvf Mycat-server-1.5.1-RELEASE-20160518143538-linux.tar.gz

4.配置主從

MyCat主從配置
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#打開配置讀寫分離的配置文件
vim mycat/conf/schema.xml
#打開以後按照如下配置
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >
 
        <!-- 配置mycat邏輯庫,類似爲mysql的數據庫,用法和mysql數據庫無異  -->
        <schema name="bokek" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
                <!-- 這裏配置表的分庫和分片的,不在本文的分享之內,所有就留空白,不做說明 -->
        </schema>
        <!--配置數據庫節點-->
        <dataNode name="dn1" dataHost="localhost1" database="bkk_dev" />
        <!--配置數據節點,讀寫分離的重頭戲,請仔細看-->
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0"
                  dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
                <heartbeat>show slave status</heartbeat>
                <!-- 主庫,寫節點 -->
                <writeHost host="hostM1" url="10.0.4.80:3306" user="root"
                        password="bokek80">
                        <!-- 從庫,都節點 -->
                        <readHost host="hostS2" url="10.0.4.101:3306" user="root" password="bokek101" />
                </writeHost>
                <!--主故障,頂替寫節點,主正常是分擔都讀壓力-->
                <writeHost host="hostS1" url="10.0.4.105:3306" user="root" password="bokek105" />
        </dataHost>
</mycat:schema>

配置詳解:

schema 標籤用於定義MyCat實例中的逡輯庫,MyCat可以有對個邏輯庫,每個邏輯庫都有自身的相關配置。可以使用 schema 標籤來劃分返回不同的邏輯。 如果丌配置 schema 標籤,所有癿表配置,會屬二同一個默訃的邏輯庫。

             name 該屬性配置邏輯庫的名字,類似mysql的數據庫名稱

             dataNode 該屬行用綁定輯庫刡某個具體的database上,1.3版本如果配置了dataNode,則不可以配置分片表,1.4可以配置默認分片,叧需要配置需要分片的表即可,具體如下配置:

mycat1.3配置
Shell
1
2
3
<schema name="bokek" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
    <!—裏面不能配置仸何表-->
</schema>

mycat1.5配置
Shell
1
2
3
4
<schema name="bokek" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn12">
    <!—配置需要分片的表-->
    <table name=tb_order” dataNode=dn2/>
</schema>

        checkSQLschema 當該屬性值設置爲 true 時,如果我們執行語句  select * from bokek.mycat_sequence_test;  則MyCat會把語句修改爲  select * from mycat_sequence_test; 。即把表示schema的字符去掉,避免發送到後端數據庫執行時報 (ERROR 1146 (42S02): Table ‘bokek.mycat_sequence_test’ doesn’t exist)。不過,即使設置該值爲 true ,如果語句所帶來的是並非是schema指定的名字,例如:  select * from bokek.mycat_sequence_test;   那麼MyCat並不會刪除bokek這個字段,如果沒有定義詮庫癿話則會報錯,所以在提供SQL詢句癿最好是不要帶這個字段。

            sqlMaxLimit 當該值設置爲某個數值時。每條執行的SQL詢句,如果沒有加上limit語句,MyCat也會自動的加上所對應的值。例如設置爲100,執行  select * from bokek.mycat_squeuce_test;  的效果爲與執行  select * from bokek.mycat_squeuece_test limit 100;  相同。 不設置該值的話,MyCat默認會把查詢到的信息全部都展示出來,造成過多的輸出。所以,在正常使用中,迓是建議加上一個值,用與減少過多的數據返回。當然SQL語句可以顯式的設置limit的大小,不受該屬性的任何約束。 需要注意的事,如果運行的schema爲非拆分庫時,那麼該屬性則不會生效。需要手動添加limit語句。

dataNode 標籤

數據節點,數據分片
Shell
1
<dataNode name="dn1" dataHost="localhost1" database="bkk_dev" />

dataNode 標籤定義了MyCat中的數據節點,也就是我們通常說所的數據分片。一個dataNode標籤就是一個獨立的數據分片。

例子中所表述的意思爲:使用名字爲localhost1數據庫實例上的bkk_dev物理數據庫,這就組成一個數據分片,最後,我們使用名字dn1標識這個分片。

name 該屬性定義數據節點的名字,這個名字需要唯一的,我們需要在table標籤上應用這個名字,來建立表不分片對應的關係。

dataHost 該屬性用於定義該分片屬於哪個數據庫實例上,該屬性值是引用dataHost標籤上定義的name屬性。

database 該屬性用於定義該分片屬於哪個數據庫實例上的具體的那個數據庫,因爲這裏使用兩個緯度來定義分片,就是:實例+具體的庫。因爲每個庫上建立的表和表結構是一樣的。所以這樣做就可以輕鬆的對錶進行水平拆分。

dataHost 標籤 作爲Schema.xml中最後的一個標籤,該標籤在mycat邏輯庫中也是作爲最底層的標籤存在,直接定義了具體的數據庫實例、讀寫分離配置和心跳語句。現在我們就解析下這個標籤。

dataHost標籤配置
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
<!--配置數據節點,讀寫分離的重頭戲,請仔細看-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0"
    dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
    <heartbeat>show slave status</heartbeat>
    <!-- 主庫,寫節點 -->
    <writeHost host="hostM1" url="10.0.4.80:3306" user="root"
        password="bokek80">
    <!-- 從庫,都節點 -->
    <readHost host="hostS2" url="10.0.4.101:3306" user="root" password="bokek101" />
    </writeHost>
    <!--主故障,頂替寫節點,主正常是分擔都讀壓力-->
    <writeHost host="hostS1" url="10.0.4.105:3306" user="root" password="bokek105" />
</dataHost>

    name 該屬性唯一標示dataHost標籤,供上層的標籤使用。

    maxCon 該屬性指定每個實例連接池的最多連接。也就是說,標籤內嵌套的writeHost、readHost標籤都會使用這個屬性的值來實例化出連接池的最多連接數。

    minCon 該屬性指定每個讀寫實例連接池的最小連接,初始化連接池的大小。

    balance 屬性,負載均衡類型,目前的值有3種:

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不負擔讀壓力,注意balance=3

    writeType 屬性

負載均衡類型,目前的取值有3種:

1. writeType="0", 所有寫操作發送到配置的第一個writeHost,第一個掛了切換到還生存的第二個writeHost,重新啓動後已切換後的爲準,切換記錄在配置文件中:dnindex.properties .

2. writeType="1",所有寫操作都隨機的發送到配置的writeHost,1.5以後廢棄不推薦使用。

    switchType 屬性

-1 表示不自動切換

1 默認值,自動切換

2 基二MySQL主從同步的狀態決定是否切換

    dbType 屬性

指定後端連接數據庫類型,目前支持二進制的mysql協議,還有其他使用JDBC連接的數數據庫。例如:mongodb、oracle、spark等。

    dbDriver 屬性

指定連接後端數據庫使用的Driver,目前可選的值有native和JDBC。使用native的話,因爲這個值執行的是二進制的mysql協議,所以可使用mysql和maridb。其他類型的數據庫需要使用JDBC驅勱來支持。

如果使用JDBC的話需要將符合JDBC 4標準的驅動JAR包放刡MYCAT\lib目錄下,並檢查驅勱JAR包中包括如下目錄結構的文件:META-INF\services\java.sql.Driver。在這個文件內寫上具體的Driver類名,例如:com.mysql.jdbc.Driver。

switchType 屬性

-1 表示丌自勱切換

1 默訃值,自勱切換

2 基二MySQL主僅同步癿狀懺決定是否切換 心跳詢句爲 show slave status

3 基二MySQL galary cluster癿切換機刢(適吅集羣)(1.4.1) 心跳詢句爲 show status like ‘wsrep%’.

tempReadHostAvailable 屬性

如果配置了返個屬忓writeHost 下面癿readHost仄舊可用,默訃0 可配置(0、1)。

heartbeat 標籤

這個標籤內指明於和後端數據庫進行心跳檢查的詢句。例如,MYSQL可以使用select user(),Oracle可以使用select 1 from dual等。 這個標籤還有一個connectionInitSql屬性,主要是當使用Oracla數據庫時,需要執行的初始化SQL語句就這個放到這裏面來。例如:alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss' 1.4主從切換的語句必項是:show slave status
writeHost標籤、readHost標籤

這兩個標籤都指定後端數據庫的相關配置給mycat,用與實例化後端連接池。唯一不同的是,writeHost指定寫實例、readHost指定讀實例,組裝這些讀寫實例來滿足系統的要求。

在一個dataHost內可以定義多個writeHost和readHost。但是,如果writeHost指定的後端數據庫宕機,那麼這個writeHost綁定的所有readHost都將不可用。另一方面,由於這個writeHost宕機系統會自動的檢測到,並切換到備用的writeHost上去。 這兩個標籤的屬性相同,這裏就一起介紹。

host屬性

用與標識不同實例,一般writeHost我們使用*M1,readHost我們用*S1。
url屬性

後端實例連接地址,如果是使用native的dbDriver,則一般爲address:port返種形式。用JDBC或其他的dbDriver,則需要特殊指定。當使用JDBC時則可以這麼寫:jdbc:mysql://localhost:3306/。

user屬性

後端物理數據數據實例所需要的用戶名

password屬性

後端物理數據數據實例所需要的密碼

weight 屬性

權重 配置在readhost 中作爲讀節點的權重

usingDecrypt 屬性

是否對密碼加密默認0 否 如需要開啓配置1,同時使用加密程序對密碼加密,加密命令爲: 執行mycat.jar 程序

 

生成加密username、password
Shell
1
java -cp Mycat-server-1.4.1-dev.jar org.opencloudb.util.DecryptUtil 1:host:user:password Mycat-server-1.4.1-dev.jarmycat download 下載目錄的jar 1:host:user:password 1db後加密標識,hostdataHosthost 名稱

server.xml配置文件

server.xml幾乎保存了所有mycat需要的系統配置信息。

配置用戶信息
Shell
1
2
3
4
5
6
7
<user name="test">
    <property name="password">test</property>
    <property name="schemas">bokek</property>
    <property name="readOnly">true</property>
    <property name="benchmark">11111</property>
    <property name="usingDecrypt">1</property>
</user>

server.xml中的標籤本就不多,這個標籤主要用與定義登陸mycat的用戶權限。例如上面的例子中,我定義了一個用戶,用戶名爲test、密碼也爲test,可訪問的schema也只有bokek一個。 如果我在schema.xml中定義了多個schema,那麼這個用戶是無法訪問其他的schema。在mysql客戶端看來則是無法使用use切換到其他的數據庫。

如果使用了use命令,則mycat會報出這樣的錯誤提示:

 

使用了user命令,錯誤提示
Shell
1
ERROR 1044 (HY000): Access denied for user 'test' to database 'xxx'

這個標籤嵌套的property標籤則是具體聲明的屬性值,正如上面的例子。我們可以修改user標籤的name屬性來指定用戶名;修改password內的文本來修改密碼;修改readOnly爲true 或false來限制用戶是否叧是可讀的;修改schemas內的文本來控制用戶可訪問的schema;修改schemas內的文本來控制用戶可訪問的schema,同時訪問多個schema的話使用 , 隔開,例如:

 

配置多個邏輯庫權限
1
<property name="schemas">bokek,bokek1,bokek2</property>

Benchmark屬性

 

Shell
1
2
3
Benchmark:mycat連接服務降級處理:
benchmark 基準, 當前端的整體connection數達到基準值是, 對來自該賬戶的請求開始拒絕連接,0或不設表示不限制
例如 <property name="benchmark">1000</property>

usingDecrypt 屬性

是否對密碼加密默認0 否 如需要開啓配置1,同時使用加密程序對密碼加密,加密命令爲: 執行mycat jar 程序:

 

加密密碼
Shell
1
2
3
java -cp Mycat-server-1.4.1-dev.jar org.opencloudb.util.DecryptUtil 0:user:password
Mycat-server-1.4.1-dev.jarmycat download 下載目錄的jar
1:host:user:password 0 爲前端加密標識

system標籤

字符集設置:

配置charset
Shell
1
2
3
4
5
6
7
8
9
10
11
配置屬性charset
<system>
<property name="charset">utf8</property>
</system>
如果需要配置utf8mb2等特殊字符集可以在
index_to_charset.properties 配置中 配置數據庫短的字符集ID=字符集
例如: 224=utf8mb4
 
配置字符集的時候一定要堅持mycat的字符集與後端數據庫的字符集是一致的,可通過變量來查詢:
show variables like 'collation_%';
show variables like 'character_set_%';

defaultSqlParser屬性

由與mycat最初的時候Foundation DB的sql解析器,而後來才添加Druid的解析器。所以這個屬性用來指定默認的解析器。目前的可用的取值有:druidparser和 fdbparser。使用的時候可以選擇其中的一種,目前一般都使用druidparser。 1.3 解析器默認爲fdbparser,1.4 默認爲druidparser,1.4以後fdbparser作廢。

processors屬性

這個屬性主要用二進制系統可用的線程數,默認值爲機器CPU核心線程數。 主要影響processorBufferPool、processorBufferLocalPercent、processorExecutor屬性。NIOProcessor的個數也是由這個屬性定義的,所以調優的時候可以適當的調高這個屬性。

processorBufferChunk屬性

這個屬性指定每次分配Socket Direct Buffer的多小,默認是4096個字節。這個屬性也影響buffer pool的長度。如果一次性獲取的數過大buffer不夠用 經常出現警告,則可以適當調大。

processorBufferPool屬性

這個屬性指定bufferPool計算 比例值。由於每次執行NIO讀、寫操作都需要使用到buffer,系統初始化的時候會建立一定長度的buffer池來加快讀、寫的效率,減少建立buffer的時間。

Mycat中有兩個主要的buffer池:

BufferPool

ThreadLocalPool

BufferPool由ThreadLocalPool組合而成,每次僅BufferPool中獲取buffer都會優先獲取ThreadLocalPool中的buffer,未命中之後纔會去獲取BufferPool中的buffer。也就是該ThreadLocalPool是作爲BufferPool的二級緩存,每個線程內部自己使用。當然,這其中還有一寫限制條件需要線程的名字是由$_開頭。然後,BufferPool上的buffer則是每個NIOProcessor都共享的。

默認這個屬性的值爲: 默認bufferChunkSize(4096) * processors屬性 * 1000
BufferPool癿總長度 = bufferPool / bufferChunk。

若bufferPool不是bufferChunk的整數倍,則總長度爲前面計算得出的商 + 1 假設系統xianc爲4,其仈都爲屬忓癿默訃值,則: bufferPool = 4096 * 4 * 1000 BufferPool癿總長度 : 4000 = 16384000 / 4096

3K~DDR6WU{]~_6HN_)%FFPY

processorBufferLocalPercent屬性

前面提到了ThreadLocalPool。這個屬性就是用來控制分配這個pool的大小用的,但其也並不是一個準確的值,也是一個比例值。返個屬性默認值爲100。

線程緩存百分比 = bufferLocalPercent / processors屬性。

例如,系統可以同時運行4個線程,使用默認值,則根捤公式每個線程的百分比爲25。

最後根據這個百分比來計算出具體的ThreadLocalPool的長度公式如下:

ThreadLocalPool癿長度 = 線程緩存百分比 * BufferPool長度 / 100

假設BufferPool的長度爲 4000,其他保持默認值。

那麼最後每個線程建立上的ThreadLocalPool癿長度爲: 1000 = 25 * 4000 / 100

processorExecutor屬性

這個屬性主要用於指定NIOProcessor上共享的businessExecutor固定線程池大小。mycat在需要處理一些異步邏輯時候會把仸務提交到這個線程池中。新版本中這個連接池的使用頻率不是特別大,可以設置一個較小的值。

sequnceHandlerType屬性

指定使用Mycat全局序列類型。0爲本地文件方式,1爲數捤庫方式,2爲時間戳序列方式。

默認是使用本地文件方式0,文件使用方式主要用於測試使用。

TCP連接相關屬性

StandardSocketOptions.SO_RCVBUF
StandardSocketOptions.SO_SNDBUF
StandardSocketOptions.TCP_NODELAY
以上這三個屬性,分別由:

frontSocketSoRcvbuf 默認值: 1024 * 1024

frontSocketSoSndbuf 默認值: 4 * 1024 * 1024

frontSocketNoDelay  默認值: 1

backSocketSoRcvbuf 默認值: 4 * 1024 * 1024

backSocketSoSndbuf 默認值: 1024 * 1024

backSocketNoDelay   默認值: 1

各自設置TCP連接參數。Mycat在每次建立前、後端連接的時候都會使用這些參數初始化連接。可以按系統要求適當調整這些buffer的大小。TCP連接參數的定義,可以查看Javadoc。

Mysql連接相關屬性

初始化mysql前後端連接所涉及到的一些屬性:

packetHeaderSize : 指定Mysql協議中的報文頭長度。默認4。

maxPacketSize : 指定Mysql協議可以攜帶數據的最大長度。默認16M。

idleTimeout : 指定連接的空閒超時時間。某連接在發起空閒檢查下,發現距離上次使用超過了空閒時間,那麼這個連接就會被回收,就是被直接的關閉掉。默認30分鐘,單位毫秒。

charset : 連接的初始化字符集。默認爲utf8。

txIsolation : 前端連接的初始化亊務隔離級別,叧在初始化的時候使用,後續會根據客戶端傳過來的屬性對後端數據庫連接進行同步。默認爲REPEATED_READ,設置值爲數字默認3。

READ_UNCOMMITTED = 1;

READ_COMMITTED = 2;

REPEATED_READ = 3;

SERIALIZABLE = 4;

sqlExecuteTimeout:SQL執行超時時間,Mycat會檢查連接上最後一次執行SQL的時間,若超過這個時間則會直接關閉這個連接。默認時間爲300秒,單位秒。

心跳屬性

mycat中有幾個週期性的任務來異步的處理一互我需要的工作。這些屬性就在系統調優的過程中也是必不可少的。

processorCheckPeriod : 清理NIOProcessor上前後端空閒、超時和關閉連接的間隔時間。默認是1秒,單位毫秒。。

dataNodeIdleCheckPeriod : 對後端連接進行空閒、超時檢查的時間間隔,默認是300秒,單位毫秒。

dataNodeHeartbeatPeriod : 對後端所有讀、寫庫發起心跳的間隔時間,默認是10秒,單位毫秒。

服務相關屬性

這裏介紹一個與服務相關的屬性,主要會影響外部系統對myact的感知。

bindIp : mycat服務監聽的IP地址,默認值爲0.0.0.0。

serverPort : 定義mycat癿使用竢口,默認值爲8066。

managerPort : 定義mycat癿管理竢口,默認值爲9066。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章