來詳細的看看 mycat的配置文件,更多信息請查看:mycat權威指南。
schema.xml:
Schema.xml 作為 MyCat 中重要的配置文件之一,管理着 MyCat 的邏輯庫、表、分片規則、DataNode 以 及 DataSource。
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!-- 邏輯庫配置--> <!--一個schema標簽就是一個邏輯庫, 邏輯庫名稱 --> <schema name="db_store" checkSQLschema="false" sqlMaxLimit="100"> <!--非分片表的配置 名稱,從屬節點 主鍵--> <table name="store" dataNode="db_store_dataNode" primaryKey="storeID"/> <table name="employee" dataNode="db_store_dataNode" primaryKey="employeeID"/> </schema> <schema name="db_user" checkSQLschema="false" sqlMaxLimit="100"> <!--全局表 指定 type ,指定所在分片 ,主鍵--> <table name="data_dictionary" type="global" dataNode="db_user_dataNode1,db_user_dataNode2" primaryKey="dataDictionaryID"/> <!--分片表的配置 ,配置分片節點 ,rule 配置分片規則,具體配置在rule.xml里面,在rule.xml再細說--> <table name="users" dataNode="db_user_dataNode$1-2" rule="mod-userID-long" primaryKey="userID"> <!--ER表,通過parentKey去找 users表對應的分片,放到同一個分片下--> <childTable name="user_address" joinKey="userID" parentKey="userID" primaryKey="addressID"/> </table> </schema> <!-- 節點配置 為什么 db_store只有一個節點呢?因為這個節點理的兩個主機是主從復制實現了讀寫分離 這里即具備讀也具備了寫。在節點主機配置中有體現。 --> <!-- db_store --> <dataNode name="db_store_dataNode" dataHost="db_storeHOST" database="db_store" /> <!-- db_user --> <dataNode name="db_user_dataNode1" dataHost="db_userHOST1" database="db_user" /> <dataNode name="db_user_dataNode2" dataHost="db_userHOST2" database="db_user" /> <!-- 主從復制 節點主機配置 --> <!-- 配置db_store的節點主機 最大連接數100 最小10 --> <dataHost name="db_storeHOST" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <!-- 心跳機制 --> <heartbeat>select user()</heartbeat> <!-- 讀寫分離 can have multi write hosts 寫節點(master)--> <writeHost host="hostM1" url="192.168.254.138:3306" user="root" password="wuzhenzhao"> <!-- can have multi read hosts 讀節點(slave)--> <readHost host="hostS1" url="192.168.254.136:3306" user="root" password="wuzhenzhao" /> </writeHost> </dataHost> <!-- 配置db_user的節點主機 --> <dataHost name="db_userHOST1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="userHost1" url="192.168.254.138:3306" user="root" password="wuzhenzhao"> </writeHost> </dataHost> <dataHost name="db_userHOST2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="userHost2" url="192.168.254.136:3306" user="root" password="wuzhenzhao"> </writeHost> </dataHost> </mycat:schema>
schema 標簽:
schema 標簽用於定義 MyCat 實例中的邏輯庫,MyCat 可以有多個邏輯庫,每個邏輯庫都有自己的相關配 置。可以使用 schema 標簽來划分這些不同的邏輯庫。
1)dataNode 屬性:該屬性用於綁定邏輯庫到某個具體的 database 上。
2)checkSQLschema 屬性:當該值設置為 true 時,如果我們執行語句**select * from TESTDB.travelrecord;**則 MyCat 會把語句修改 為**select * from travelrecord;**。即把表示 schema 的字符去掉,避免發送到后端數據庫執行時報**(ERROR 1146 (42S02): Table ‘testdb.travelrecord’ doesn’t exist)。** 不過,即使設置該值為 true ,如果語句所帶的是並非是 schema 指定的名字,例如:**select * from db1.travelrecord;** 那么 MyCat 並不會刪除 db1 這個字段,如果沒有定義該庫的話則會報錯,所以在提供 SQL 語句的最好是不帶這個字段。
3)sqlMaxLimit 屬性:當該值設置為某個數值時。每條執行的 SQL 語句,如果沒有加上 limit 語句,MyCat 也會自動的加上所對應 的值。需要注意的是,如果運行的 schema 為非拆分庫的,那么該屬性不會生效。需要手動添加 limit 語句。
table 標簽:
Table 標簽定義了 MyCat 中的邏輯表,所有需要拆分的表都需要在這個標簽中定義。
1)name 屬性: 定義邏輯表的表名,這個名字就如同我在數據庫中執行 create table 命令指定的名字一樣,同個 schema 標 簽中定義的名字必須唯一。
2)dataNode 屬性: 定義這個邏輯表所屬的 dataNode, 該屬性的值需要和 dataNode 標簽中 name 屬性的值相互對應。如果需 要定義的 dn 過多 可以使用($1-2) 方法減少配置。例如我上面的例子。
3)rule 屬性: 該屬性用於指定邏輯表要使用的規則名字,規則名字在 rule.xml 中定義,必須與 tableRule 標簽中 name 屬 性屬性值一一對應。
4)ruleRequired 屬性: 該屬性用於指定表是否綁定分片規則,如果配置為 true,但沒有配置具體 rule 的話 ,程序會報錯。
5)primaryKey 屬性 :該邏輯表對應真實表的主鍵,例如:分片的規則是使用非主鍵進行分片的,那么在使用主鍵查詢的時候,就 會發送查詢語句到所有配置的 DN (dataNode)上,如果使用該屬性配置真實表的主鍵。難么 MyCat 會緩存主鍵與具體 DN 的 信息,那么再次使用非主鍵進行查詢的時候就不會進行廣播式的查詢,就會直接發送語句給具體的 DN,但是盡管 配置該屬性,如果緩存並沒有命中的話,還是會發送語句給具體的 DN,來獲得數據。推薦配置成有唯一索引的字段,這樣子能大大提高數據庫性能。
6)type 屬性:該屬性定義了邏輯表的類型,目前邏輯表只有“全局表”和”普通表”兩種類型。對應的配置:全局表:global。普通表:不指定該值為 globla 的所有表。
7)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” 來禁用這個功能,當然你也可以直接刪除掉這個屬性。默認就是禁用的。
8)subTables 屬性: 使用方式添加 subTables="t_order$1-2,t_order3"。 目前分表 1.6 以后開始支持 並且 dataNode 在分表條件下只能配置一個,分表條件下不支持各種條件的 join 語句。
9)needAddLimit 屬性 :指定表是否需要自動的在每個語句后面加上 limit 限制。由於使用了分庫分表,數據量有時會特別巨大。這時 候執行查詢語句,如果恰巧又忘記了加上數量限制的話。那么查詢所有的數據出來,也夠等上一小會兒的。 所以,mycat 就自動的為我們加上 LIMIT 100。當然,如果語句中有 limit,就不會在次添加了。 這個屬性默認為 true,你也可以設置成 false`禁用掉默認行為。
childTable 標簽:
childTable 標簽用於定義 E-R 分片的子表。通過標簽上的屬性與父表進行關聯。
1)name 屬性 定義子表的表名。
2)joinKey 屬性 插入子表的時候會使用這個列的值查找父表存儲的數據節點。
3)parentKey 屬性 屬性指定的值一般為與父表建立關聯關系的列名。程序首先獲取 joinkey 的值,再通過 parentKey 屬性指定 的列名產生查詢語句,通過執行該語句得到父表存儲在哪個分片上。從而確定子表存儲的位置。
4)primaryKey 屬性 同 table 標簽所描述的。
5)needAddLimit 屬性 同 table 標簽所描述的。
dataNode 標簽:
dataNode 標簽定義了 MyCat 中的數據節點,也就是我們通常說所的數據分片。
1)name 屬性: 定義數據節點的名字,這個名字需要是唯一的,我們需要在 table 標簽上應用這個名字,來建立表與分片對 應的關系。
2)dataHost 屬性 :該屬性用於定義該分片屬於哪個數據庫實例的,屬性值是引用 dataHost 標簽上定義的 name 屬性。
3)database 屬性: 該屬性用於定義該分片屬性哪個具體數據庫實例上的具體庫,因為這里使用兩個緯度來定義分片,就是:實 例+具體的庫。因為每個庫上建立的表和表結構是一樣的。所以這樣做就可以輕松的對表進行水平拆分。
dataHost 標簽 :
作為 Schema.xml 中最后的一個標簽,該標簽在 mycat 邏輯庫中也是作為最底層的標簽存在,直接定義了具 體的數據庫實例、讀寫分離配置和心跳語句。現在我們就解析下這個標簽。
dataHost 標簽的相關屬性:屬性名,值,數量限制
1)name String (1) :唯一標識 dataHost 標簽,供上層的標簽使用。
2)maxCon Integer (1) :指定每個讀寫實例連接池的最大連接。
3)minCon Integer (1) :指定每個讀寫實例連接池的最小連接,初始化連接池的大小。
4)balance Integer (1) :負載均衡類型,目前的取值有 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 只在 1.4 及其以后版本有,1.3 沒有。
5)writeType Integer (1) :
負載均衡類型,目前的取值有 3 種:
1. writeType="0", 所有寫操作發送到配置的第一個 writeHost,第一個掛了切到還生存的第二個 writeHost,重新啟動后以切換后的為准,切換記錄在配置文件中:dnindex.properties 。
2. writeType="1",所有寫操作都隨機的發送到配置的 writeHost,1.5 以后廢棄不推薦。switchType 屬 性 - -1 表示不自動切換。 - 1 默認值,自動切換。 - 2 基於 MySQL 主從同步的狀態決定是否切換。
6)dbType String (1) :指定后端連接的數據庫類型,目前支持二進制的 mysql 協議,還有其他使用 JDBC 連接的數據庫。例如: mongodb、oracle、mysql、spark 等。
7)dbDriver String (1):指定連接后端數據庫使用的 Driver,目前可選的值有 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。
8) switchType 屬性: 主從切換策略
-1 表示不自動切換。
1 默認值,自動切換 ,心跳 select user()。
2 基於 MySQL 主從同步的狀態決定是否切換 心跳語句為 show slave status (主從延遲解決方案)。
3 基於 MySQL galary cluster 的切換機制(適合集群)(1.4.1) 心跳語句為 show status like ‘wsrep%。
9) slaveThreshold屬性: 由於配置了 switch Type屬性,會執行心跳語句 select user(),而這個屬性就是查看slave的狀態有個屬性叫 Seconds_Behind_Master,這個屬性大於 slave Threshold 配置的值,我們這里是大於100秒,就不會去讀取。
超時的從節點,所有數據會從沒有延遲的節點去加載或者從主節點加載。
writeHost 標簽、readHost 標簽:
這兩個標簽都指定后端數據庫的相關配置給 mycat,用於實例化后端連接池。唯一不同的是,writeHost 指 定寫實例、readHost 指定讀實例,組着這些讀寫實例來滿足系統的要求。 在一個 dataHost 內可以定義多個 writeHost 和 readHost。但是,如果 writeHost 指定的后端數據庫宕機, 那么這個 writeHost 綁定的所有 readHost 都將不可用。另一方面,由於這個 writeHost 宕機系統會自動的檢測 到,並切換到備用的 writeHost 上去。
1)host 屬性 :用於標識不同實例,一般 writeHost 我們使用*M1,readHost 我們用*S1。
2)url 屬性: 后端實例連接地址,如果是使用 native 的 dbDriver,則一般為 address:port 這種形式。用 JDBC 或其他的 dbDriver,則需要特殊指定。當使用 JDBC 時則可以這么寫:jdbc:mysql://localhost:3306/。
3)user 屬性 :后端存儲實例需要的用戶名字。
4)password 屬性 :后端存儲實例需要的密碼。
5)weight 屬性 :權重 配置在 readhost 中作為讀節點的權重(1.4 以后)。
6)usingDecrypt 屬性: 是否對密碼加密默認 0 否 如需要開啟配置 1,同時使用加密程序對密碼加密,加密命令為: 執行 mycat jar 程序(1.4.1 以后):
java -cp Mycat-server-1.6.6.1-release.jar io.mycat.util.DecryptUtil 1:host:user:password Mycat-server-1.6.6.1-release.jar 為 mycat lib 目錄的 jar 1:host:user:password 中 1 為 db 端加密標志,host 為 dataHost 的 host 名稱
執行結果如下:將該加密串替換掉password的值就可以提高密碼安全性。這個時候請加上 usingDecrypt

server.xml:
server.xml 幾乎保存了所有 mycat 需要的系統配置信息。其在代碼內直接的映射類為 SystemConfig 類。
<?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="useSqlStat">0</property> <!-- 1為開啟實時統計、0為關閉 --> <property name="useGlobleTableCheck">0</property> <!-- 1為開啟全加班一致性檢測、0為關閉 --> <property name="sequnceHandlerType">2</property> <!-- <property name="useCompression">1</property>--> <!--1為開啟mysql壓縮協議--> <!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--設置模擬的MySQL版本號--> <!-- <property name="processorBufferChunk">40960</property> --> <!-- <property name="processors">1</property> <property name="processorExecutor">32</property>--> <!--默認為type 0: DirectByteBufferPool | type 1 ByteBufferArena--> <property name="processorBufferPoolType">0</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="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> --> <!--分布式事務開關,0為不過濾分布式事務,1為過濾分布式事務(如果分布式事務內只涉及全局表,則不過濾), 2為不過濾分布式事務,但是記錄分布式事務日志--> <property name="handleDistributedTransactions">0</property> <!--off heap for merge/order/group/limit 1開啟 0關閉--> <property name="useOffHeapForMerge">1</property> <!--單位為m--> <property name="memoryPageSize">1m</property> <!--單位為k--> <property name="spillsFileBufferSize">1k</property> <property name="useStreamOutput">0</property> <!--單位為m--> <property name="systemReserveMemorySize">384m</property> <!--是否采用zookeeper協調切換 --> <property name="useZKSwitch">true</property> </system> <!-- 全局SQL防火牆設置 --> <!-- <firewall> <whitehost> <host host="127.0.0.1" user="mycat"/> <host host="127.0.0.2" user="mycat"/> </whitehost> <blacklist check="false"> </blacklist> </firewall> --> <!--把mycat看成一個超級數據庫,在這里配置數據庫的用戶密碼及可以訪問的數據庫--> <user name="root"> <property name="password">wuzhenzhao</property> <property name="schemas">db_store,db_user</property> <!-- 表級 DML 權限設置 --> <!-- <privileges check="false"> <schema name="db_user" dml="0110" > <table name="users" dml="1111"></table> IUSD <table name="useraddres" dml="1110"></table> </schema> </privileges>--> </user> </mycat:server> --> </user> </mycat:server>
system 標簽:
這個標簽內嵌套的所有 property 標簽都與系統配置有關,請注意,下面我會省去標簽 property 直接使用這 個標簽的 name 屬性內的值來介紹這個屬性的作用。
1)sequnceHandlerType 屬性 :指定使用 Mycat 全局序列的類型。0 為本地文件方式,1 為數據庫方式,2 為時間戳序列方式,3 為分布式 ZK ID 生成器,4 為 zk 遞增 id 生成。 從 1.6 增加 兩種 ZK 的全局 ID 生成算法。
2)processors 屬性 :這個屬性主要用於指定系統可用的線程數,默認值為機器 CPU 核心線程數。 主要影響 processorBufferPool、processorBufferLocalPercent、processorExecutor 屬性。 NIOProcessor 的個數也是由這個屬性定義的,所以調優的時候可以適當的調高這個屬性。
3)processorExecutor 屬性:線程池內線程的數量
4)serverPort : 定義 mycat 的使用端口,默認值為 8066。
5)managerPort : 定義 mycat 的管理端口,默認值為 9066。 可以使用mysql -uroot -p123456 -P9066 -h192.168.254.138 登陸管理端。
firewall 標簽:
全局sql防火牆的設置,設置黑(blacklist)/白(whitehost)名單,黑白名單互斥,理論上只存在一個。
user 標簽:
這個標簽主要用於定義登錄 mycat 的用戶和權限。例如上面的例子中,我定 義了一個用戶,用戶名為 root、密碼為 wuzhenzhao,可訪問的 schema 有 db_store,db_user 兩個。 如果我在 schema.xml 中定義了多個 schema,那么這個用戶是無法訪問其他的 schema。在 mysql 客戶端看來 則是無法使用 use 切換到這個其他的數據庫。
1)Benchmark 屬性:Benchmark:mycat 連接服務降級處理: benchmark 基准, 當前端的整體 connection 數達到基准值是, 對來自該賬戶的請求開始拒絕連接,0 或不設 表示不限制 例如 1000
2)usingDecrypt 屬性: 80 是否對密碼加密默認 0 否 如需要開啟配置 1,在上篇博客中有詳細說明。
privileges 標簽:
對用戶的 schema 及 下級的 table 進行精細化的 DML 權限控制,privileges 節點中的 check 屬性是用 於標識是否開啟 DML 權限檢查, 默認 false 標識不檢查,當然 privileges 節點不配置,等同 check=false, 由於 Mycat 一個用戶的 schemas 屬性可配置多個 schema ,所以 privileges 的下級節點 schema 節點同樣 可配置多個,對多庫多表進行細粒度的 DML 權限控制
按照以上 XML 所配置的來說 root 用戶對於庫 db_user 的權限是 0110 ,對於users 表是1111 ,對應的操作是 IUSD ( 增,改,查,刪 )。同時配置了庫跟表的權限,就近原則。以表權限為准。
rule.xml:
rule.xml 里面就定義了我們對表進行拆分所涉及到的規則定義。我們可以靈活的對表使用不同的分片算法, 或者對表使用相同的算法但具體的參數不同。這個文件里面主要有 tableRule 和 function 這兩個標簽。在具體使 用過程中可以按照需求添加 tableRule 和 function。
<?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:rule SYSTEM "rule.dtd"> <mycat:rule xmlns:mycat="http://io.mycat/"> ........ <tableRule name="mod-long"> <rule> <columns>id</columns> <algorithm>mod-long</algorithm> </rule> </tableRule> <!-- 分片規則定義--> <tableRule name="mod-userID-long"> <rule> <!--根據哪個列來分區--> <columns>userID</columns> <!--分區算法,指向下面的function 標簽--> <algorithm>mod-long</algorithm> </rule> </tableRule> <tableRule name="sharding-by-murmur"> <rule> <columns>id</columns> <algorithm>murmur</algorithm> </rule> </tableRule> <tableRule name="crc32slot"> <rule> <columns>id</columns> <algorithm>crc32slot</algorithm> </rule> </tableRule> <!--指定分片類。指定規則與2取模--> <function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">2</property> </function> <function name="murmur" class="io.mycat.route.function.PartitionByMurmurHash"> <property name="seed">0</property><!-- 默認是0 --> <property name="count">2</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 --> <property name="virtualBucketTimes">160</property><!-- 一個實際的數據庫節點被映射為這么多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍 --> <!-- <property name="weightMapFile">weightMapFile</property> 節點的權重,沒有指定權重的節點默認是1。以properties文件的格式填寫,以從0開始到count-1的整數值也就是節點索引為key,以節點權重值為值。所有權重值必須是正整數,否則以1代替 --> <!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> 用於測試時觀察各物理節點與虛擬節點的分布情況,如果指定了這個屬性,會把虛擬節點的murmur hash值與物理節點的映射按行輸出到這個文件,沒有默認值,如果不指定,就不會輸出任何東西 --> </function> <function name="crc32slot" class="io.mycat.route.function.PartitionByCRC32PreSlot"> <property name="count">2</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 --> </function> ........ </mycat:rule>
這個配置文件的內容屬性比較少,具體作用都標注在XML 里面了。分片規則在 mycat權威指南中說的相當詳細(從118頁開始)。我這里就簡單的描述一下。
根據官方提供的分片規則的特點來分,可以分成三大類:連續分片,離散分片,綜合類分片。
1)連續分片:
該分片規則的代表是按日期(天)分片,按照自定義數字范圍分片,自然月分片,該分片規則的優點是擴容無需遷移數據庫,范圍條件查詢資源消耗少,缺點是並發能力受限於分片節點。
2)離散分片:
該分片規則的代表是枚舉分片,數字取模分片,字符串數字hash分片,一致性hash分片,程序指定,該分片規則的優點是數據分布均勻,並發能力強,不受限分片節點,缺點是移植性差,擴容難。
3)綜合類分片:
該分片規則的代表是范圍求模分片,取模范圍約束分片,該分片規則的優點是兼並以上二者 。
規則是很多,我這邊主要列舉兩個,一個是按照數字范圍分片跟取模分片,想了解更多請翻閱mycat權威指南,鏈接在頂部。
數字范圍分片配置:
此分片適用於,提前規划好分片字段某個范圍屬於哪個分片, start <= range <= end. range start-end ,data node index K=1000,M=10000.
<tableRule name="auto-sharding-long"> <rule> <columns>user_id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule> <function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong"> <!--規則配置文件-->
<property name="mapFile">autopartition-long.txt</property>
<!--超出的范圍記錄在0號分片上-->
<property name="defaultNode">0</property> </function>
配置說明: 上面 columns 標識將要分片的表字段,algorithm 分片函數, rang-long 函數中 mapFile 代表配置文件路徑 ,查看如下:

defaultNode 超過范圍后的默認節點。 所有的節點配置都是從 0 開始,及 0 代表節點 1,此配置非常簡單,即預先制定可能的 id 范圍到某個分片 0-500M=0 500M-1000M=1 1000M-1500M=2 或 0-10000000=0 10000001-20000000=1。
取模分片:
此規則為對分片字段求摸運算。
<tableRule name="mod-long"> <rule> <columns>user_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">3</property> </function>
配置說明: 上面 columns 標識將要分片的表字段,algorithm 分片函數, 此種配置非常明確即根據 id 進行十進制求模預算,相比固定分片 hash,此種在批量插入時可能存在批量插入單 事務插入多數據分片,增大事務一致性難度。
分片取舍:
數據特點:活躍的數據熱度較高規模可以預期,增長量比較穩定,首選 固定數量的離散分片規
數據特點:活躍的數據為歷史數據,熱度要求不高。規模可以預期,增長量比較穩定. 優勢可定時清理或者遷移,連續分規則優先。
分片選擇:
1,根據業務數據的特性合理選擇分片規則。
2,善用全局表、ER關系表解決join操作。
3,用好primaryKey讓你的性能起飛。
全局序列號:
在實現分庫分表的情況下,數據庫自增主鍵已無法保證自增主鍵的全局唯一。為此,MyCat 提供了全局 sequence,並且提供了包含本地配置和數據庫配置等多種實現方式。0 為本地文件方式,1 為數據庫方式,2 為時間戳序列方式,3 為分布式 ZK ID 生成器,4 為 zk 遞增 id 生成。 從 1.6 增加 兩種 ZK 的全局 ID 生成算法。我這里主要介紹前3種,也是比較常用的方式。
本地文件方式: 原理:此方式 MyCAT 將 sequence 配置到文件中,當使用到 sequence 中的配置后,MyCAT 會更下 classpath 中的 sequence_conf.properties 文件中 sequence 當前的值。
配置方式: 在 sequence_conf.properties 文件中做如下配置:
GLOBAL_SEQ.HISIDS=
GLOBAL_SEQ.MINID=1001
GLOBAL_SEQ.MAXID=1000000000
GLOBAL_SEQ.CURID=1000
其中 HISIDS 表示使用過的歷史分段(一般無特殊需要可不配置),MINID 表示最小 ID 值,MAXID 表示最大 ID 值,CURID 表示當前 ID 值。 server.xml 中配置:
<system><property name="sequnceHandlerType">0</property></system>
配置完可以登陸命令行監控工具查看配置信息:

注:sequnceHandlerType 需要配置為 0,表示使用本地文件方式。 使用示例:insert into users(userID,username,phoneNum) values(next value for MYCATSEQ_GLOBAL,‘本地全局序號’,'13858765412'); 缺點:當 MyCAT 重新發布后,配置文件中的 sequence 會恢復到初始值。 優點:本地加載,讀取速度較快。看結果:

數據庫方式:
在數據庫中建立一張表,存放 sequence 名稱(name),sequence 當前值(current_value),步長(increment int 類型每次讀取多少個 sequence
server.xml 配置:sequnceHandlerType 需要配置為 1,表示使用數據庫方式生成 sequence。
1.創建 MYCAT_SEQUENCE 表:
DROP TABLE IF EXISTS MYCAT_SEQUENCE;
CREATE TABLE `MYCAT_SEQUENCE` (
`NAME` varchar(50) NOT NULL,
`current_value` int(11) NOT NULL,
`increment` int(11) NOT NULL DEFAULT '100',
PRIMARY KEY (`NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.創建相關的 FUNCTION ,返回當前的sequence的值:
DROP FUNCTION IF EXISTS mycat_seq_currval;
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval='-999999999,null';
SELECT concat(CAST(current_value AS CHAR),',',CAST(increment AS CHAR)) INTO retval FROM
MYCAT_SEQUENCE WHERE name = seq_name;
RETURN retval;
END
設置sequence的值:
DROP FUNCTION IF EXISTS mycat_seq_setval;
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),value INTEGER) RETURNS varchar(64)
CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END
獲取下一個sequence的值:
DROP FUNCTION IF EXISTS mycat_seq_nextval;
CREATE FUNCTION mycat_seq_nextval ( seq_name VARCHAR ( 50 ) ) RETURNS VARCHAR ( 64 ) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END
創建完MYCAT_SEQUENCE 表跟3個FUNCTION 后需要配置 schema.xml,在指定的 schema中加入以下信息:dataNode表示你創建表跟函數的哪個節點配置
<table name = "mycat_sequence" dataNode ="db_user_dataNode1" />
然后配置 sequence_db_conf.properties 注釋掉原來的所有東西,加入以下:這個USERS就是等等使用插入命令用的。
USERS=db_user_dataNode1
注意:MYCAT_SEQUENCE 表和以上的 3 個 function,需要放在同一個節點上。然后重啟 mycat服務,執行 insert into users(userID,username,phoneNum) values(next value for MYCATSEQ_USERS,'數據庫序列號','13858765412'); 。這個執行語句中 next value for MYCATSEQ_USERS 的USERS就是在 sequence_db_conf.properties 中配置的。結果如下。

本地時間戳方式:
ID= 64 位二進制 (42(毫秒)+5(機器 ID)+5(業務編碼)+12(重復累加) 換算成十進制為 18 位數的 long 類型,每毫秒可以並發 12 位二進制的累加。
1.配置 server.xml :sequnceHandlerType 需要配置為 2.
2.在 mycat 下配置:sequence_time_conf.properties.
WORKID=0-31 任意整數
DATAACENTERID=0-31 任意整數
多個 mycat 節點下每個 mycat 配置的 WORKID,DATAACENTERID 不同,組成唯一標識,總共支持 32*32=1024 種組合。
3.在 schema.xml 的對應邏輯表位置配置 autoIncrement="true"。重啟mycat服務,使用插入語句 insert into users(username,phoneNum) values("本地時間戳序列號","165498467684"); 注意這里需要把userID的長度設置成 bigint。不然會報錯,結果如下:

最后來看以下命令行監控工具:使用命令 mysql -uroot -p123456 -P9066 -h 192.168.254.138 這里的信息都是 mycat 的信息。進入控制台輸入 show @@help; 查看命令:
可以通過這些命令查看所有你想獲取的信息。

