一、為什麼需要分布式資料據庫
随着計算機和資訊技術的迅猛發展,行業應用系統的規模迅速擴大,行業應用所産生的資料量呈爆炸式增長,動辄達到數百TB甚至數百PB的規模,已遠遠超出傳統計算技術和資訊系統的處理能力,集中式資料庫面對大規模資料處理逐漸表現出其局限性。是以,人們希望尋找一種能快速處理資料和及時響應使用者通路的方法,也希望對資料進行集中分析、管理和維護。這已經成為迫切需求。
分布式資料庫是在集中式資料庫的基礎上發展起來的,是計算機技術和網絡技術結合的産物。分布式資料庫是指資料在實體上分布而在邏輯上集中管理的資料庫系統。實體上分布是指資料分布在實體位置不同并由網絡連接配接的節點或站點上;邏輯上集中是指各資料庫節點之間的邏輯上是一個整體,并由統一的資料庫管理系統管理。不同的節點分布可以跨不同的機房、城市甚至國家。
二、分布式資料庫的特點
分布式資料庫具有透明性、資料備援性、易于擴充性、自治性等特點,還具有經濟、性能優越、響應速度更快、靈活的體系結構、易于內建現有系統等特點。
分布式資料庫盡管有着天生的高貴血統,但它依賴調整網絡,對事務的處理遠沒有傳統資料庫成熟,在很長一段時間内分布式資料存儲将與傳統資料存儲共存。
三、MyCat資料庫中間件簡介
MyCat是一個徹底開源的面向企業應用開發的大資料庫叢集,支援事務、ACID,是可以替代MySQL的加強版資料庫。MyCat被視為MySQL叢集的企業級資料庫,用來替代昂貴的Oracle叢集,它是整合了記憶體緩存技術、NoSQL技術、HDFS大資料的新型SQL Server,是結合了傳統資料庫和新型分布式資料倉庫的新一代企業級資料庫産品,也是一個優秀的資料庫中間件。
MyCat是通過Cobar改良而生。MyCat支援Oracle、PostgreSQL,從1.3版本開始支援NoSQL(SequoiaDB及MongoDB)并引入了Druid解析器。2016年MyCat釋出了1.5版本,2018年釋出了 1.6.6版本 。目前MyCat2.0項目已經啟動,核心代碼已經送出(
https://github.com/MyCatApache/MyCat2.git)。
四、MyCat核心概念詳解
4.1 邏輯庫(schema)
通常在實際應用中,業務開發人員并不需要知道中間件的存在,隻需要關注資料庫,是以資料庫中間件可以被當作一個或多個資料庫叢集構成的邏輯庫。
4.2 邏輯表(table)
既然有邏輯庫,就會有邏輯表。在分布式資料庫中,對于應用來說,讀寫資料的表就是邏輯表。邏輯表可以分布在一個或多個分片庫中,也可以不分片。
1)分片表分片表是指将資料量很大的表切分到多個資料庫執行個體中,所有分片組合起來構成了一張完整的表。例如在MyCat上配置t_node的分片表,資料按照規則被切分到dn1、dn2兩個節點。
<table name=”t_node” primaryKey=”vid” autoIncrement=”true” dataNode=”nd1,dn2” rule=”rule1” />
2)非分片表 并非所有的表在數量很大時都需要進行分片。非分片表是相對分片表而言的,不需要進行資料切分的表。如下面配置中的t_node隻存在于節點dn1上。
<table name=”t_node” primaryKey=”vid” autoIncrement=”true” dataNode=”nd1,dn2” rule=”rule1” />
3)ER表 關系型資料庫是基于實體關系模型(Entity Relationship Model)的,MyCat中的ER表便來源于此。基于此思想,MyCat提出了基于E-R關系的資料分片政策,子表的記錄與其所關聯的父表的記錄存放在同一個資料分片上,即子表依賴于父表,通過表分組(Table Group)保證資料關聯查詢不會跨庫操作。
表分組是解決跨分片資料關聯查詢的一種很好的思路,也是資料切分的一條重要規則。
4)全局表在一個真實的業務場景中往往存在大量類似的字典表,這些字典表中的資料變動不頻繁,而且資料規模不大,很少有超過數十萬條的記錄。
當業務表因為規模進行分片後,業務表與這些附屬的字典表之間的關聯查詢就成了比較棘手的問題,是以在MyCat中通過資料備援來解決這類表的關聯查詢,即所有分片都複制了一份資料,我們把這些備援資料的表定義為全局表。
資料備援是解決跨分片資料關聯查詢的一種很好的思路,也是資料切分規劃的另一條重要規則。
4.3 分片節點(dataNode)
将資料切分後,一個大表被分到不同的分片資料庫上,每個表分片所在的資料庫是分片節點。
4.4 節點主機(dataHost)
将資料切分後,每個分片節點不一定會獨占一台機器,同一台機器上可以有多個分片資料庫,這樣一個或多個分片節點所在的機器就是節點主機。為了規避單節點主機并發數量的限制,盡量将讀寫壓力高的分片節點均勻地放在不同的節點主機上。
五、MyCat原理介紹
MyCat原理中最重要的一個動詞是“攔截”,它攔截了使用者發送過來的SQL語句,首先對SQL語句做了一些特定的分析,例如分片分析、路由分析、讀寫分離分析、緩存分析等,然後将此SQL語句發往後端的真實資料庫,并将傳回的結果做适當的處理,最終再傳回給使用者。
MyCat收到一條SQL語句時,首先解析SQL語句涉及的表,接着檢視此表的定義,如果該表存在分片規則,則擷取SQL語句裡分片字段的值,并比對分片函數,得到該SQL語句對應的分片清單,然後将SQL語句發送到相應的分片去執行,最後處理所有分片傳回的資料并傳回給用戶端。
六、MyCat配置
schema.xml是MyCat的重要配置檔案,它管理着邏輯庫、分片表、分片節點和分片主機等資訊。
service.xml是系統參數的配置檔案,掌握MyCat優化方法,必需熟悉該檔案的配置項。
sequence是全局序列的配置檔案。
6.1 server.xml配置檔案
server.xml配置檔案包含了MyCat的系統配置資訊,對應的源碼是SystemConfig.java。它有兩個重要的标簽,分别是user、system。掌握system标簽的各項配置屬性是MyCat調優的關鍵。
<MyCat:server xmlns:MyCat=" http://io.MyCat/">
<system>
<property name="nonePasswordLogin">0</property> <!-- 0為需要密碼登陸、1為不需要密碼登陸 ,預設為0,設定為1則需要指定預設賬戶-->
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property> <!-- 1為開啟實時統計、0為關閉 -->
<property name="useGlobleTableCheck">0</property> <!-- 1為開啟全加班一緻性檢測、0為關閉 -->
<property name="sequnceHandlerType">2</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查詢中存在關聯查詢的情況下,檢查關聯字段中是否有分片字段 .預設 false -->
<!-- <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 | type 2 NettyBufferPool -->
<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">64k</property>
<!--
機關為k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
機關為m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper協調切換 -->
<property name="useZKSwitch">false</property>
<!-- XA Recovery Log日志路徑 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->
<!-- XA Recovery Log日志名稱 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
<!--如果為 true的話 嚴格遵守隔離級别,不會在僅僅隻有select語句的時候在事務中切換連接配接-->
<property name="strictTxIsolation">false</property>
<property name="useZKSwitch">true</property>
</system>
<!-- 全局SQL防火牆設定 -->
<!--白名單可以使用通配符%或着*-->
<!--例如<host host="127.0.0.*" user="root"/>-->
<!--例如<host host="127.0.*" user="root"/>-->
<!--例如<host host="127.*" user="root"/>-->
<!--例如<host host="1*7.*" user="root"/>-->
<!--這些配置情況下對于127.0.0.1都能以root賬戶登入-->
<!--
<firewall>
<whitehost>
<host host="1*7.0.0.*" user="root"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</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="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
</MyCat:server>
6.2 schema.xml配置檔案
schema.xml 作為MyCat中重要的配置檔案之一,涵蓋了MyCat的邏輯庫、表、分片規則、分片節點及資料源。
1)schema 标簽<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
schema标簽用于定義MyCat執行個體中的邏輯庫。MyCat可以有多個邏輯庫,每個邏輯庫都有自己的相關配置。可以使用schema标簽來劃分不同的邏輯庫,如果有配置schema标簽,則所有的表配置都會屬于同一個預設的邏輯庫。
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
<schema name="USERDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="company" dataNode="dn10,dn11,dn12" rule="auto-sharding-long" />
</schema>
如上所示配置了兩個不同的邏輯庫,邏輯庫的概念等同于MySQL資料庫中的Database概念,我們在查詢邏輯庫中的表時,需要切換到該邏輯庫下才可以查詢其中的表。
checkSQLschema屬性,當把該值設定為true時,如果我們執行語句 select from TESTDB.travelrecord;,則MyCat會把schema字元去掉,把SQL語句修改為select from travelrecord;可避免發送到後端資料庫執行時報錯。
SqlMaxLimit屬性,當該屬性設定為某個值時,每次執行的SQL語句如果沒有加上limit語句,MyCat也會自動在limit語句後加上對應的值。如果不設定該值,則MyCat會把查詢到的資訊全部傳回。
2)table 标簽<table name=”travelrecord” dataNode=”dn1,dn2,dn3” rule=”auto-sharding-long”></table>
table标簽定義了MyCat中的邏輯表,所有需要拆分的的表都需要在table标簽中定義。
table标簽的主要屬性見下表,具體介紹參見MyCat官方網站
http://www.MyCat.io屬性名 | 值 | 數量限制 |
---|---|---|
name | String | 1 |
dataNode | 1..* | |
rule | 0..1 | |
ruleRequired | boolean | |
primaryKey | ||
type | ||
autoIncrement | ||
subTables | ||
needAddLimit | Boolean |
childTable标簽用于定義 E-R 分片的子表,通過标簽上的屬性與父表進行關聯。
4)dataNode标簽dataNode标簽定義了MyCat中的資料節點,也就是我們通常所說的資料分片。一個dataNode标簽就是一個獨立的資料分片。
5)dataHost标簽dataHost标簽在MyCat邏輯庫中作為底層标簽存在,直接定義了具體的資料庫執行個體,讀寫分離和心跳語句。
Heartbeat标簽用來配置心跳檢查語句,Mysql可以使用select user(),Oracle可以使用select 1 from dual 等。
writeHost和readHost是讀寫的配置,一個dataHost内可以配置多個讀和寫。但如果writeHost指定的後端資料庫當機,那麼這個writeHost綁定的所有readHost也将不可用;另一方面,MyCat會自動檢測到writeHost當機,并切換到備用的writeHost上。
七、MyCat分片
在MyCat中将表分為兩種大的概念:資料量小且不需要做資料切分的表,稱為非分片表;資料量大到單庫性能、容量不足以支撐,資料需要通過水準切分均勻分布到不同的資料庫中的表,稱為分片表。而中間件最終需要處理的事情是對資料切分、聚合。
7.1 ER關系分片表
ER模型是實體關系模型,廣泛采用概念模型設計方法,基本元素是實體、關系和屬性。MyCat将它引入資料切分規則中,使得有互相依賴的表能夠按照某一規則切分到相同的節點上,避免跨庫Join關聯查詢。具體詳情配置内容在這裡不做描述請參考官方文檔。
八、功能與優勢
8.1 常用指令
- MyCat提供類似資料管理監控方式,可以通過MySQL指令行登入管理端口(9066)執行相應的SQL語句進行管理,也可以通過JDBC方式進行遠端連接配接管理。
- Reload @@config指令用于更新配置檔案運作該指令,不用重新開機即可進行配置檔案更新。
- Reload @@sqlstat用來關閉和開啟SQL監控分析。
- Show @@database指令用來顯示MyCat資料庫清單,運作結果對應schema.xml配置檔案的schema子節點。
- Show @@datanode用來顯示MyCat資料節點,運作結果對應schema.xml配置檔案的dataNode節點。
- Show @@heartbeat用于報告心跳狀态。
- Show @@connection用來擷取MyCat的前端連接配接狀态。
- Kill @@connection id,id,id 用來關閉連接配接。
- Show @@ cache用來檢視緩存。
- Show @@datasource 用來檢視資料源狀态,如果配置了主從或多主,則可以切換。
- Switch @@ datasource name:index 用于切換資料源。
- Show @@syslog limit 用于顯示系統日志。
- Show @@sql 顯示在MyCat中執行過的語句。
- Show @@shl.show 顯示慢SQL語句。
- Show @@sql.sum 顯示SQL語句的整體執行情況、讀寫比例等。
8.2 局限性
delete操作不支援沒有主鍵的表。沒有主鍵的表在不同節點的順序不同,如果執行 select ...limit...,則将出現不同的結果集。
不支援XA事務,在送出上可能復原。
由于叢集是樂觀的并發控件,事務commit可能在該階段中止,是以如果有兩個事務向叢集中的不同節點的同一行寫入并送出,則失敗的節點将中止。對于叢集級别的中止,叢集傳回死鎖錯誤。
整個叢集的寫入吞吐量由最弱的節點限制,如果有一個節點變得緩慢,那麼整個叢集将變得緩慢。
叢集内部按照id自增長機制寫入資料,比如叢集中有三台可能是3,6,9這樣的遞增。
8.3 與Sharding-JDBC對比Sharding-JDBC
MyCat是一個中間件的第三方應用,sharding-jdbc是一個jar包。
因為MyCat是單獨部署,是以使用MyCat就像是通路資料庫一樣,而sharding-jdbc的邏輯都是需要在工程裡寫的。
如果隻是單獨應用可以使用輕量級的Sharding-JDBC,如果多個服務都需要操作資料庫則使用MyCat更合适。因為用Sharding-JDBC需要在每一個工程裡邊都配置上相應的分片等邏輯,而MyCat隻需要配置一份單獨部署。
雲伺服器ECS位址:阿裡雲·雲小站