一篇秒懂mycat

前言

哈嘍,大家好,最近換了工作,爲了更快的熟悉新環境,大部分精力都在學習公司的項目業務以及技術,所以公衆號更新就少了(非常感謝各位依舊關注),但是我又學到了一些新的技術哈哈~~,又整理了一遍分享給各位。

什麼是mycat

它是阿里開源的一個數據庫中間件,專門爲大數據量的項目做分庫分表用的。有如下特點:

  • 一個徹底開源的,面向企業應用開發的大數據庫集羣
  • 支持事務、ACID、可以替代MySQL的加強版數據庫
  • 一個可以視爲MySQL集羣的企業級數據庫,用來替代昂貴的Oracle集羣
  • 一個融合內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server
  • 結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品
  • 一個新穎的數據庫中間件產品

官網地址:
http://www.mycat.org.cn/

mycat權威指南:
http://www.mycat.org.cn/document/mycat-definitive-guide.pdf

mycat架構

話不多說,一張mycat架構圖就能讓你知道mycat的角色以及作用。

mycat1.6版本架構如下:

由圖可知,mycat位於數據庫和應用層(APP)之間,它的角色就是幫我們管理數據庫集羣,而提供應用統一訪問數據庫接口。

垂直分庫

垂直分庫通俗來說就是按照功能劃分,將不同的數據放在不同的數據庫中。

水平分表

水平分表通俗來說就是某表數據量太大了,那麼我們很自然地想到是加多一個表來存儲數據,這樣查詢速度纔會更快。那麼水平分表就是表結構是一樣的,只不過存的數據不一樣而已。

邏輯庫和邏輯表

邏輯庫:通常對實際應用來說,並不需要知道中間件的存在,業務開發人員只需要知道數據庫的概念,所以數據庫中間件可以被看做是一個或多個數據庫集羣構成的邏輯庫。

邏輯表:分佈式數據庫中,對應用來說,讀寫數據的表就是邏輯表。邏輯表,可以是數據切分後,分佈在一個或多個分片庫中,也可以不做數據切分,不分片,只有一個表構成。

mycat基本配置

當我們數據量特別大的時候需要分庫分表的時候,那麼我們可以考慮使用mycat。那麼mycat具體如何做到分庫分表的呢?接下來就要學習mycat的三大配置文件進行靈活配置就可以實現分庫分表啦啦啦。。。

mycat主要的三大配置文件:
server.xml、schema.xml、rule.xml

這三個配置文件位於mycat的安裝目錄的conf目錄中。

server.xml

該文件幾乎包含了所有 mycat 需要的系統配置信息。其中包括對外(應用)訪問端口,編碼,連接超時時間,最大連接數,事務級別,用戶密碼以及邏輯庫等信息。

詳細可以閱讀下面的配置:


<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
        <property name="serverPort">8066</property> <!-- mycat 服務端口-->
        <property name="managerPort">9066</property><!-- mycat 管理端口-->
        <property name="nonePasswordLogin">0</property>
        <property name="bindIp">0.0.0.0</property>
        <property name="frontWriteQueueSize">2048</property>
        <property name="charset">utf8</property><!-- 配置該屬性的時候一定要保證mycat的字符集和mysql 的字符集是一致的 -->	
        <property name="txIsolation">2</property> <!-- 前端連接的初始化事務隔離級別,只在初始化的時候使用,後續會根據客戶端傳遞過來的屬性對後端[數據庫](http://msd.misuland.com/pd/3148108429789238586)連接進行同步。默認爲 REPEATED_READ,設置值爲數字默認 3。  READ_UNCOMMITTED = 1;  READ_COMMITTED = 2;  REPEATED_READ = 3;  SERIALIZABLE = 4;-->
        <property name="processors">8</property><!-- 處理線程數量,默認是cpu數量-->
        <property name="idleTimeout">1800000</property><!-- mycat訪問mysql,多長時間無反應斷開連接-->
        <property name="useSqlStat">0</property> <!-- 1爲開啓實時統計、0爲關閉 -->
        <property name="useGlobleTableCheck">0</property> <!-- 1爲開啓全局表一致性檢測、0爲關閉 -->
        <property name="sqlExecuteTimeout">300</property><!-- SQL 執行超時的時間,Mycat 會檢查連接上最後一次執行 SQL 的時間,若超過這個時間則會直接關閉這連接。默認時間爲 300 秒,單位秒。-->
        <property name="sequnceHandlerType">1</property>  <!-- 用來指定Mycat全局序列類型,0爲本地文件,1爲數據庫方式,2爲時間戳列方式,默認使用本地文件方式,文件方式主要用於測試--> 
        <property name="defaultMaxLimit">100</property><!-- mycat 默認返回的結果集大小-->
        <property name="maxPacketSize">104857600</property><!-- 指定 Mysql 協議可以攜帶的數據最大長度。默認 16M。-->
    </system>
  <!--表示mycat的登錄用戶名-->
    <user name="root">
 <!--表示mycat的登錄密碼,密碼加密:java -cp Mycat-server-xxx.jar io.mycat.util.DecryptUtil 0:user:password 
      <property name="usingDecrypt">1</property> -->
        <property name="password">123456</property>
<!--表示mycat的邏輯數據庫名稱,可以自定義-->
        <property name="schemas">shop_db</property>
    </user>
</mycat:server>

更多關於server.xml的配置可參考以下文章:

http://suo.im/6lJTHF
http://suo.im/6lJTK5
http://suo.im/6613kS

schema.xml

作爲MyCat中重要的配置文件之一,它主要管理着MyCat的邏輯庫、表、分片規則、DataNode以及DataHost。弄懂這些配置,是正確使用MyCat的前提。這裏就一層層對該文件進行解析。

標籤解析:

  • schema:配置邏輯庫,與server.xml中的邏輯庫要對應。
  • table:配置邏輯表,包含主鍵,自增在,位於哪個節點等。
  • dataNode :配置邏輯庫與物理庫的對應關係
  • dataHost :配置連接數據庫主機信息。

更多詳細可以參考配置文件說明:

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 定義邏輯庫,name屬性是指邏輯庫,sqlMaxLimit限制返回的行數,checkSQLschema默認是false,判斷是否檢查發給mycat的sql是否包含庫名 -->
    <schema name="shop_db" checkSQLschema="false" sqlMaxLimit="100">
 <!-- 定義邏輯表,name屬性定義邏輯表名稱,dataNode表示數據所屬邏輯節點,primaryKey定義邏輯表的主鍵,type表示邏輯表的類型,global爲全局表,autoIncrement是指自動遞增-->
        <table name="region_info" dataNode="orddb,custdb,prodb" primaryKey="region_id" type="global"/>
        <table name="order_cart" dataNode="orddb" primaryKey="cart_id"/>
        <table name="order_customer_addr" dataNode="orddb" primaryKey="customer_addr_id"/>
        <table name="order_detail" dataNode="orddb" primaryKey="order_detail_id"/>
        <table name="order_master" dataNode="orddb01,orddb02,orddb03,orddb04" rule="order_master" primaryKey="order_id" autoIncrement="true"/>
        <table name="customer_balance_log" dataNode="custdb" primaryKey="balance_id"/>
        <table name="customer_inf" dataNode="custdb" primaryKey="customer_inf_id"/>
        <table name="customer_level_inf" dataNode="custdb" primaryKey="customer_level"/>
        <table name="customer_login" dataNode="custdb" primaryKey="customer_id"/>
        <table name="customer_login_log" dataNode="custdb" primaryKey="login_id"/>
        <table name="customer_point_log" dataNode="custdb" primaryKey="point_id"/>
        <table name="product_brand_info" dataNode="prodb" primaryKey="brand_id"/>
        <table name="product_category" dataNode="prodb" primaryKey="category_id"/>
        <table name="product_comment" dataNode="prodb" primaryKey="comment_id"/>
        <table name="product_info" dataNode="prodb" primaryKey="product_id"/>
        <table name="product_supplier_info" dataNode="prodb" primaryKey="supplier_id"/>
    </schema>
    <!-- 定義數據存儲的物理位置,dataHost指邏輯主機,database爲物理數據庫的名稱-->
    <dataNode name="orddb" dataHost="mysql10" database="order_db"/>
    <dataNode name="custdb" dataHost="mysql11" database="customer_db"/>
    <dataNode name="prodb" dataHost="mysql12" database="product_db"/>
    <dataNode name="orddb01" dataHost="mysql10" database="orddb01"/>
    <dataNode name="orddb02" dataHost="mysql10" database="orddb02"/>
    <dataNode name="orddb03" dataHost="mysql11" database="orddb01"/>
    <dataNode name="orddb04" dataHost="mysql12" database="orddb01"/>
    <dataNode name="mycat" dataHost="mysql10" database="mycat"/>

    <!-- 定義後端數據庫主機信息;balance=3指所有的讀操作都只發送到writeHost的readHost上;writeType=“0”, 所有寫操作都發送到可用的writeHost上;switchType='1' 默認值,表示自動切換-->
    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql10" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
          <!--檢查後端數據庫是否可用 -->
        <heartbeat>select user()</heartbeat>
        <!-- writeHost指定寫實例、readHost指定讀實例-->
        <writeHost host="192.168.56.10" url="192.168.56.10:3306" password="123456" user="im_mycat"/>
    </dataHost>
    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql11" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <writeHost host="192.168.56.11" url="192.168.56.11:3306" password="123456" user="im_mycat"/>
    </dataHost>
    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql12" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <writeHost host="192.168.56.12" url="192.168.56.12:3306" password="123456" user="im_mycat"/>
    </dataHost>
</mycat:schema>

關於更多ER圖關係配置和其他參數意義。可參考以下文件或者《mycat權威指南》
https://blog.csdn.net/l1028386804/article/details/53385637
https://www.cnblogs.com/jihaibo/p/9051105.html
https://www.cnblogs.com/ivictor/p/5131480.html

rule.xml

它的功能主要體現在以下兩個方面:

  • 1、配置水平分片的分片規則
  • 2、配置分片規則所對應的分片函數
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
    <tableRule name="order_master"> <!-- 與schema.xml的table標籤中的rule對應關係-->
        <rule>
            <columns>customer_id</columns>
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <property name="count">4</property>
    </function>
</mycat:rule>

其中的function的name必須是唯一的,以上就是hash取模4的分片算法。

常見的分片算法:

  • 簡單取模-PartitionByMod
  • 哈希取模-PartitionByHashMod
  • 分片枚舉-PartitionByFileMap
  • 字符串範圍取模分片

更多可以參考文章:
https://blog.csdn.net/l1028386804/article/details/53402552
https://www.cnblogs.com/kingsonfu/p/10627423.html

最後

mycat的基本知識到此結束,如果需要了解更多可以閱讀官網提供的《mycat權威指南》,後續會對其操作進行詳細的描述哦,下期再見!!!

更多關於Java的知識可以關注公衆號【愛編碼】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章