為什么需要讀寫分離
至于為什么需要讀寫分離囤踩,在我之前的文章有介紹過了蔬捷,相信看到這篇文章的人也知道為什么需要讀寫分離了幔翰,當然如果你也需要了解一下凭疮,那么歡迎查看我之前的文章SpringBoot Mybatis 讀寫分離配置,順便也可以了解一下怎么通過代碼進行讀寫分離的
MySQL主從復制
主從復制是讀寫分離的關(guān)鍵,不管通過什么方式進行讀寫分離膛腐,前提就是MySQL有主從復制睛约,當前雙機主從也行,但是關(guān)鍵的關(guān)鍵哲身,是要能保證2個庫的數(shù)據(jù)能一致(出掉剛寫入主庫從庫還未能及時反應過來的情況)辩涝,如果2個庫的數(shù)據(jù)不一致,那么讀寫分離也有沒有任何意義了勘天,具體MySQL怎么做主從復制可以查看我之前的文章MySQL主從復制搭建怔揩,基于日志(binlog)
Mycat是什么
一個徹底開源的,面向企業(yè)應用開發(fā)的大數(shù)據(jù)庫集群
支持事務(wù)脯丝、ACID商膊、可以替代MySQL的加強版數(shù)據(jù)庫
一個可以視為MySQL集群的企業(yè)級數(shù)據(jù)庫,用來替代昂貴的Oracle集群
一個融合內(nèi)存緩存技術(shù)宠进、NoSQL技術(shù)晕拆、HDFS大數(shù)據(jù)的新型SQL Server
結(jié)合傳統(tǒng)數(shù)據(jù)庫和新型分布式數(shù)據(jù)倉庫的新一代企業(yè)級數(shù)據(jù)庫產(chǎn)品
一個新穎的數(shù)據(jù)庫中間件產(chǎn)品
以上內(nèi)容來自Mycat官網(wǎng),簡單來說材蹬,Mycat就是一個數(shù)據(jù)庫中間件实幕,對于我們開發(fā)來說,就像是一個代理堤器,當我們需要使用到多個數(shù)據(jù)庫和需要進行分庫分表的時候昆庇,我們只需要在mycat里面配置好相關(guān)規(guī)則,程序無需做任何修改闸溃,只是需要將原本的數(shù)據(jù)源鏈接到mycat而已整吆,當然如果以前有多個數(shù)據(jù)源,需要將數(shù)據(jù)源切換為單個數(shù)據(jù)源圈暗,這樣有個好處就是當我們的數(shù)據(jù)量已經(jīng)很大的時候掂为,需要開始分庫分表或者做讀寫分離的時候,不用修改代碼(只需要改一下數(shù)據(jù)源的鏈接地址)
Mycat讀寫分離設(shè)置
配置Mycat用戶
Mycat的用戶就跟MySQL用戶是同一個意思员串,主要配置鏈接到Mycat的用戶名以及密碼,以及能使用的邏輯庫昼扛,用戶信息主要在server.xml中配置的寸齐,具體如下
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="defaultSqlParser">druidparser</property>
<!-- <property name="useCompression">1</property>--> <!--1為開啟mysql壓縮協(xié)議-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默認是65535 64K 用于sql解析時最大文本長度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="mutiNodeLimitType">1</property> 0:開啟小數(shù)量級(默認) 欲诺;1:開啟億級數(shù)據(jù)排序
<property name="mutiNodePatchSize">100</property> 億級數(shù)量排序批量
<property name="processors">32</property> <property name="processorExecutor">32</property>
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
</system>
<user name="raye">
<property name="password">rayewang</property>
<property name="schemas">separate</property>
</user>
</host>
</mycat:server>
其中<user name="raye">
定義了一個名為raye的用戶,標簽user中的<property name="password">rayewang</property>
定義了用戶的密碼渺鹦,<property name="schemas">separate</property>
定義了用戶可以使用的邏輯庫
配置Mycat邏輯庫
Mycat的配置有很多扰法,不過因為我們只是使用Mycat的讀寫分類的功能,所以用到的配置并不多毅厚,只需要配置一些基本的塞颁,當然本文也只是會介紹到讀寫分離相關(guān)的配置,其他配置建議讀者自己查看一下文檔吸耿,或者通過其他方式了解祠锣,邏輯庫是在schema.xml
中配置的
首先介紹Mycat邏輯庫中的一些配置標簽
schema
schema
標簽是用來定義邏輯庫的,schema
有四個屬性dataNode
,checkSQLschema
,sqlMaxLimit
,name
dataNode
標簽屬性用于綁定邏輯庫到某個具體的 database 上咽安,1.3 版本如果配置了 dataNode伴网,則不可以配置分片表,1.4 可以配置默認分片妆棒,只需要配置需要分片的表即可
name
是定義當前邏輯庫的名字的澡腾,方便server.xml
中定義用戶時的引用
checkSQLschema
當該值設(shè)置為 true 時,如果我們執(zhí)行語句select * from separate.users;則 MyCat 會把語句修改
為select * from users;糕珊。即把表示 schema 的字符去掉动分,避免發(fā)送到后端數(shù)據(jù)庫執(zhí)行時報(ERROR 1146 (42S02): Table ‘separate.users’ doesn’t exist)。
不過红选,即使設(shè)置該值為 true 刺啦,如果語句所帶的是并非是 schema 指定的名字,例如:select * from db1.users; 那么 MyCat 并不會刪除 db1 這個字段纠脾,如果沒有定義該庫的話則會報錯玛瘸,所以在提供 SQL語句的最好是不帶這個字段。
sqlMaxLimit
當該值設(shè)置為某個數(shù)值時苟蹈。每條執(zhí)行的 SQL 語句糊渊,如果沒有加上 limit 語句,MyCat 也會自動的加上所對應的值慧脱。例如設(shè)置值為 100渺绒,執(zhí)行select * from users;的效果為和執(zhí)行select * from users limit 100;相同。設(shè)置該值的話菱鸥,MyCat 默認會把查詢到的信息全部都展示出來宗兼,造成過多的輸出。所以氮采,在正常使用中殷绍,還是建議加上一個值,用于減少過多的數(shù)據(jù)返回鹊漠。當然 SQL 語句中也顯式的指定 limit 的大小主到,不受該屬性的約束茶行。需要注意的是,如果運行的 schema 為非拆分庫的登钥,那么該屬性不會生效畔师。需要手動添加 limit 語句。
schema
標簽中有標簽table
用于定義不同的表分片信息牧牢,不過我們只是做讀寫分離看锉,并不會用到,所以這里就不多介紹了
dataNode
dataNode
dataNode 標簽定義了 MyCat 中的數(shù)據(jù)節(jié)點塔鳍,也就是我們通常說所的數(shù)據(jù)分片伯铣。一個 dataNode 標簽就是一個獨立的數(shù)據(jù)分片,dataNode
有3個屬性:name
,dataHost
,database
。
name
定義數(shù)據(jù)節(jié)點的名字献幔,這個名字需要是唯一的懂傀,此名字是用于table
標簽和schema
標簽中引用的
dataHost
該屬性用于定義該分片屬于哪個數(shù)據(jù)庫實例的,屬性值是引用 dataHost 標簽上定義的 name 屬性
database
該屬性用于定義該分片屬性哪個具體數(shù)據(jù)庫實例上的具體庫蜡感,因為這里使用兩個緯度來定義分片蹬蚁,就是:實例+具體的庫。因為每個庫上建立的表和表結(jié)構(gòu)是一樣的郑兴。所以這樣做就可以輕松的對表進行水平拆分
dataHost
dataHost
是定義真實的數(shù)據(jù)庫連接的標簽犀斋,該標簽在 mycat 邏輯庫中也是作為最底層的標簽存在,直接定義了具體的數(shù)據(jù)庫實例情连、讀寫分離配置和心跳語句叽粹,dataHost
有7個屬性:name
,maxCon
,minCon
,balance
,writeType
,dbType
,dbDriver
,有2個標簽heartbeat
,writeHost
,其中writeHost
標簽中又包含一個readHost
標簽
name
唯一標識 dataHost 標簽,供dataNode
標簽使用
maxCon
指定每個讀寫實例連接池的最大連接却舀。也就是說虫几,標簽內(nèi)嵌套的 writeHost、readHost 標簽都會使用這個屬性的值來實例化出連接池的最大連接數(shù)
minCon
指定每個讀寫實例連接池的最小連接挽拔,初始化連接池的大小
balance
讀取負載均衡類型
balance="0", 不開啟讀寫分離機制辆脸,所有讀操作都發(fā)送到當前可用的 writeHost 上。
balance="1"螃诅,全部的 readHost 與 stand by writeHost 參與 select 語句的負載均衡啡氢,簡單的說,當雙主雙從模式(M1->S1术裸,M2->S2倘是,并且 M1 與 M2 互為主備),正常情況下袭艺,M2,S1,S2 都參與 select 語句的負載均衡搀崭。
balance="2",所有讀操作都隨機的在 writeHost匹表、readhost 上分發(fā)门坷。
balance="3"宣鄙,所有讀請求隨機的分發(fā)到 wiriterHost 對應的 readhost 執(zhí)行袍镀,writerHost 不負擔讀壓力
writeType
寫入負載均衡類型默蚌,目前的取值有 3 種:
writeType="0", 所有寫操作發(fā)送到配置的第一個 writeHost,第一個掛了切到還生存的第二個writeHost苇羡,重新啟動后已切換后的為準绸吸,切換記錄在配置文件中:dnindex.properties .
writeType="1",所有寫操作都隨機的發(fā)送到配置的 writeHost
dbType
指定后端連接的數(shù)據(jù)庫類型设江,目前支持二進制的 mysql 協(xié)議锦茁,還有其他使用 JDBC 連接的數(shù)據(jù)庫。例如:mongodb叉存、oracle码俩、spark 等
dbDriver
指定連接后端數(shù)據(jù)庫使用的 Driver,目前可選的值有 native 和 JDBC歼捏。使用 native 的話稿存,因為這個值執(zhí)行的
是二進制的 mysql 協(xié)議,所以可以使用 mysql 和 maridb瞳秽。其他類型的數(shù)據(jù)庫則需要使用 JDBC 驅(qū)動來支持瓣履。從 1.6 版本開始支持 postgresql 的 native 原始協(xié)議。
如果使用 JDBC 的話需要將符合 JDBC 4 標準的驅(qū)動 JAR 包放到 MYCAT\lib 目錄下练俐,并檢查驅(qū)動 JAR 包中包括如下目錄結(jié)構(gòu)的文件:META-INF\services\java.sql.Driver袖迎。在這個文件內(nèi)寫上具體的 Driver 類名,例如:
com.mysql.jdbc.Driver腺晾。
heartbeat
這個標簽內(nèi)指明用于和后端數(shù)據(jù)庫進行心跳檢查的語句燕锥。例如,MYSQL 可以使用 select user(),Oracle 可以使用 select 1 from dual 等悯蝉。
這個標簽還有一個 connectionInitSql 屬性归形,主要是當使用 Oracla 數(shù)據(jù)庫時,需要執(zhí)行的初始化 SQL 語句就這個放到這里面來泉粉。例如:alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'
writeHost
连霉,readHost
這兩個標簽都指定后端數(shù)據(jù)庫的相關(guān)配置給 mycat,用于實例化后端連接池嗡靡。唯一不同的是跺撼,writeHost 指定寫實例、readHost 指定讀實例讨彼,組著這些讀寫實例來滿足系統(tǒng)的要求歉井。
在一個 dataHost 內(nèi)可以定義多個 writeHost 和 readHost。但是哈误,如果 writeHost 指定的后端數(shù)據(jù)庫宕機哩至,那么這個 writeHost 綁定的所有 readHost 都將不可用躏嚎。另一方面,由于這個 writeHost 宕機系統(tǒng)會自動的檢測到菩貌,并切換到備用的 writeHost 上去,這2個標簽屬性都一致卢佣,擁有host
,url
,password
,user
,weight
,usingDecrypt
等屬性
host
用于標識不同實例,一般 writeHost 我們使用M1箭阶,readHost 我們用S1
url
真實數(shù)據(jù)庫的實例的鏈接地址虚茶,如果是使用 native 的 dbDriver,則一般為 address:port 這種形式仇参。用 JDBC 或其他的dbDriver嘹叫,則需要特殊指定。當使用 JDBC 時則可以這么寫:jdbc:mysql://localhost:3306/
user
真實數(shù)據(jù)庫實例的鏈接用戶名
password
真實數(shù)據(jù)庫實例的鏈接密碼
weight
權(quán)重 配置在 readhost 中作為讀節(jié)點的權(quán)重,主要用于多臺讀取的數(shù)據(jù)庫實例機器配置不同的情況诈乒,可以根據(jù)權(quán)重調(diào)整訪問量
usingDecrypt
是否對密碼加密默認 0 否 如需要開啟配置 1罩扇,同時使用加密程序?qū)γ艽a加密
==注意,readHost是在writeHost標簽內(nèi)的怕磨,不是單獨的==
以下是我的讀寫分離配置文件
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="separate" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"/>
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.1.126:3307" user="root"
password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS2" url="192.168.1.126:3308" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
前面已經(jīng)差不多都解釋清楚了喂饥,因為我只是用的基本的主從復制,所以我的將dataHost
的balance
設(shè)置成了3
啟動mycat癌压,然后用數(shù)據(jù)庫連接工具連接到mycat仰泻,可以測試是否配置成功,最簡單的就是通過修改從庫的數(shù)據(jù)滩届,這樣方便查看到底是運行到哪個庫上面了集侯,另外由于我是基于docker啟動的mycat,所以如果是直接在系統(tǒng)中運行的mycat的帜消,可以去看官方文檔棠枉,看看到底怎么啟動mycat