學會資料庫讀寫分離、分表分庫——用Mycat,這一篇就夠了!

来源:http://www.cnblogs.com/joylee/archive/2017/09/13/7513038.html
-Advertisement-
Play Games

系統開發中,資料庫是非常重要的一個點。除了程式的本身的優化,如:SQL語句優化、代碼優化,資料庫的處理本身優化也是非常重要的。主從、熱備、分表分庫等都是系統發展遲早會遇到的技術問題問題。Mycat是一個廣受好評的資料庫中間件,已經在很多產品上進行使用了。希望通過這篇文章的介紹,能學會Mycat的使用 ...


系統開發中,資料庫是非常重要的一個點。除了程式的本身的優化,如:SQL語句優化、代碼優化,資料庫的處理本身優化也是非常重要的。主從、熱備、分表分庫等都是系統發展遲早會遇到的技術問題問題。Mycat是一個廣受好評的資料庫中間件,已經在很多產品上進行使用了。希望通過這篇文章的介紹,能學會Mycat的使用。

安裝

Mycat官網:http://www.mycat.io/
可以瞭解下Mycat的背景和應用情況,這樣使用起來比較有信心。

Mycat下載地址:http://dl.mycat.io/
官網有個文檔,屬於詳細的介紹,初次入門,看起來比較花時間。

下載:
建議大家選擇 1.6-RELEASE 版本,畢竟是比較穩定的版本。

安裝:
根據不同的系統選擇不同的版本。包括linux、windows、mac,作者考慮還是非常周全的,當然,也有源碼版的。(ps:源碼版的下載後,只要配置正確,就可以正常運行調試,這個贊一下。)

Mycat的安裝其實只要解壓下載的目錄就可以了,非常簡單。
安裝完成後,目錄如下:

目錄 說明
bin mycat命令,啟動、重啟、停止等
catlet catlet為Mycat的一個擴展功能
conf Mycat 配置信息,重點關註
lib Mycat引用的jar包,Mycat是java開發的
logs 日誌文件,包括Mycat啟動的日誌和運行的日誌。

配置

Mycat的配置文件都在conf目錄裡面,這裡介紹幾個常用的文件:

文件 說明
server.xml Mycat的配置文件,設置賬號、參數等
schema.xml Mycat對應的物理資料庫和資料庫表的配置
rule.xml Mycat分片(分庫分表)規則

Mycat的架構其實很好理解,Mycat是代理,Mycat後面就是物理資料庫。和Web伺服器的Nginx類似。對於使用者來說,訪問的都是Mycat,不會接觸到後端的資料庫。
我們現在做一個主從、讀寫分離,簡單分表的示例。結構如下圖:

伺服器 IP 說明
Mycat 192.168.0.2 mycat伺服器,連接資料庫時,連接此伺服器
database1 192.168.0.3 物理資料庫1,真正存儲數據的資料庫
database2 192.168.0.4 物理資料庫2,真正存儲數據的資料庫

Mycat作為主資料庫中間件,肯定是與代碼弱關聯的,所以代碼是不用修改的,使用Mycat後,連接資料庫是不變的,預設埠是8066。連接方式和普通資料庫一樣,如:jdbc:mysql://192.168.0.2:8066/

server.xml

示例

<user name="test">
        <property name="password">test</property>  
        <property name="schemas">lunch</property>  
        <property name="readOnly">false</property>  
        
        <!-- 表級 DML 許可權設置 -->
        <!--        
        <privileges check="false">
            <schema name="TESTDB" dml="0110" >
                <table name="tb01" dml="0000"></table>
                <table name="tb02" dml="1111"></table>
            </schema>
        </privileges>       
         -->
    </user>

重點關註下麵這段,其他預設即可。

參數 說明
user 用戶配置節點
--name 登錄的用戶名,也就是連接Mycat的用戶名
--password 登錄的密碼,也就是連接Mycat的密碼
--schemas 資料庫名,這裡會和schema.xml中的配置關聯,多個用逗號分開,例如需要這個用戶需要管理兩個資料庫db1,db2,則配置db1,dbs
--privileges 配置用戶針對錶的增刪改查的許可權,具體見文檔吧

我這裡配置了一個賬號test 密碼也是test,針對資料庫lunch,讀寫許可權都有,沒有針對錶做任何特殊的許可權。

schema.xml
schema.xml是最主要的配置項,首先看我的配置文件。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- 資料庫配置,與server.xml中的資料庫對應 -->
    <schema name="lunch" checkSQLschema="false" sqlMaxLimit="100">
        <table name="lunchmenu" dataNode="dn1"  />
        <table name="restaurant" dataNode="dn1"  />
        <table name="userlunch" dataNode="dn1"  />
        <table name="users" dataNode="dn1"  />
        <table name="dictionary" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2"  rule="mod-long" />

        
    </schema>

<!-- 分片配置 -->
    <dataNode name="dn1" dataHost="test1" database="lunch" />
    <dataNode name="dn2" dataHost="test2" database="lunch" />

<!-- 物理資料庫配置 -->
    <dataHost name="test1" maxCon="1000" minCon="10" balance="0"  writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="123456">  
        </writeHost>
    </dataHost>

    <dataHost name="test2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="hostS1" url="192.168.0.3:3306" user="root" password="123456">  
        </writeHost>
    </dataHost>

</mycat:schema>
參數 說明
schema 資料庫設置,此資料庫為邏輯資料庫,name與server.xml中schema對應
dataNode 分片信息,也就是分庫相關配置
dataHost 物理資料庫,真正存儲數據的資料庫

每個節點的屬性逐一說明:

schema:

屬性 說明
name 邏輯資料庫名,與server.xml中的schema對應
checkSQLschema 資料庫首碼相關設置,建議看文檔,這裡暫時設為folse
sqlMaxLimit select 時預設的limit,避免查詢全表

table:

屬性 說明
name 表名,物理資料庫中表名
dataNode 表存儲到哪些節點,多個節點用逗號分隔。節點為下文dataNode設置的name
primaryKey 主鍵欄位名,自動生成主鍵時需要設置
autoIncrement 是否自增
rule 分片規則名,具體規則下文rule詳細介紹

dataNode

屬性 說明
name 節點名,與table中dataNode對應
datahost 物理資料庫名,與datahost中name對應
database 物理資料庫中資料庫名

dataHost

屬性 說明
name 物理資料庫名,與dataNode中dataHost對應
balance 均衡負載的方式
writeType 寫入方式
dbType 資料庫類型
heartbeat 心跳檢測語句,註意語句結尾的分號要加。

應用場景

資料庫分表分庫

配置如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- 資料庫配置,與server.xml中的資料庫對應 -->
    <schema name="lunch" checkSQLschema="false" sqlMaxLimit="100">
        <table name="lunchmenu" dataNode="dn1"  />
        <table name="restaurant" dataNode="dn1"  />
        <table name="userlunch" dataNode="dn1"  />
        <table name="users" dataNode="dn1"  />
        <table name="dictionary" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2"  rule="mod-long" />

        
    </schema>

<!-- 分片配置 -->
    <dataNode name="dn1" dataHost="test1" database="lunch" />
    <dataNode name="dn2" dataHost="test2" database="lunch" />

<!-- 物理資料庫配置 -->
    <dataHost name="test1" maxCon="1000" minCon="10" balance="0"  writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="123456">  
        </writeHost>
    </dataHost>

    <dataHost name="test2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="hostS1" url="192.168.0.3:3306" user="root" password="123456">  
        </writeHost>
    </dataHost>

</mycat:schema>

我在192.168.0.2、192.168.0.3均有資料庫lunch。
lunchmenu、restaurant、userlunch、users這些表都只寫入節點dn1,也就是192.168.0.2這個服務,而dictionary寫入了dn1、dn2兩個節點,也就是192.168.0.2、192.168.0.3這兩台伺服器。分片的規則為:mod-long。
主要關註rule屬性,rule屬性的內容來源於rule.xml這個文件,Mycat支持10種分表分庫的規則,基本能滿足你所需要的要求,這個必須贊一個,其他資料庫中間件好像都沒有這麼多。
table中的rule屬性對應的就是rule.xml文件中tableRule的name,具體有哪些分表和分庫的實現,建議還是看下文檔。我這裡選擇的mod-long就是將數據平均拆分。因為我後端是兩台物理庫,所以rule.xml中mod-long對應的function count為2,見下麵部分代碼:

<tableRule name="mod-long">
        <rule>
            <columns>id</columns>
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
    
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <property name="count">2</property>
    </function>

資料庫讀寫分離

配置如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- 資料庫配置,與server.xml中的資料庫對應 -->
    <schema name="lunch" checkSQLschema="false" sqlMaxLimit="100">
        <table name="lunchmenu" dataNode="dn1"  />
        <table name="restaurant" dataNode="dn1"  />
        <table name="userlunch" dataNode="dn1"  />
        <table name="users" dataNode="dn1"  />
        <table name="dictionary" primaryKey="id" autoIncrement="true" dataNode="dn1"  />

        
    </schema>

<!-- 分片配置 -->
    <dataNode name="dn1" dataHost="test1" database="lunch" />


<!-- 物理資料庫配置 -->
    <dataHost name="test1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="123456">  
        <readHost host="hostM1" url="192.168.0.3:3306" user="root" password="123456">   
        </readHost>
        </writeHost>
    </dataHost>


</mycat:schema>

這樣的配置與前一個示例配置改動如下:
刪除了table分配的規則,以及datanode只有一個
datahost也只有一臺,但是writehost總添加了readhost,balance改為1,表示讀寫分離。
以上配置達到的效果就是102.168.0.2為主庫,192.168.0.3為從庫。

註意:Mycat主從分離只是在讀的時候做了處理,寫入數據的時候,只會寫入到writehost,需要通過mycat的主從複製將數據複製到readhost,這個問題當時候我糾結了好久,數據寫入writehost後,readhost一直沒有數據,以為是自己配置的問題,後面才發現Mycat就沒有實現主從複製的功能,畢竟資料庫本身自帶的這個功能才是最高效穩定的。

至於其他的場景,如同時主從和分表分庫也是支持的了,只要瞭解這個實現以後再去修改配置,都是可以實現的。而熱備及故障專業官方推薦使用haproxy配合一起使用,大家可以試試。

使用

Mycat的啟動也很簡單,啟動命令在Bin目錄:

##啟動
mycat start

##停止
mycat stop

##重啟
mycat restart

如果在啟動時發現異常,在logs目錄中查看日誌。

  • wrapper.log 為程式啟動的日誌,啟動時的問題看這個
  • mycat.log 為腳本執行時的日誌,SQL腳本執行報錯後的具體錯誤內容,查看這個文件。mycat.log是最新的錯誤日誌,歷史日誌會根據時間生成目錄保存。

mycat啟動後,執行命令不成功,可能實際上配置有錯誤,導致後面的命令沒有很好的執行。

Mycat帶來的最大好處就是使用是完全不用修改原有代碼的,在mycat通過命令啟動後,你只需要將資料庫連接切換到Mycat的地址就可以了。如下麵就可以進行連接了:

 mysql -h192.168.0.1 -P8806 -uroot -p123456

連接成功後可以執行sql腳本了。
所以,可以直接通過sql管理工具(如:navicat、datagrip)連接,執行腳本。我一直用datagrip來進行日常簡單的管理,這個很方便。

Mycat還有一個管理的連接,埠號是9906.

 mysql -h192.168.0.1 -P9906 -uroot -p123456

連接後可以根據管理命令查看Mycat的運行情況,當然,喜歡UI管理方式的人,可以安裝一個Mycat-Web來進行管理,有興趣自行搜索。

簡而言之,開發中使用Mycat和直接使用Mysql機會沒有差別。

常見問題

使用Mycat後總會遇到一些坑,我將自己遇到的一些問題在這裡列一下,希望能與大家有共鳴:

  • Mycat是不是配置以後,就能完全解決分表分庫和讀寫分離問題?
    Mycat配合資料庫本身的複製功能,可以解決讀寫分離的問題,但是針對分表分庫的問題,不是完美的解決。或者說,至今為止,業界沒有完美的解決方案。
    分表分庫寫入能完美解決,但是,不能完美解決主要是聯表查詢的問題,Mycat支持兩個表聯表的查詢,多餘兩個表的查詢不支持。 其實,很多資料庫中間件關於分表分庫後查詢的問題,都是需要自己實現的,而且節本都不支持聯表查詢,Mycat已經算做地非常先進了。
    分表分庫的後聯表查詢問題,大家通過合理資料庫設計來避免。

  • Mycat支持哪些資料庫,其他平臺如 .net、PHP能用嗎?
    官方說了,支持的資料庫包括MySQL、SQL Server、Oracle、DB2、PostgreSQL 等主流資料庫,很贊。
    儘量用Mysql,我試過SQL Server,會有些小問題,因為部分語法有點差異。

  • Mycat 非JAVA平臺如 .net、PHP能用嗎?
    可以用。這一點MyCat做的也很棒。

參考

《Mycat權威指南》: http://www.mycat.io/document/Mycat_V1.6.0.pdf
官網 :http://www.mycat.io/

如果想熟練使用Mycat,建議要仔細看看官方推薦的文檔,可能需要花點時間。本文只是簡單的介紹下Mycat的配置,希望能快速讓大家對Mycat有個認識,官方的文檔理解起來也很容易,只是需要的時間更多,本文為說明的參數,請參考官方文檔。


歡迎大家關註我的公眾號交流、學習、第一時間獲取最新的文章
微信號:itmifen


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Coloring Trees CodeForces - 711C 題意:有n個點,每個點有一個c值,如果為0表示它沒有被染色,否則表示它被染成了c值的顏色。顏色有1到m。把第i棵樹染成顏色j所需要的代價是p[i][j]。求最小的代價,使得將每棵樹都染色,且如果將連續的一串同色的樹視為一個集合,共有k ...
  • 對於Spring相信很多做web開發的小活動一定不陌生,Spring中我們經常談到的就是IOC和AOP,但是對於Spring的事務管理,相信大家一定也很感興趣,今天我們就探討一下Spring中的事務管理。 首先談一下事務使用的場景,我們能想到的最常見場景就是銀行轉賬,A給B轉賬,第一步扣除A中的賬戶 ...
  • AJAX開發 AJAX即“Asynchronous Javascript And XML”(非同步JavaScript和XML),是指一種創建互動式網頁應用的網頁開發技術。 AJAX = 非同步 JavaScript和XML(標準通用標記語言的子集)。 AJAX 是一種用於創建快速動態網頁的技術。 通過 ...
  • 壞味道意指代碼中出現的可以被改進的地方。當你嗅到壞味道的時候,也就意味著重構的時機到了。 重構對軟體內部結構的一種調整,目的是在不改變軟體可觀察行為的前提下,提高其可理解性,降低其修改成本。 ...
  • 本期我們組的技術分享,打算跟大家講講服務治理。我在上篇文章中介紹了我們美團.點評北京總部用的OCTO框架,其實在上海點評部門用的是另一套Pigeon。這兩套框架都很重。這是和我們的業務有關的,其實服務治理這個東西都創業公司到成熟的大公司都在用,只是做到的程度不同。 先說說服務治理的邊界。本質上任何能 ...
  • 建造者模式是最後一個創建型設計模式,也是研究對象的創建。 將一個複雜對象的創建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 創建和表示是什麼意思 ? 表示就是外在,對象具體的樣子,而內部構建過程是一種組裝的概念,有點像套娃,同樣的結構,但是卻產生了不同大小的樣子。 按照慣例,先講故事。 假 ...
  • 今天要講的是以下三個概念: - 控制反轉 :IoC, Inversion of Control - 依賴註入:DI, Dependency Injection - 依賴查找:DL, Dependency Lookup, Service Locator 什麼是控制反轉 先說正常的控制流程是怎樣的: 比 ...
  • .NET 官方架構指南 Microservices and Docker Containers Web Applications with ASP.NET 官網地址:https://www.microsoft.com/net/learn/architecture 三層及多層架構 Multitier ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...