隨着計算機和信息技術的迅猛發展,行業應用系統的規模迅速擴大,行業應用所產生的數據量呈爆炸式增加,動輒達到數百TB甚至數百PB的規模,已遠遠超出傳統計算技術和信息系統的處理能力,集中式數據庫面對大規模數據處理逐漸表現出其侷限性。所以,人們但願尋找一種能快速處理數據和及時響應用戶訪問的方法,也但願對數據進行集中分析、管理和維護。這已經成爲迫切需求。前端
分佈式數據庫是在集中式數據庫的基礎上發展起來的,是計算機技術和網絡技術結合的產物。分佈式數據庫是指數據在物理上分佈而在邏輯上集中管理的數據庫系統。物理上分佈是指數據分佈在物理位置不一樣並由網絡鏈接的節點或站點上;邏輯上集中是指各數據庫節點之間的邏輯上是一個總體,並由統一的數據庫管理系統管理。不一樣的節點分佈能夠跨不一樣的機房、城市甚至國家。java
分佈式數據庫具備透明性、數據冗餘性、易於擴展性、自治性等特色,還具備經濟、性能優越、響應速度更快、靈活的體系結構、易於集成現有系統等特色。node
分佈式數據庫儘管有着天生的高貴血統,但它依賴調整網絡,對事務的處理遠沒有傳統數據庫成熟,在很長一段時間內分佈式數據存儲將與傳統數據存儲共存。mysql
MyCat是一個完全開源的面向企業應用開發的大數據庫集羣,支持事務、ACID,是能夠替代MySQL的增強版數據庫。MyCat被視爲MySQL集羣的企業級數據庫,用來替代昂貴的Oracle集羣,它是整合了內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server,是結合了傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品,也是一個優秀的數據庫中間件。git
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)。github
一般在實際應用中,業務開發人員並不須要知道中間件的存在,只須要關注數據庫,因此數據庫中間件能夠被看成一個或多個數據庫集羣構成的邏輯庫。sql
既然有邏輯庫,就會有邏輯表。在分佈式數據庫中,對於應用來講,讀寫數據的表就是邏輯表。邏輯表能夠分佈在一個或多個分片庫中,也能夠不分片。數據庫
1)分片表後端
分片表是指將數據量很大的表切分到多個數據庫實例中,全部分片組合起來構成了一張完整的表。例如在MyCat上配置t_node的分片表,數據按照規則被切分到dn一、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=」dn1」 />
3)ER表
關係型數據庫是基於實體關係模型(Entity Relationship Model)的,MyCat中的ER表便來源於此。基於此思想,MyCat提出了基於E-R關係的數據分片策略,子表的記錄與其所關聯的父表的記錄存放在同一個數據分片上,即子表依賴於父表,經過表分組(Table Group)保證數據關聯查詢不會跨庫操做。
表分組是解決跨分片數據關聯查詢的一種很好的思路,也是數據切分的一條重要規則。
4)全局表
在一個真實的業務場景中每每存在大量相似的字典表,這些字典表中的數據變更不頻繁,並且數據規模不大,不多有超過數十萬條的記錄。
當業務表由於規模進行分片後,業務表與這些附屬的字典表之間的關聯查詢就成了比較棘手的問題,因此在MyCat中經過數據冗餘來解決這類表的關聯查詢,即全部分片都複製了一份數據,咱們把這些冗餘數據的表定義爲全局表。
數據冗餘是解決跨分片數據關聯查詢的一種很好的思路,也是數據切分規劃的另外一條重要規則。
將數據切分後,一個大表被分到不一樣的分片數據庫上,每一個表分片所在的數據庫是分片節點。
將數據切分後,每一個分片節點不必定會獨佔一臺機器,同一臺機器上能夠有多個分片數據庫,這樣一個或多個分片節點所在的機器就是節點主機。爲了規避單節點主機併發數量的限制,儘可能將讀寫壓力高的分片節點均勻地放在不一樣的節點主機上。
MyCat原理中最重要的一個動詞是「攔截」,它攔截了用戶發送過來的SQL語句,首先對SQL語句作了一些特定的分析,例如分片分析、路由分析、讀寫分離分析、緩存分析等,而後將此SQL語句發日後端的真實數據庫,並將返回的結果作適當的處理,最終再返回給用戶。
MyCat收到一條SQL語句時,首先解析SQL語句涉及的表,接着查看此表的定義,若是該表存在分片規則,則獲取SQL語句裏分片字段的值,並匹配分片函數,獲得該SQL語句對應的分片列表,而後將SQL語句發送到相應的分片去執行,最後處理全部分片返回的數據並返回給客戶端。
schema.xml是MyCat的重要配置文件,它管理着邏輯庫、分片表、分片節點和分片主機等信息。
service.xml是系統參數的配置文件,掌握MyCat優化方法,必需熟悉該文件的配置項。
sequence是全局序列的配置文件。
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>
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 | String | 1..* |
rule | String | 0..1 |
ruleRequired | boolean | 0..1 |
primaryKey | String | 1 |
type | String | 0..1 |
autoIncrement | boolean | 0..1 |
subTables | String | 1 |
needAddLimit | Boolean | 0..1 |
3)childTable 標籤
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中將表分爲兩種大的概念:數據量小且不須要作數據切分的表,稱爲非分片表;數據量大到單庫性能、容量不足以支撐,數據須要經過水平切分均勻分佈到不一樣的數據庫中的表,稱爲分片表。而中間件最終須要處理的事情是對數據切分、聚合。
ER模型是實體關係模型,普遍採用概念模型設計方法,基本元素是實體、關係和屬性。MyCat將它引入數據切分規則中,使得有互相依賴的表可以按照某一規則切分到相同的節點上,避免跨庫Join關聯查詢。具體詳情配置內容在這裏不作描述請參考官方文檔。
delete操做不支持沒有主鍵的表。沒有主鍵的表在不一樣節點的順序不一樣,若是執行 select ...limit...,則將出現不一樣的結果集。
不支持XA事務,在提交上可能回滾。
因爲集羣是樂觀的併發控件,事務commit可能在該階段停止,因此若是有兩個事務向集羣中的不一樣節點的同一行寫入並提交,則失敗的節點將停止。對於集羣級別的停止,集羣返回死鎖錯誤。
整個集羣的寫入吞吐量由最弱的節點限制,若是有一個節點變得緩慢,那麼整個集羣將變得緩慢。
集羣內部按照id自增加機制寫入數據,好比集羣中有三臺多是3,6,9這樣的遞增。
MyCat是一箇中間件的第三方應用,sharding-jdbc是一個jar包。 由於MyCat是單獨部署,因此使用MyCat就像是訪問數據庫同樣,而sharding-jdbc的邏輯都是須要在工程裏寫的。
若是隻是單獨應用可使用輕量級的Sharding-JDBC,若是多個服務都須要操做數據庫則使用MyCat更合適。由於用Sharding-JDBC須要在每個工程裏邊都配置上相應的分片等邏輯,而MyCat只須要配置一份單獨部署。
做者:高玉瓏
來源:宜信技術學院