數(shù)據(jù)庫(kù)中間件之Mycat

Mycat入門(mén)

轉(zhuǎn)載自https://chenjiabing666.github.io/2018/10/07/Mycat/

安裝

  • 點(diǎn)擊下載
  • 配置java環(huán)境
  • 配置mysql數(shù)據(jù)庫(kù)
  • 打開(kāi)conf/wrapper.conf文件冒窍,將其中的wrapper.java.command的值改成服務(wù)器上的jdk地址,如wrapper.java.command=/usr/local/jdk/jdk1.8.0_172/bin/java
  • 為bin文件夾中的所有內(nèi)容賦予執(zhí)行的權(quán)限:chmod a+x *
  • 修改schemal.xml文件中的內(nèi)容劫笙,填上對(duì)應(yīng)的表,數(shù)據(jù)節(jié)點(diǎn),數(shù)據(jù)主機(jī)的內(nèi)容
  • 啟動(dòng) :./mycat start (后臺(tái)啟動(dòng))、./mycat console(前臺(tái)啟動(dòng))
  • 開(kāi)啟服務(wù)器的8086端口
  • 使用navicat連接mycat,端口是8086

常用的命令

./mycat start 啟動(dòng)

./mycat stop 停止

./mycat console 前臺(tái)運(yùn)行

./mycat install 添加到系統(tǒng)自動(dòng)啟動(dòng)(暫未實(shí)現(xiàn))

./mycat remove 取消隨系統(tǒng)自動(dòng)啟動(dòng)(暫未實(shí)現(xiàn))

./mycat restart 重啟服務(wù)

./mycat pause 暫停

./mycat status 查看啟動(dòng)狀態(tài)

數(shù)據(jù)庫(kù)切分

  • 數(shù)據(jù)庫(kù)切分分為垂直切分踱承,水平切分

垂直切分

  • 一個(gè)數(shù)據(jù)庫(kù)由很多表的構(gòu)成,每個(gè)表對(duì)應(yīng)著不同的業(yè)務(wù)米母,垂直切分是指按照業(yè)務(wù)將表進(jìn)行分類(lèi)勾扭,分布到不同 的數(shù)據(jù)庫(kù)上面毡琉,這樣也就將數(shù)據(jù)或者說(shuō)壓力分擔(dān)到不同的庫(kù)上面 铁瞒。
  • 比如商城項(xiàng)目可以根據(jù)不同的業(yè)務(wù)將表分成用戶(hù)表、訂單表等桅滋,這些表分布在不同的數(shù)據(jù)庫(kù)中慧耍,從而實(shí)現(xiàn)了垂直切分
  • 優(yōu)點(diǎn):
    • 拆分后業(yè)務(wù)清晰,拆分規(guī)則明確丐谋。
    • 系統(tǒng)之間整合或擴(kuò)展容易
    • 數(shù)據(jù)維護(hù)簡(jiǎn)單芍碧。
  • 缺點(diǎn):
    • 部分業(yè)務(wù)表無(wú)法 join,只能通過(guò)接口方式解決号俐,提高了系統(tǒng)復(fù)雜度泌豆。
    • 受每種業(yè)務(wù)不同的限制存在單庫(kù)性能瓶頸,不易數(shù)據(jù)擴(kuò)展跟性能提高吏饿。
    • 事務(wù)處理復(fù)雜踪危。
  • 由于垂直切分是按照業(yè)務(wù)的分類(lèi)將表分散到不同的庫(kù)蔬浙,所以有些業(yè)務(wù)表會(huì)過(guò)于龐大,存在單庫(kù)讀寫(xiě)與存儲(chǔ)瓶 頸贞远,所以就需要水平拆分來(lái)做解決畴博。

水平切分

  • 水平拆分不是將表做分類(lèi),而是按照某個(gè)字段的某種規(guī)則來(lái)分散到多個(gè)庫(kù)之中蓝仲,每個(gè)表中 包含一部分?jǐn)?shù)據(jù)俱病。簡(jiǎn)單來(lái)說(shuō),我們可以將數(shù)據(jù)的水平切分理解為是按照數(shù)據(jù)行的切分袱结,就是將表中的某些行切分 到一個(gè)數(shù)據(jù)庫(kù)亮隙,而另外的某些行又切分到其他的數(shù)據(jù)庫(kù)中
  • 拆分規(guī)則:
    • 按照用戶(hù) ID 求模,將數(shù)據(jù)分散到不同的數(shù)據(jù)庫(kù)垢夹,具有相同數(shù)據(jù)用戶(hù)的數(shù)據(jù)都被分散到一個(gè)庫(kù)中咱揍。
    • 按照日期,將不同月甚至日的數(shù)據(jù)分散到不同的庫(kù)中棚饵。
    • 按照某個(gè)特定的字段求摸煤裙,或者根據(jù)特定范圍段分散到不同的庫(kù)中。
  • 優(yōu)點(diǎn):
    • 拆分規(guī)則抽象好噪漾,join 操作基本可以數(shù)據(jù)庫(kù)做硼砰。
    • 不存在單庫(kù)大數(shù)據(jù),高并發(fā)的性能瓶頸欣硼。
    • 應(yīng)用端改造較少题翰。
    • 提高了系統(tǒng)的穩(wěn)定性跟負(fù)載能力。
  • 缺點(diǎn):
    • 拆分規(guī)則難以抽象诈胜。
    • 分片事務(wù)一致性難以解決豹障。
    • 數(shù)據(jù)多次擴(kuò)展難度跟維護(hù)量極大。
    • 跨庫(kù) join 性能較差焦匈。

垂直拆分和水平拆分的共同缺點(diǎn)

  • 引入分布式事務(wù)的問(wèn)題血公。
  • 跨節(jié)點(diǎn) Join 的問(wèn)題。
  • 跨節(jié)點(diǎn)合并排序分頁(yè)問(wèn)題缓熟。
  • 多數(shù)據(jù)源管理問(wèn)題累魔。

日志分析

sql防火墻配置

  • 在server.xml中配置

Mycat配置

schema(邏輯庫(kù))

  • 一個(gè)標(biāo)簽,定義一個(gè)邏輯數(shù)據(jù)庫(kù)够滑】研矗可以同時(shí)指定多個(gè)標(biāo)簽來(lái)指定不同的邏輯庫(kù)

  • 標(biāo)簽體的屬性如下:

    • dataNode:字符串,該屬性用于綁定邏輯庫(kù)到某個(gè)具體的 database 上 彰触,多個(gè)值用逗號(hào)分隔
    • checkSQLschema:布爾值梯投,當(dāng)該值設(shè)置為 true 時(shí),如果我們執(zhí)行語(yǔ)句select * from TESTDB.travelrecord;則 MyCat 會(huì)把語(yǔ)句修改 為select * from travelrecord; ,設(shè)置這個(gè)屬性為true分蓖,可以在navicat中直接查看邏輯表中的所有數(shù)據(jù)吮龄,否則將會(huì)報(bào)異常(Table ‘testdb.travelrecord’ doesn’ t exist)
    • sqlMaxLimit:當(dāng)該值設(shè)置為某個(gè)數(shù)值時(shí)。每條執(zhí)行的 SQL 語(yǔ)句咆疗,如果沒(méi)有加上 limit 語(yǔ)句漓帚,MyCat 也會(huì)自動(dòng)的加上所對(duì)應(yīng) 的值。例如設(shè)置值為 100午磁,執(zhí)行select * from TESTDB.travelrecord;的效果為和執(zhí)行select * from TESTDB.travelrecord limit 100;相同尝抖。 設(shè)置該值的話(huà),MyCat 默認(rèn)會(huì)把查詢(xún)到的信息全部都展示出來(lái)迅皇,造成過(guò)多的輸出昧辽。所以,在正常使用中登颓,還 是建議加上一個(gè)值搅荞,用于減少過(guò)多的數(shù)據(jù)返回.當(dāng)然 SQL 語(yǔ)句中也顯式的指定 limit 的大小,不受該屬性的約束框咙。 需要注意的是咕痛,如果運(yùn)行的 schema 為非拆分庫(kù)的,那么該屬性不會(huì)生效喇嘱。需要手動(dòng)添加 limit 語(yǔ)句茉贡。

table (邏輯表)

  • 屬性如下:
name String 定義邏輯表的表名,這個(gè)名字就如同我在數(shù)據(jù)庫(kù)中執(zhí)行 create table 命令指定的名字一樣者铜,同個(gè) schema 標(biāo) 簽中定義的名字必須唯一
dataNode String 定義這個(gè)邏輯表所屬的 dataNode, 該屬性的值需要和 dataNode 標(biāo)簽中 name 屬性的值相互對(duì)應(yīng)腔丧。多個(gè)值用逗號(hào)分隔
rule String 該屬性用于指定邏輯表要使用的規(guī)則名字,規(guī)則名字在 rule.xml 中定義作烟,必須與 tableRule 標(biāo)簽中 name 屬 性屬性值一一對(duì)應(yīng)
ruleRequired boolean 該屬性用于指定表是否綁定分片規(guī)則愉粤,如果配置為 true,但沒(méi)有配置具體 rule 的話(huà) 拿撩,程序會(huì)報(bào)錯(cuò)衣厘。
primaryKey String 該邏輯表對(duì)應(yīng)真實(shí)表的主鍵,例如:分片的規(guī)則是使用非主鍵進(jìn)行分片的绷雏,那么在使用主鍵查詢(xún)的時(shí)候头滔,就 會(huì)發(fā)送查詢(xún)語(yǔ)句到所有配置的 DN 上,如果使用該屬性配置真實(shí)表的主鍵涎显。難么 MyCat 會(huì)緩存主鍵與具體 DN 的 信息,那么再次使用非主鍵進(jìn)行查詢(xún)的時(shí)候就不會(huì)進(jìn)行廣播式的查詢(xún)兴猩,就會(huì)直接發(fā)送語(yǔ)句給具體的 DN期吓,但是盡管 配置該屬性,如果緩存并沒(méi)有命中的話(huà),還是會(huì)發(fā)送語(yǔ)句給具體的 DN讨勤,來(lái)獲得數(shù)據(jù)箭跳。如果沒(méi)有指定,那么默認(rèn)使用的是主鍵字段是id
type String 該屬性定義了邏輯表的類(lèi)型潭千,目前邏輯表只有“全局表”和”普通表”兩種類(lèi)型谱姓。對(duì)應(yīng)的配置: 1、全局表:global刨晴。 2屉来、 普通表:不指定該值為 globla 的所有表
autoIncrement boolean mysql 對(duì)非自增長(zhǎng)主鍵,使用 last_insert_id()是不會(huì)返回結(jié)果的狈癞,只會(huì)返回 0茄靠。所以,只有定義了自增長(zhǎng)主 鍵的表才可以用 last_insert_id()返回主鍵值蝶桶。 mycat 目前提供了自增長(zhǎng)主鍵功能慨绳,但是如果對(duì)應(yīng)的 mysql 節(jié)點(diǎn)上數(shù)據(jù)表,沒(méi)有定義 auto_increment真竖,那 么在 mycat 層調(diào)用 last_insert_id()也是不會(huì)返回結(jié)果的脐雪。 由于 insert 操作的時(shí)候沒(méi)有帶入分片鍵,mycat 會(huì)先取下這個(gè)表對(duì)應(yīng)的全局序列恢共,然后賦值給分片鍵喂江。這樣 才能正常的插入到數(shù)據(jù)庫(kù)中,最后使用 last_insert_id()才會(huì)返回插入的分片鍵值旁振。 如果要使用這個(gè)功能最好配合使用數(shù)據(jù)庫(kù)模式的全局序列获询。 75 使用 autoIncrement=“true” 指定這個(gè)表有使用自增長(zhǎng)主鍵,這樣 mycat 才會(huì)不拋出分片鍵找不到的異 常拐袜。 使用 autoIncrement=“false” 來(lái)禁用這個(gè)功能吉嚣,當(dāng)然你也可以直接刪除掉這個(gè)屬性。默認(rèn)就是禁用的蹬铺。
subTables String
needAddLimit boolean 指定表是否需要自動(dòng)的在每個(gè)語(yǔ)句后面加上 limit 限制尝哆。由于使用了分庫(kù)分表,數(shù)據(jù)量有時(shí)會(huì)特別巨大甜攀。這時(shí) 候執(zhí)行查詢(xún)語(yǔ)句秋泄,如果恰巧又忘記了加上數(shù)量限制的話(huà)。那么查詢(xún)所有的數(shù)據(jù)出來(lái)规阀,也夠等上一小會(huì)兒的恒序。 所以,mycat 就自動(dòng)的為我們加上 LIMIT 100谁撼。當(dāng)然歧胁,如果語(yǔ)句中有 limit,就不會(huì)在次添加了。 這個(gè)屬性默認(rèn)為 true,你也可以設(shè)置成 false`禁用掉默認(rèn)行為喊巍。

dataNode

  • 數(shù)據(jù)節(jié)點(diǎn)屠缭,用來(lái)設(shè)置
name String 定義數(shù)據(jù)節(jié)點(diǎn)的名字,這個(gè)名字需要是唯一的崭参,我們需要在 table 標(biāo)簽上應(yīng)用這個(gè)名字呵曹,來(lái)建立表與分片對(duì) 應(yīng)的關(guān)系
dataHost String 該屬性用于定義該分片屬于哪個(gè)數(shù)據(jù)庫(kù)實(shí)例的,屬性值是引用 dataHost 標(biāo)簽上定義的 name 屬性何暮。
database String 該屬性用于定義該分片屬性哪個(gè)具體數(shù)據(jù)庫(kù)實(shí)例上的具體庫(kù)奄喂,因?yàn)檫@里使用兩個(gè)緯度來(lái)定義分片,就是:實(shí) 例+具體的庫(kù)郭卫。因?yàn)槊總€(gè)庫(kù)上建立的表和表結(jié)構(gòu)是一樣的砍聊。所以這樣做就可以輕松的對(duì)表進(jìn)行水平拆分

dataHost

  • 作為 Schema.xml 中最后的一個(gè)標(biāo)簽,該標(biāo)簽在 mycat 邏輯庫(kù)中也是作為最底層的標(biāo)簽存在贰军,直接定義了具 體的數(shù)據(jù)庫(kù)實(shí)例玻蝌、讀寫(xiě)分離配置和心跳語(yǔ)句。現(xiàn)在我們就解析下這個(gè)標(biāo)簽词疼。

  • 配置如下:

name String 唯一標(biāo)識(shí) dataHost 標(biāo)簽俯树,供上層的標(biāo)簽使用。
maxCon Integer 指定每個(gè)讀寫(xiě)實(shí)例連接池的最大連接贰盗。也就是說(shuō)许饿,標(biāo)簽內(nèi)嵌套的 writeHost、 readHost 標(biāo)簽都會(huì)使用這個(gè)屬 性的值來(lái)實(shí)例化出連接池的最大連接數(shù)
minCon Integer 指定每個(gè)讀寫(xiě)實(shí)例連接池的最小連接舵盈,初始化連接池的大小
balance Integer 負(fù)載均衡類(lèi)型陋率,目前的取值有 3 種: 1. balance="0", 不開(kāi)啟讀寫(xiě)分離機(jī)制,所有讀操作都發(fā)送到當(dāng)前可用的 writeHost 上秽晚。 2. balance="1"瓦糟,全部的 readHost 與 stand by writeHost 參與 select 語(yǔ)句的負(fù)載均衡,簡(jiǎn)單的說(shuō)赴蝇,當(dāng)雙 主雙從模式(M1->S1菩浙,M2->S2,并且 M1 與 M2 互為主備)句伶,正常情況下劲蜻,M2,S1,S2 都參與 select 語(yǔ)句的負(fù)載 均衡。 3. balance="2"考余,所有讀操作都隨機(jī)的在 writeHost先嬉、 readhost 上分發(fā)。 4. balance="3"秃殉,所有讀請(qǐng)求隨機(jī)的分發(fā)到 wiriterHost 對(duì)應(yīng)的 readhost 執(zhí)行坝初,writerHost 不負(fù)擔(dān)讀壓 力浸剩,注意 balance=3 只在 1.4 及其以后版本有钾军,1.3 沒(méi)有鳄袍。
writeType Integer 負(fù)載均衡類(lèi)型,目前的取值有 3 種: 1. writeType="0", 所有寫(xiě)操作發(fā)送到配置的第一個(gè) writeHost吏恭,第一個(gè)掛了切到還生存的第二個(gè) writeHost拗小,重新啟動(dòng)后已切換后的為準(zhǔn),切換記錄在配置文件中:dnindex.properties . 2. writeType="1"樱哼,所有寫(xiě)操作都隨機(jī)的發(fā)送到配置的 writeHost哀九,1.5 以后廢棄不推薦。
dbType String 指定后端連接的數(shù)據(jù)庫(kù)類(lèi)型搅幅,目前支持二進(jìn)制的 mysql 協(xié)議阅束,還有其他使用 JDBC 連接的數(shù)據(jù)庫(kù)。例如: mongodb茄唐、 oracle息裸、 spark 等。
dbDriver String 指定連接后端數(shù)據(jù)庫(kù)使用的 Driver沪编,目前可選的值有 native 和 JDBC呼盆。使用 native 的話(huà),因?yàn)檫@個(gè)值執(zhí)行的 是二進(jìn)制的 mysql 協(xié)議蚁廓,所以可以使用 mysql 和 maridb访圃。其他類(lèi)型的數(shù)據(jù)庫(kù)則需要使用 JDBC 驅(qū)動(dòng)來(lái)支持。 從 1.6 版本開(kāi)始支持 postgresql 的 native 原始協(xié)議相嵌。 如果使用 JDBC 的話(huà)需要將符合 JDBC 4 標(biāo)準(zhǔn)的驅(qū)動(dòng) JAR 包放到 MYCAT\lib 目錄下腿时,并檢查驅(qū)動(dòng) JAR 包中 包括如下目錄結(jié)構(gòu)的文件:META-INF\services\java.sql.Driver。在這個(gè)文件內(nèi)寫(xiě)上具體的 Driver 類(lèi)名饭宾,例如: com.mysql.jdbc.Driver批糟。
switchType Integer -1 表示不自動(dòng)切換 1 默認(rèn)值,自動(dòng)切換 2 基于 MySQL 主從同步的狀態(tài)決定是否切換 心跳語(yǔ)句為 show slave status 3 基于 MySQL galary cluster 的切換機(jī)制(適合集群)(1.4.1) 心跳語(yǔ)句為 show status like ‘wsrep%’. 這個(gè)和writeType結(jié)合使用

heartbeat

  • 這個(gè)標(biāo)簽內(nèi)指明用于和后端數(shù)據(jù)庫(kù)進(jìn)行心跳檢查的語(yǔ)句捏雌。例如,MYSQL 可以使用select user()跃赚,Oracle 可以 使用 select 1 from dual等。 這個(gè)標(biāo)簽還有一個(gè) connectionInitSql屬性性湿,主要是當(dāng)使用 Oracla 數(shù)據(jù)庫(kù)時(shí)纬傲,需要執(zhí)行的初始化 SQL 語(yǔ)句就 這個(gè)放到這里面來(lái)。例如:alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss' 1.4 主從切換的語(yǔ)句必須是:show slave status

writeHost 肤频、 readHost

  • 這兩個(gè)標(biāo)簽都指定后端數(shù)據(jù)庫(kù)的相關(guān)配置給 mycat叹括,用于實(shí)例化后端連接池。唯一不同的是宵荒,writeHost 指 定寫(xiě)實(shí)例汁雷、 readHost 指定讀實(shí)例净嘀,組著這些讀寫(xiě)實(shí)例來(lái)滿(mǎn)足系統(tǒng)的要求
  • 在一個(gè) dataHost 內(nèi)可以定義多個(gè) writeHost 和 readHost。但是侠讯,如果 writeHost 指定的后端數(shù)據(jù)庫(kù)宕機(jī)挖藏, 那么這個(gè) writeHost 綁定的所有 readHost 都將不可用。另一方面厢漩,由于這個(gè) writeHost 宕機(jī)系統(tǒng)會(huì)自動(dòng)的檢測(cè) 到膜眠,并切換到備用的 writeHost 上去
  • 這兩個(gè)標(biāo)簽的屬性相同,這里就一起介紹溜嗜。
host String 用于標(biāo)識(shí)不同實(shí)例宵膨,一般 writeHost 我們使用M1,readHost 我們用S1炸宵。
url String 后端實(shí)例連接地址辟躏,如果是使用 native 的 dbDriver,則一般為 address:port 這種形式土全。用 JDBC 或其他的 dbDriver捎琐,則需要特殊指定。當(dāng)使用 JDBC 時(shí)則可以這么寫(xiě):jdbc:mysql://localhost:3306/涯曲。
password String 后端存儲(chǔ)實(shí)例需要的用戶(hù)名字 ,即是指向mysql的密碼
user String 后端存儲(chǔ)實(shí)例需要的密碼 野哭,即是指向mysql的用戶(hù)
weight String 權(quán)重 配置在 readhost 中作為讀節(jié)點(diǎn)的權(quán)重(1.4 以后)
usingDecrypt String 是否對(duì)密碼加密默認(rèn) 0 否 如需要開(kāi)啟配置 1,同時(shí)使用加密程序?qū)γ艽a加密

childTable

  • childTable 標(biāo)簽用于定義 E-R 分片的子表幻件。通過(guò)標(biāo)簽上的屬性與父表進(jìn)行關(guān)聯(lián)拨黔。
name String 定義子表的表名。
joinKey String 插入子表的時(shí)候會(huì)使用這個(gè)列的值查找父表存儲(chǔ)的數(shù)據(jù)節(jié)點(diǎn)
parentKey String 屬性指定的值一般為與父表建立關(guān)聯(lián)關(guān)系的列名绰沥。程序首先獲取 joinkey 的值篱蝇,再通過(guò) parentKey 屬性指定 的列名產(chǎn)生查詢(xún)語(yǔ)句,通過(guò)執(zhí)行該語(yǔ)句得到父表存儲(chǔ)在哪個(gè)分片上徽曲。從而確定子表存儲(chǔ)的位置零截。
primaryKey String 同 table 標(biāo)簽所描述的
needAddLimit boolean 同 table 標(biāo)簽所描述的
autoIncrement boolean 設(shè)置是否主鍵自增

server.xml中的標(biāo)簽

設(shè)置用戶(hù)

<!--
        user標(biāo)簽可以設(shè)置登錄的用戶(hù),可以指定多個(gè)
        
        <property name="password">: 設(shè)置該用戶(hù)登錄的密碼
        
        <property name="schemas"> :設(shè)置該用戶(hù)可以訪問(wèn)的邏輯庫(kù)秃臣,如果有多個(gè)涧衙,那么需要使用逗號(hào)分隔
        
        <property name="readOnly">true</property> : 設(shè)置該用戶(hù)是否對(duì)邏輯庫(kù)為只讀權(quán)限
        
        <property name="benchmark">11111</property>: mycat 連接服務(wù)降級(jí)處理:benchmark 基準(zhǔn), 當(dāng)前端的整體 connection 數(shù)達(dá)到基準(zhǔn)值是, 對(duì)來(lái)自該賬戶(hù)的請(qǐng)求開(kāi)始拒絕連接, 0 或不設(shè)
表示不限制
        
        <property name="usingDecrypt">1</property>:是否對(duì)密碼加密默認(rèn) 0 否 如需要開(kāi)啟配置 1奥此,同時(shí)使用加密程序?qū)γ艽a加密
        
        privileges 子節(jié)點(diǎn):對(duì)用戶(hù)的 schema 及 下級(jí)的 table 進(jìn)行精細(xì)化的 DML 權(quán)限控制弧哎,privileges 節(jié)點(diǎn)中的 check 屬性是用
于標(biāo)識(shí)是否開(kāi)啟 DML 權(quán)限檢查, 默認(rèn) false 標(biāo)識(shí)不檢查稚虎,當(dāng)然 privileges 節(jié)點(diǎn)不配置撤嫩,等同 check=false,
由于 Mycat 一個(gè)用戶(hù)的 schemas 屬性可配置多個(gè) schema ,所以 privileges 的下級(jí)節(jié)點(diǎn) schema 節(jié)點(diǎn)同樣
可配置多個(gè)蠢终,對(duì)多庫(kù)多表進(jìn)行細(xì)粒度的 DML 權(quán)限控制

                schema 標(biāo)簽: 指定邏輯庫(kù)的名稱(chēng)序攘,用來(lái)選擇對(duì)應(yīng)的表茴她,可以有多個(gè)

                        dml:設(shè)置對(duì)指定表的crud操作,分別是insert,update,select,delete程奠,對(duì)應(yīng)的如果是0表示禁止丈牢,1表示不禁止
        
        
        
    -->
    <user name="root">
        <property name="password">123456</property>
        <property name="schemas">Test</property>
        
        <!-- 表級(jí) DML 權(quán)限設(shè)置 -->
        <!--        
        <privileges check="false">
            <schema name="TESTDB" dml="0110" >
                <table name="tb01" dml="0000"></table>
                <table name="tb02" dml="1111"></table>
            </schema>
            
            <schema name="TESTDB" dml="0110" >
                <table name="tb01" dml="0000"></table>
                <table name="tb02" dml="1111"></table>
            </schema>
            
        </privileges>       
         -->
    </user>

system標(biāo)簽

  • 這個(gè)標(biāo)簽內(nèi)嵌套的所有 property 標(biāo)簽都與系統(tǒng)配置有關(guān),請(qǐng)注意梦染,下面我會(huì)省去標(biāo)簽 property 直接使用這 個(gè)標(biāo)簽的 name 屬性?xún)?nèi)的值來(lái)介紹這個(gè)屬性的作用赡麦。
屬性 作用 概要
charset 字符集設(shè)置朴皆。 配置字符集的時(shí)候一定要堅(jiān)持 mycat 的字符集與數(shù)據(jù)庫(kù)端的字符集是一致的帕识,可以通過(guò)變量來(lái)查詢(xún)。比如<property name="charset">utf8</property>
defaultSqlParser 1.3 解析器默認(rèn)為 fdbparser遂铡,1.4 默認(rèn)為 druidparser肮疗,1.4 以后 fdbparser 作廢。 由于 mycat 最初是時(shí)候 Foundation DB 的 sql 解析器扒接,而后才添加的 Druid 的解析器伪货。所以這個(gè)屬性用來(lái) 指定默認(rèn)的解析器。目前的可用的取值有:druidparser 和 fdbparser钾怔。使用的時(shí)候可以選擇其中的一種碱呼,目前一 般都使用 druidparser
processors 這個(gè)屬性主要用于指定系統(tǒng)可用的線(xiàn)程數(shù),默認(rèn)值為機(jī)器 CPU 核心線(xiàn)程數(shù)宗侦。 主要影響 processorBufferPool愚臀、 processorBufferLocalPercent、 processorExecutor 屬性矾利。 NIOProcessor 的個(gè)數(shù)也是由這個(gè)屬性定義的姑裂,所以調(diào)優(yōu)的時(shí)候可以適當(dāng)?shù)恼{(diào)高這個(gè)屬性。
processorBufferChunk 這個(gè)屬性指定每次分配 Socket Direct Buffer 的大小男旗,默認(rèn)是 4096 個(gè)字節(jié)舶斧。這個(gè)屬性也影響 buffer pool 的 長(zhǎng)度。如果一次性獲取的數(shù)過(guò)大 buffer 不夠用 經(jīng)常出現(xiàn)警告察皇,則可以適當(dāng)調(diào)大茴厉。
processorBufferPool 這個(gè)屬性指定 bufferPool 計(jì)算 比例值。由于每次執(zhí)行 NIO 讀什荣、寫(xiě)操作都需要使用到 buffer矾缓,系統(tǒng)初始化的 時(shí)候會(huì)建立一定長(zhǎng)度的 buffer 池來(lái)加快讀、寫(xiě)的效率溃睹,減少建立 buffer 的時(shí)間而账。 Mycat 中有兩個(gè)主要的 buffer 池: - BufferPool - ThreadLocalPool BufferPool 由 ThreadLocalPool 組合而成,每次從 BufferPool 中獲取 buffer 都會(huì)優(yōu)先獲取 ThreadLocalPool 中的 buffer因篇,未命中之后才會(huì)去獲取 BufferPool 中的 buffer泞辐。也就是說(shuō) ThreadLocalPool 是 作為 BufferPool 的二級(jí)緩存笔横,每個(gè)線(xiàn)程內(nèi)部自己使用的。當(dāng)然咐吼,這其中還有一些限制條件需要線(xiàn)程的名字是由$_ 開(kāi)頭吹缔。然而,BufferPool 上的 buffer 則是每個(gè) NIOProcessor 都共享的锯茄。 默認(rèn)這個(gè)屬性的值為: 默認(rèn) bufferChunkSize(4096) * processors 屬性 * 1000 BufferPool 的總長(zhǎng)度 = bufferPool / bufferChunk厢塘。 若 bufferPool 不是 bufferChunk 的整數(shù)倍,則總長(zhǎng)度為前面計(jì)算得出的商 + 1 假設(shè)系統(tǒng)線(xiàn)程數(shù)為 4肌幽,其他都為屬性的默認(rèn)值晚碾,則: bufferPool = 4096 * 4 * 1000 BufferPool 的總長(zhǎng)度 : 4000 = 16384000 / 4096
processorBufferLocalPercent 前面提到了 ThreadLocalPool。這個(gè)屬性就是用來(lái)控制分配這個(gè) pool 的大小用的喂急,但其也并不是一個(gè)準(zhǔn)確 的值格嘁,也是一個(gè)比例值。這個(gè)屬性默認(rèn)值為 100廊移。 線(xiàn)程緩存百分比 = bufferLocalPercent / processors 屬性糕簿。 例如梗劫,系統(tǒng)可以同時(shí)運(yùn)行 4 個(gè)線(xiàn)程讯沈,使用默認(rèn)值脐供,則根據(jù)公式每個(gè)線(xiàn)程的百分比為 25趣兄。最后根據(jù)這個(gè)百分比 來(lái)計(jì)算出具體的 ThreadLocalPool 的長(zhǎng)度公式如下: ThreadLocalPool 的長(zhǎng)度 = 線(xiàn)程緩存百分比 * BufferPool 長(zhǎng)度 / 100 假設(shè) BufferPool 的長(zhǎng)度為 4000择示,其他保持默認(rèn)值标捺。 那么最后每個(gè)線(xiàn)程建立上的 ThreadLocalPool 的長(zhǎng)度為: 1000 = 25 * 4000 / 100
processorExecutor 這個(gè)屬性主要用于指定 NIOProcessor 上共享的 businessExecutor 固定線(xiàn)程池大小模蜡。 mycat 在需要處理一 些異步邏輯的時(shí)候會(huì)把任務(wù)提交到這個(gè)線(xiàn)程池中嘉蕾。新版本中這個(gè)連接池的使用頻率不是很大了荚醒,可以設(shè)置一個(gè)較 小的值
sequnceHandlerType 指定使用 Mycat 全局序列的類(lèi)型芋类。 0 為本地文件方式,1 為數(shù)據(jù)庫(kù)方式界阁,2 為時(shí)間戳序列方式侯繁,3 為分布式 ZK ID 生成器,4 為 zk 遞增 id 生成泡躯。
handleDistributedTransactions 分布式事務(wù)開(kāi)關(guān)贮竟,0為不過(guò)濾分布式事務(wù),1為過(guò)濾分布式事務(wù)(如果分布式事務(wù)內(nèi)只涉及全局表较剃,則不過(guò)濾)咕别,2為不過(guò)濾分布式事務(wù),但是記錄分布式事務(wù)日志

全局表

  • mycat中使用type定義全局表和普通表(type=global),沒(méi)有定義type的類(lèi)型的都是普通表写穴,是需要分片的
  • 全局表適合那些數(shù)據(jù)量比較少的惰拱,變動(dòng)不是很頻繁的
  • 全局表的插入,更新操作會(huì)實(shí)時(shí)在所有節(jié)點(diǎn)上執(zhí)行啊送,保持各個(gè)分片的數(shù)據(jù)一致性偿短。沒(méi)有太激烈的update操作欣孤。
  • 全局表查詢(xún)只從一個(gè)節(jié)點(diǎn)獲取
  • 全局表可以和任何一個(gè)表進(jìn)行JOIN操作
  • 需要注意的是,全局表每個(gè)分片節(jié)點(diǎn)上都要有運(yùn)行創(chuàng)建表的 DDL 語(yǔ)句昔逗。

Mycat的跨分片join

  • 同一個(gè)分片的數(shù)據(jù)可以任意的join降传,join的數(shù)量也沒(méi)有限制,但是不同分片的數(shù)據(jù)跨分片join的話(huà)勾怒,是查詢(xún)不到結(jié)果的

全局表

  • 全局表在每一個(gè)分片上都保持著相同的數(shù)據(jù)婆排,因此全局表可以和任意的表跨分片join

ER join

  • 我們可以根據(jù)ER關(guān)系設(shè)置每張表的關(guān)系,比如訂單表依賴(lài)于用戶(hù)表笔链,我們可以設(shè)置ER join方式的段只,那么會(huì)根據(jù)外鍵(joinKey)的值和相關(guān)依賴(lài)的表分配在同一個(gè)分片上,那么就可以join了
  • 支持多表join
  • 配置如下(其中childTable中也可以嵌套childTable):
<table name="t_user" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" primaryKey="id" autoIncrement="true">
            <!--訂單表卡乾,
            joinKey是t_order和t_user關(guān)聯(lián)的外鍵關(guān)系翼悴,
            parentKey指定的是t_user表中的主鍵
            primaryKey:指定的是t_order的主鍵
            autoIncrement:設(shè)置是否主鍵自增
-->
            <childTable name="t_order" joinKey="user_id" parentKey="id" primaryKey="id" autoIncrement="true"/>
</table>

Share Join

mycat自增主鍵的配置(數(shù)據(jù)庫(kù)方式)

  • 在mycat中并沒(méi)有實(shí)現(xiàn)mysql的自增主鍵的配置,如果需要實(shí)現(xiàn)的話(huà)幔妨,需要自己配置。
  • 自增主鍵的方式配置有多種方式谍椅,比如本地方式误堡,數(shù)據(jù)庫(kù)方式,ZK方式雏吭,時(shí)間戳的方式锁施,這里我們測(cè)試的是數(shù)據(jù)庫(kù)的方式。

測(cè)試步驟

1杖们、修改server.xml中生成方式為數(shù)據(jù)庫(kù)生成的方式

<!--將sequnceHandlerType設(shè)置為1-->
<property name="sequnceHandlerType">1</property>

2悉抵、在schema.xml中,table中增加屬性autoIncrement值為true摘完,添加mycat_sequence

<schema name="Test" checkSQLschema="true">
        <!-- auto sharding by id (long)
        rule:指定分片的規(guī)則為根據(jù)Id自動(dòng)分片
        primaryKey: 指定主鍵
        autoIncrement: 指定自增長(zhǎng)姥饰,一定要為true
        -->
        <table name="t_item" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" primaryKey="id" autoIncrement="true"  />
        <!--指定自增長(zhǎng)的表,數(shù)據(jù)節(jié)點(diǎn)為dn1-->
        <table name="mycat_sequence" primaryKey="name" dataNode="dn1" />
        
    </schema>
    <dataNode name="dn1" dataHost="localhost1" database="db1" />
    <dataNode name="dn2" dataHost="localhost1" database="db2" />
    <dataNode name="dn3" dataHost="localhost1" database="db3" />

3孝治、在數(shù)據(jù)節(jié)點(diǎn)dn1的數(shù)據(jù)庫(kù)db1中新建mycat_sequence的表列粪,如下:

1、name:sequence:名稱(chēng)

2谈飒、currenct_value:當(dāng)前value

3岂座、increment:增長(zhǎng)步長(zhǎng) 
DROP TABLE IF EXISTS MYCAT_SEQUENCE;   
CREATE TABLE MYCAT_SEQUENCE(   
    name VARCHAR(50) NOT NULL,  
    current_value INT NOT NULL,  
    increment INT NOT NULL DEFAULT 100,  
    PRIMARY KEY(name)  
) ENGINE=InnoDB;

4、在db1數(shù)據(jù)中創(chuàng)建存儲(chǔ)函數(shù)杭措,用來(lái)維持自增長(zhǎng)

-- 獲取當(dāng)前sequence的值 (返回當(dāng)前值,增量)  
DROP FUNCTION IF EXISTS mycat_seq_currval;  
DELIMITER $  
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 $  
DELIMITER ;  
      
-- 設(shè)置sequence值  
DROP FUNCTION IF EXISTS mycat_seq_setval;  
DELIMITER $  
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 $  
DELIMITER ;  
    
-- 獲取下一個(gè)sequence值  
DROP FUNCTION IF EXISTS mycat_seq_nextval;  
DELIMITER $  
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 $  
DELIMITER ;

5费什、在mycat_sequence表中插入數(shù)據(jù),用來(lái)記錄t_item表的自增長(zhǎng)數(shù)據(jù)手素,名稱(chēng)必須全部大寫(xiě)

? 1鸳址、當(dāng)然這里一條數(shù)據(jù)就代表一張表自增長(zhǎng)赘那,如果想要其他的表也能自增長(zhǎng),那么直接添加即可

INSERT INTO MYCAT_SEQUENCE(name, current_value, increment) VALUES ('T_TIEM', 0,1);

6氯质、在conf/sequence_db_conf.properties的文件中添加依賴(lài)全局序列募舟,增加序列,與table名稱(chēng)相同全大寫(xiě)

# T_ITEM是自增長(zhǎng)的表闻察,dn1是mycat_sequence所在的數(shù)據(jù)節(jié)點(diǎn)拱礁,之后每添加一張自增長(zhǎng)的表,只需要在其中添加即可
T_ITEM=dn1

7辕漂、測(cè)試呢灶,向t_item表中添加數(shù)據(jù)

INSERT INTO t_item(name) values("chenjiabing");

8、測(cè)試使用mybatis添加數(shù)據(jù)

    @Insert("INSERT into t_item(name) values(#{name})")
    @Options(useGeneratedKeys = true,keyProperty = "id")   //自增長(zhǎng)主鍵返回
    void insert(Item item);     

參考文章

Java操作Mycat

  • 只需要將連接mysql的端口改成8066即可钉嘹,其他的就像是操作mysql一樣

Mycat的事務(wù)處理

  • Mycat 目前沒(méi)有出來(lái)跨分片的事務(wù)強(qiáng)一致性支持鸯乃,目前單庫(kù)內(nèi)部可以保證事務(wù)的完整性,如果跨庫(kù)事務(wù)跋涣, 在執(zhí)行的時(shí)候任何分片出錯(cuò)缨睡,可以保證所有分片回滾,但是一旦應(yīng)用發(fā)起 commit 指令陈辱,無(wú)法保證所有分片都成 功奖年,考慮到某個(gè)分片掛的可能性不大所以稱(chēng)為弱 XA。
  • 也就是說(shuō)沛贪,我們?cè)趩误w應(yīng)用中可以正常使用spring提供的事務(wù)管理器進(jìn)行事務(wù)的管理陋守,在處理出現(xiàn)異常的時(shí)候也是可以回滾的。

Mycat查詢(xún)

非分片字段查詢(xún)

  • 如果查詢(xún)條件中有分片字段的話(huà)利赋,那么mycat就可以輕松的根據(jù)分片規(guī)則找到對(duì)應(yīng)的數(shù)據(jù)節(jié)點(diǎn)水评,然后在對(duì)應(yīng)節(jié)點(diǎn)中查詢(xún),比如使用的是id取模分片規(guī)則媚送,那么此時(shí)的id就是分片字段中燥,一旦查詢(xún)條件中有id這個(gè)字段的,就可以根據(jù)id的值定位到指定的節(jié)點(diǎn)中查詢(xún)季希,否則將會(huì)在每個(gè)節(jié)點(diǎn)中執(zhí)行sql語(yǔ)句褪那,然后將每個(gè)節(jié)點(diǎn)的返回結(jié)果匯總返回

分頁(yè)查詢(xún)

  • mycat針對(duì)分頁(yè)查詢(xún)的執(zhí)行邏輯如下:
    • 根據(jù)sql語(yǔ)句的過(guò)濾條件到每個(gè)數(shù)據(jù)節(jié)點(diǎn)篩選數(shù)據(jù),篩選完成之后返回各個(gè)節(jié)點(diǎn)的分頁(yè)數(shù)據(jù)
    • mycat會(huì)判斷哪個(gè)節(jié)點(diǎn)先返回?cái)?shù)據(jù)式塌,真正返回給客戶(hù)端的就是先返回?cái)?shù)據(jù)的那個(gè)節(jié)點(diǎn)上的數(shù)據(jù)庫(kù)中
  • 根據(jù)上面的分析博敬,我們可以判斷分頁(yè)查詢(xún)的數(shù)據(jù)每次都是不同的,不同數(shù)據(jù)節(jié)點(diǎn)的返回速度決定著分頁(yè)查詢(xún)的數(shù)據(jù)顯示峰尝。
  • 解決辦法:在分頁(yè)查詢(xún)的時(shí)候必要的時(shí)候進(jìn)行排序偏窝,這樣返回的結(jié)果才是正確的,不然每次返回的結(jié)果可能不同,比如select * from t_item order by id desc limit 1,29

排序查詢(xún)

  • mycat 的排序查詢(xún)的執(zhí)行邏輯如下:
    • 將sql語(yǔ)句發(fā)送到各個(gè)節(jié)點(diǎn)進(jìn)行篩選數(shù)據(jù)祭往,返回?cái)?shù)據(jù)給mycat
    • mycat獲取到各個(gè)節(jié)點(diǎn)的數(shù)據(jù)的時(shí)候會(huì)根據(jù) 不同的排序規(guī)則(升序伦意,降序)對(duì)全部節(jié)點(diǎn)的數(shù)據(jù)重新排序,最后所有數(shù)據(jù)排序完成的結(jié)果就是正確的結(jié)果

分頁(yè)排序查詢(xún)

參考文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末硼补,一起剝皮案震驚了整個(gè)濱河市驮肉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌已骇,老刑警劉巖离钝,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異褪储,居然都是意外死亡卵渴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)鲤竹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浪读,“玉大人,你說(shuō)我怎么就攤上這事辛藻〉忾伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵揩尸,是天一觀的道長(zhǎng)蛹屿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)岩榆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任坟瓢,我火速辦了婚禮勇边,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘折联。我一直安慰自己粒褒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布诚镰。 她就那樣靜靜地躺著奕坟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪清笨。 梳的紋絲不亂的頭發(fā)上月杉,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音抠艾,去河邊找鬼苛萎。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腌歉。 我是一名探鬼主播蛙酪,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翘盖!你這毒婦竟也來(lái)了桂塞?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤馍驯,失蹤者是張志新(化名)和其女友劉穎阁危,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體泥彤,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡欲芹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吟吝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菱父。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剑逃,靈堂內(nèi)的尸體忽然破棺而出浙宜,到底是詐尸還是另有隱情,我是刑警寧澤蛹磺,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布粟瞬,位于F島的核電站,受9級(jí)特大地震影響萤捆,放射性物質(zhì)發(fā)生泄漏裙品。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一俗或、第九天 我趴在偏房一處隱蔽的房頂上張望市怎。 院中可真熱鬧,春花似錦辛慰、人聲如沸区匠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驰弄。三九已至,卻和暖如春速客,著一層夾襖步出監(jiān)牢的瞬間戚篙,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工挽封, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留已球,地道東北人臣镣。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像智亮,于是被迫代替她去往敵國(guó)和親忆某。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容