Mycat核心配置之schema.xml

 schema.xml 作爲 Mycat 中重要的配置文件之一,管理着 Mycat 的邏輯庫、表、分片規則、DataNode 以及 DataSource。弄懂這些配置,是正確使用 Mycat 的前提。

一、<schema> 標籤

 schema 標籤用於定義 Mycat 實例中的邏輯庫。Mycat 可以有多個邏輯庫,每個邏輯庫都有自己的相關配置。可以使用 <schema> 來劃分這些不同的邏輯庫,在源碼的映射類爲 io.mycat.config.model.SchemaConfig 類。

<schema name="TESTDB"></schema>

 schema 標籤的相關屬性:

屬性名 值類型 必需 默認值 說明
name string 邏輯庫名稱
checkSQLschema boolean false 是否去掉 sql 中的默認邏輯庫名
sqlMaxLimit int -1 sql 的返回結果集的最大行數
dataNode string 用於綁定邏輯庫到某個具體的 database 上
randomDataNode string

 各屬性的具體說明:

  • checkSQLschema 屬性
     當該值設置爲 true 時,如果我們的執行語句是 select * from TESTDB.travel_record,則 Mycat 會把語句寫改爲 select * from travel_record,即表示把 schema 名稱的字符去掉,避免發送到後端數據執行時報如下異常。

      ERROR 1146 (42S02): Table 'testdb.travelrecord' doesn't exist
    

    不過,即使設置該值爲 true,如果語句所帶的並非是 schema 指定的名稱,例如:select * from db1.travel_record,那麼 Mycat並不會刪除 db1 這個字段,如果沒有定義該庫的話則會報錯,所以,在提供 SQL 語句時,最好是不帶 schema 名稱。

  • sqlMaxLimit 屬性
     當該值爲自然數,且被執行的 SQL 語句中不含 limit 關鍵字時,Mycat 會自動加上所對應的值,例如此屬性的值是 100,則執行 select * from travel_record 的返回結果與執行 select * from travel_record limit 100 返回結果相同。

    如果不設置該值,Mycat 默認會把查詢到的信息全部都展示出來,造成過多的輸出。所以,在正常使用中,還是建議加上一個值,用於減少過多的數據返回。

     當然,SQL 語句中也可以顯式的指定 limit 的大小,不受該屬性的約束。

    注意:如果運行的 schema 爲非拆分庫,那麼該屬性不會生效。需要手動添加 limit 語句。

  • dataNode 屬性
     表示與該邏輯庫默認綁定的數據節點(數據庫實例——database)。所有沒有通過 <table> 標籤綁定到其他數據節點的表都會走該數據節點。

    這裏注意沒有配置在分片裏面的表無法顯示在查看工具裏,但是可以正常使用。

<table> 標籤

 <Table> 定義了 Mycat 中的邏輯表,所有需要拆分的表都需要在這個標籤中定義。如下代碼塊所示,同一個 schema 標籤內可定義個多個邏輯表,但邏輯表的名稱必須唯一,在源碼的映射類爲 io.mycat.config.model.TableConfig 類。

<schema name="TESTDB">
    <table name="travel_record" dataNode="dn1,dn2,dn3" rule="auto-sharding-long"></table>
    <table name="multipleDn1" dataNode="dn1,dn2,dn3" rule="auto-sharding-long"></table>
</schema>

 table 標籤的相關屬性:

屬性名稱 值類型 必需 默認值 說明
name string 邏輯表名稱
nameSuffix string 邏輯表名前綴(1.6 版本新特性)
dataNode string 本邏輯表分佈在哪些 dataNode 上
rule string 分片規則名稱
ruleRequired boolean false 是否綁定有分片規則
primaryKey string null 主鍵,用於之後路由分析,以及啓用自增長主鍵
type string null 是否爲global
autoIncrement boolean false 是否主鍵自增
subTables string
needAddLimit boolean true 是否需要加返回結果集限制
  • name 屬性
     邏輯表的名稱,這個名稱就如同在數據庫中執行create table命令指定的名稱一樣,同一個 schema 標籤中定義的邏輯表名稱必須唯一。
  • dataNode 屬性
     定義這個邏輯表所屬的 dataNode,該屬性的值需要和 <dataNode> 中 name 屬性的值相對應。如果需要定義的數據節點過多,可以使用如下的方法減少配置:
    <table name="travel_record" dataNode="multipleDn$0-99,multipleDn2$100-199" rule="auto-sharding-long"></table>
    <dataNode name="multipleDn$0-99" dataHost="localhost1" database="db$0-99"></dataNode>
    <dataNode name="multipleDn2$100-199" dataHost="localhost1" database=" db$100-199"></dataNode>
    
     這裏需要注意的是 database 屬性所指定的真實 database name 需要在後面添加一個$符號,例如上面的例子中,表示需要在真實的 mysql 上建立名稱爲 db0 到 db199 的 database。
  • rule 屬性
     該屬性用於指定邏輯表要使用的分片規則名字,規則名字在 rule.xml 中定義,必須與 <tableRule> 中 name 屬性值對應。
  • ruleRequired 屬性
     該屬性用於指定表是否綁定分片規則,如果配置爲 true,但沒有配置具體 rule 的話,程序會報錯。
  • primaryKey 屬性
     邏輯表對應真實表的主鍵。例如:分片的規則是使用非主鍵進行分片的,那麼在使用主鍵查詢的時候,就會發送查詢語句到所有配置的數據節點上。如果使用該屬性配置真實表的主鍵,那麼 Mycat 會緩存主鍵與具體的數據節點信息,再次使用非主鍵進行查詢時,就不會進行廣播式的查詢,就只會接發送語句給具體的數據節點,但是儘管配置該屬性,如果緩存並沒有命中的話,還是會發送語句給具體的數據節點,來獲取數據。
  • type 屬性
     該屬性定義了邏輯表的類型,目前邏輯表只有“全局表”和“普通表”兩種類型。對應的配置:
    • 全局表:global。
    • 普通表:非 global 即可。
  • autoIncrement 屬性
     是否自增長主鍵。MySQL 對非自增長主鍵,使用 last_insert_id() 是不會返回結果的,只會返回 0。所以,只有定義了自增長主鍵的表纔可以用 last_insert_id() 返回主鍵值。
     Mycat 目前提供了增長主鍵功能,但是如果對應的 MySQL 節點上數據表,沒有定義 auto_increment,那麼在 Mycat 層調用 last_insert_id() 也是不會返回結果的。
     由於 insert 操作的時候沒有帶入分片鍵,Mycat 會先取下這個表對應的全局序列,然後賦值給分片鍵。這樣才能正常的插入到數據庫中,最後使用 last_insert_id() 纔會返回插入的分片鍵值。
     如果要使用這個功能最好配合使用數據庫模式的全局序列。
     使用 autoIncrement=“true” 指定這個表有使用自增長主鍵,這樣 Mycat 纔會不拋出分片鍵找不到的異常。
     使用 autoIncrement=“false” 來禁用這個功能,當然你也可以直接刪除掉這個屬性。默認就是禁用的。
  • subTables 屬性
     目前 1.6 版本開始支持分表,並且 dataNode 在分表條件下只能配置一個,分表條件下不支持各種條件的 join 語句。使用方式是添加 subTables=“t_order$1-2,t_order3”
  • needAddLimit 屬性
     指定表是否需要自動的在每個語句後面加上 limit 限制。由於使用了分庫分表,數據量有時會特別巨大,這時候執行查詢語句,如果恰巧又忘記了加上數量限制的話,那麼將查詢出所有的數據出來。所以,Mycat 就自動的爲我們加上 LIMIT 100。當然,如果語句中有 limit,就不會再次添加了。

<childTable> 標籤

 <childTable> 用於定義 E-R 分片的子表。通過標籤上的屬性與父表進行關聯。

<schema name="TESTDB">
    <table name="travel_record" dataNode="dn$1-3">
        <childTable name="company" joinKey="id" parentKey="parent_id"/>
    </table>
</schema>

 <childTable> 的相關屬性:

屬性名 值類型 必需 默認值 說明
name string 子表的表名
joinKey string 插入子表的時候會使用這個列的值查找父表存儲的數據節點
parentKey string 與父表建立關聯關係的列名
primaryKey string 該表對應的真實主鍵
needAddLimit boolean 是否需要爲 sql 自動添加 limit 關鍵字
autoIncrement boolean false 是否主鍵自增
  • parentKey 屬性
     屬性指定的值一般爲與父表建立關聯關係的列名稱,程序首先獲取 joinKey 的值,再通過 parentKey 屬性指定的列名產生查詢語句,通過執行該語句得到父表存儲在哪個分片上,從而確定子表存儲的位置。

二、<dataNode> 標籤

 <dataNode>定義了 Mycat 中的數據節點,也就是我們通常所說的數據分片。一個 <dataNode> 就是一個獨立的數據分片,在源碼的映射類爲 io.mycat.config.model.DataNodeConfig 類。

<dataNode name="dn1" dataHost="localhost1" database="db1"/>

將名爲 localhost1 節點上數據庫實例爲 db1 的物理庫標記成名爲 dn1 的獨立數據分片。

 <dataNode> 的相關屬性:

屬性名 值類型 必需 說明
name string 數據節點名稱,須保證唯一
dataHost string 該分片節點所屬的節點主機
database string 真實的 database 名稱

 屬性釋義:

  • name 屬性
     定義數據節點的名字(須保證唯一),我們需要在 <table> 上引用這個名稱,來建立表與分片對應的關係。
  • dataHost 屬性
     該屬性用於定義該分片屬於哪個數據庫實例,屬性值是引用自 <dataHost> 上定義的 name 屬性。
  • database 屬性
     該屬性用於定義該分片屬於哪個具體數據庫實例上的具體庫。

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

三、<dataHost> 標籤

 作爲 schema.xml 中最後的一個標籤,該標籤在 Mycat 邏輯庫中也是作爲最底層的標籤存在,直接定義了具體的數據庫實例、讀寫分離配置和心跳語句,在源碼的映射類是 io.mycat.config.model.DataHostConfig 類。

<dataHost name="dn1" balance="0" dbDriver="native" dbType="mysql" maxCon="10" minCon="100">
    <heartbeat>select 1 from dual</heartbeat>
    <writeHost host="hostM1" url="master1:3306" user="root" password="123456">
        <readHost host="hostS1" url="slave1:3306" user="root" password="123456"/>
    </writeHost>
</dataHost>

<dataHost> 標籤的相關屬性:

屬性名 值類型 必需 默認值 說明
name string 節點主機的唯一標識,供其他標籤使用
maxCon int 128 讀寫連接池的最大連接數
minCon int 10 讀寫連接池的最小/初始連接數
balance int 0 負載均衡類型
balanceType int 0 負載均衡策略
dbType string 後端數據庫類型
dbDriver string 連接後端數據庫使用的驅動
writeType int 0 寫類型
switchType int -1 切換類型
slaveThreshold int -1 從庫延遲界限
tempReadHostAvailable int 0 寫節點宕機時,臨時讀節點是否可用
notSwitch string 0

 屬性釋義:

  • balance 屬性
     負載均衡類型,目前的取值有 4 中:
    • balance=“0”,不開啓讀寫分離機制,所有讀操作都發送到當前可用的 writeHost 上。
    • balance=“1”,全部的 readHost 與 stand by writeHost 參與 select 語句的負載均衡,簡單地說,當說雙主從模式(M1 -> S1,M2 -> S2,並且 M1 與 M2 互爲主備),正常情況下,M2、S1、S2 都參與 select 語句的負載均衡。
    • balance=“2”,所有讀操作都隨機的在 writeHost、readHost 上分發。
    • balance=“3”,(1.4+ 版本特性)所有讀請求隨機的分發到 writeHost 對應的 readHost 執行,writeHost 不負擔讀壓力。
  • balanceType 屬性
    • 0 表示隨機。
    • 1 表示加權輪詢。
    • 2 表示最少活躍數。
  • writeType 屬性
     負載均衡類型,目前的取值有 2 種:
    • writeType=“0”,所有寫操作發送到配置的第一個 writeHost,第一個掛了切到還存活的第二個 writeHost,重新啓動後以切換後的爲準,切換信息記錄在 dnindex.properties 配置文件。
    • writeType=“1”,所有寫操作都隨機的發送到配置的 writeHost。(1.5+ 廢棄,不推薦使用)
  • switchType 屬性
    • -1 表示不自動切換。
    • 1 自動切換。
    • 2 基於 MySQL 主從同步的狀態決定是否切換。心跳語句爲:show slave status
    • 3 基於 MySQL galary cluster 的切換機制(適合集羣)(1.4.1+版本)。心跳語句爲:show status like ‘wsrep%’
  • dbType 屬性
     指定後端連接的數據庫類型,目前支持二進制的 mysql 協議,還有其他使用 JDBC 連接的數據庫。例如:mongodb、oracle、spark 等。
  • dbDriver 屬性
     指定連接後端數據庫使用的驅動,目前可選的值有 native 和 JDBC。使用 native 的話,因爲這個值執行的是二進制的 mysql 協議,所以可以使用 mysql 和 maridb。其他類型的數據庫則需要使用 JDBC 驅動來支持。從 1.6 版本開始支持 postgresql 的 native 原始協議。
     如果使用 JDBC 的話,需要將符合 JDBC 4 標準的驅動 JAR 包放到 MYCAT\lib 目錄下,並檢查驅動 JAR 包中包括如下目錄結構的文件:META-INF\services\java.sql.Driver。在這個文件內寫上具體的 Driver 類名,例如:com.mysql.jdbc.Driver。
  • tempReadHostAvailable 屬性
     如果屬性值大於 0 則表示在寫節點宕機時,臨時的讀服務依然可用,即如果配置了這個屬性,<writeHost> 下面的 <readHost> 仍舊可用,默認 0 可配置(0、1)。

<heartbeat> 標籤

 這個標籤內指明用於和後端數據庫進行心跳檢查的語句。例如,MySQL 可以使用 select user(),Oracle 可以使用 select 1 from dual 等。

<dataHost name="dn1" balance="0" dbDriver="native" dbType="mysql" maxCon="10" minCon="100">
    <heartbeat>select user()</heartbeat>
</dataHost>

Mycat 1.4 版本的主從切換的心跳語句必須是:show slave status

<connectionInitSql> 標籤

 當使用 Oracle 數據庫時,需要執行的初始化 SQL 語句就放到這裏面來。例如:

<dataHost name="dn1" balance="0" dbDriver="jdbc" dbType="oracle" maxCon="10" minCon="100">
    <heartbeat>select 1 from dual</heartbeat>
    <connectionInitSql>alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'</connectionInitSql>
</dataHost>

<writeHost> 標籤、<readHost> 標籤

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

<dataHost name="dn1" balance="0" dbDriver="native" dbType="mysql" maxCon="10" minCon="100">
    <writeHost host="hostM1" url="master1:3306" user="root" password="123456">
        <readHost host="hostS1" url="slave1:3306" user="root" password="123456"/>
    </writeHost>
</dataHost>

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

屬性名 值類型 必需 默認值 說明
host string 用於標識不同實例,一般writeHost使用 M1;readHost 用 S1
url string 後端實例連接地址,如果是使用 native 的 dbDriver,則一般爲 localhost:3306 形式;
在使用 jdbc 時,則可寫爲:jdbc:mysql://localhost:3306
user string 後端存儲實例需要的用戶名稱
password string 後端存儲實例需要的密碼
weight string 0 權重。配置在 <readhost> 中作爲讀節點的權重(1.4+ 版本生效)
usingDecrypt string 0 是否對密碼加密
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章