MySQL數(shù)據(jù)庫中怎么實現(xiàn)水平切分,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
專注于為中小企業(yè)提供網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)陜州免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了近1000家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。隨著互聯(lián)網(wǎng)應(yīng)用的廣泛普及,海量數(shù)據(jù)的存儲和訪問成為了系統(tǒng)設(shè)計的瓶頸問題。對于一個大型的互聯(lián)網(wǎng)應(yīng)用,每天幾十億的PV無疑對數(shù)據(jù)庫造成了相當高的負載。對于系統(tǒng)的穩(wěn)定性和擴展性造成了極大的問題。通過數(shù)據(jù)切分來提高網(wǎng)站性能,橫向擴展數(shù)據(jù)層已經(jīng)成為架構(gòu)研發(fā)人員選的方式。水平切分數(shù)據(jù)庫,可以降低單臺機器的負載,同時大限度的降低了了宕機造成的損失。通過負載均衡策略,有效的降低了單臺機器的訪問負載,降低了宕機的可能性;通過集群方案,解決了數(shù)據(jù)庫宕機帶來的單點數(shù)據(jù)庫不能訪問的問題;通過讀寫分離策略更是大限度了提高了應(yīng)用中讀?。≧ead)數(shù)據(jù)的速度和并發(fā)量。目前國內(nèi)的大型互聯(lián)網(wǎng)應(yīng)用中,大量的采用了這樣的數(shù)據(jù)切分方案,Taobao,Alibaba,Tencent,它們大都實現(xiàn)了自己的分布式數(shù)據(jù)訪問層(DDAL)。以實現(xiàn)方式和實現(xiàn)的層次來劃分,大概分為兩個層次(Java應(yīng)用為例):JDBC層的封裝,ORM框架層的實現(xiàn)。就JDBC層的直接封裝而言,現(xiàn)在國內(nèi)發(fā)展較好的一個項目是被稱作“變形蟲”(Amoeba)的項目,由阿里集團的研究院開發(fā),現(xiàn)在仍然處于測試階段(beta版),其運行效率和生產(chǎn)時效性有待考究。就ORM框架層的實現(xiàn)而言,比如Taobao的基于ibatis和Spring的的分布式數(shù)據(jù)訪問層,已有多年的應(yīng)用,運行效率和生產(chǎn)實效性得到了開發(fā)人員和用戶的肯定。本文就是以O(shè)RM框架層為基礎(chǔ)而實現(xiàn)的分布式數(shù)據(jù)訪問層。本課題的難點在于分庫后,路由規(guī)則的制定和選擇以及后期的擴展性,比如:如何做到用最少的數(shù)據(jù)遷移量,達到擴充數(shù)據(jù)庫容量(增加機器節(jié)點)的目的。核心問題將圍繞數(shù)據(jù)庫分庫分表的路由規(guī)則和負載均衡策略展開。
第2章 基本原理和概念
2.1基本原理:
人類認知問題的過程總是這樣的:what(什么)-?why(為什么)-?how(怎么
做),接下來,本文將就這三個問題展開討論和研究:
2.1.1什么是數(shù)據(jù)切分
"Shard" 這個詞英文的意思是"碎片",而作為數(shù)據(jù)庫相關(guān)的技術(shù)用語,似乎最早見于大型多人在線角色扮演游戲中。"Sharding" 姑且稱之為"分片"。Sharding 不是一門新技術(shù),而是一個相對簡樸的軟件理念。眾所周知,MySQL 5 之后才有了數(shù)據(jù)表分區(qū)功能,那么在此之前,很多 MySQL 的潛在用戶都對 MySQL 的擴展性有所顧慮,而是否具備分區(qū)功能就成了衡量一個數(shù)據(jù)庫可擴展性與否的一個關(guān)鍵指標(當然不是唯一指標)。數(shù)據(jù)庫擴展性是一個永恒的話題,MySQL 的推廣者經(jīng)常會被問到:如在單一數(shù)據(jù)庫上處理應(yīng)用數(shù)據(jù)捉襟見肘而需要進行分區(qū)化之類的處理,是如何辦到的呢? 答案是:Sharding。 Sharding 不是一個某個特定數(shù)據(jù)庫軟件附屬的功能,而是在具體技術(shù)細節(jié)之上的抽象處理,是水平擴展(Scale Out,亦或橫向擴展、向外擴展)的解決方案,其主要目的是為突破單節(jié)點數(shù)據(jù)庫服務(wù)器的 I/O 能力限制,解決數(shù)據(jù)庫擴展性問題。
通過一系列的切分規(guī)則將數(shù)據(jù)水平分布到不同的DB或table中,在通過相應(yīng)的DB路由或者table路由規(guī)則找到需要查詢的具體的DB或者table,以進行Query操作。這里所說的“sharding”通常是指“水平切分”,這也是本文討論的重點。具體將有什么樣的切分方式呢和路由方式呢?行文至此,讀者難免有所疑問,接下來舉個簡單的例子:我們針對一個Blog應(yīng)用中的日志來說明, 比如日志文章(article)表有如下字段:
面對這樣的一個表,我們怎樣切分呢?怎樣將這樣的數(shù)據(jù)分布到不同的數(shù)據(jù)庫中的表中去呢?其實分析blog的應(yīng)用,我們不難得出這樣的結(jié)論:blog的應(yīng)用中,用戶分為兩種:瀏覽者和blog的主人。瀏覽者瀏覽某個blog,實際上是在一個特定的用戶的blog下進行瀏覽的,而blog的主人管理自己的blog,也同樣是在特定的用戶blog下進行操作的(在自己的空間下)。所謂的特定的用戶,用數(shù)據(jù)庫的字段表示就是“user_id”。就是這個“user_id”,它就是我們需要的分庫的依據(jù)和規(guī)則的基礎(chǔ)。我們可以這樣做,將user_id為1~10000的所有的文章信息放入DB1中的article表中,將user_id為10001~20000的所有文章信息放入DB2中的article表中,以此類推,一直到DBn。這樣一來,文章數(shù)據(jù)就很自然的被分到了各個數(shù)據(jù)庫中,達到了數(shù)據(jù)切分的目的。接下來要解決的問題就是怎樣找到具體的數(shù)據(jù)庫呢?其實問題也是簡單明顯的,既然分庫的時候我們用到了區(qū)分字段user_id,那么很自然,數(shù)據(jù)庫路由的過程當然還是少不了user_id的??紤]一下我們剛才呈現(xiàn)的blog應(yīng)用,不管是訪問別人的blog還是管理自己的blog,總之我都要知道這個blog的用戶是誰吧,也就是我們知道了這個blog的user_id,就利用這個user_id,利用分庫時候的規(guī)則,反過來定位具體的數(shù)據(jù)庫,比如user_id是234,利用該才的規(guī)則,就應(yīng)該定位到DB1,假如user_id是12343,利用該才的規(guī)則,就應(yīng)該定位到DB2。以此類推,利用分庫的規(guī)則,反向的路由到具體的DB,這個過程我們稱之為“DB路由”。
當然考慮到數(shù)據(jù)切分的DB設(shè)計必然是非常規(guī),不正統(tǒng)的DB設(shè)計。那么什么樣的DB設(shè)計是正統(tǒng)的DB設(shè)計呢?
我們平常規(guī)規(guī)矩矩用的基本都是。平常我們會自覺的按照范式來設(shè)計我們的數(shù)據(jù)庫,負載高點可能考慮使用相關(guān)的Replication機制來提高讀寫的吞吐和性能,這可能已經(jīng)可以滿足很多需求,但這套機制自身的缺陷還是比較顯而易見的(下文會提及)。上面提到的“自覺的按照范式設(shè)計”。考慮到數(shù)據(jù)切分的DB設(shè)計,將違背這個通常的規(guī)矩和約束,為了切分,我們不得不在數(shù)據(jù)庫的表中出現(xiàn)冗余字段,用作區(qū)分字段或者叫做分庫的標記字段,比如上面的article的例子中的user_id這樣的字段(當然,剛才的例子并沒有很好的體現(xiàn)出user_id的冗余性,因為user_id這個字段即使就是不分庫,也是要出現(xiàn)的,算是我們撿了便宜吧)。當然冗余字段的出現(xiàn)并不只是在分庫的場景下才出現(xiàn)的,在很多大型應(yīng)用中,冗余也是必須的,這個涉及到高效DB的設(shè)計,本文不再贅述。
2.1.2為什么要數(shù)據(jù)切分
上面對什么是數(shù)據(jù)切分做了個概要的描述和解釋,讀者可能會疑問,為什么需要數(shù)據(jù)切分呢?像Oracle這樣成熟穩(wěn)定的數(shù)據(jù)庫,足以支撐海量數(shù)據(jù)的存儲與查詢了?為什么還需要數(shù)據(jù)切片呢?的確,Oracle的DB確實很成熟很穩(wěn)定,但是高昂的使用費用和高端的硬件支撐不是每一個公司能支付的起的。試想一下一年幾千萬的使用費用和動輒上千萬元的小型機作為硬件支撐,這是一般公司能支付的起的嗎?即使就是能支付的起,假如有更好的方案,有更廉價且水平擴展性能更好的方案,我們?yōu)槭裁床贿x擇呢?
但是,事情總是不盡人意。平常我們會自覺的按照范式來設(shè)計我們的數(shù)據(jù)庫,負載高點可能考慮使用相關(guān)的Replication機制來提高讀寫的吞吐和性能,這可能已經(jīng)可以滿足很多需求,但這套機制自身的缺陷還是比較顯而易見的。首先它的有效很依賴于讀操作的比例,Master往往會成為瓶頸所在,寫操作需要順序排隊來執(zhí)行,過載的話Master首先扛不住,Slaves的數(shù)據(jù)同步的延遲也可能比較大,而且會大大耗費CPU的計算能力,因為write操作在Master上執(zhí)行以后還是需要在每臺slave機器上都跑一次。這時候 Sharding可能會成為雞肋了。 Replication搞不定,那么為什么Sharding可以工作呢?道理很簡單,因為它可以很好的擴展。我們知道每臺機器無論配置多么好它都有自身的物理上限,所以當我們應(yīng)用已經(jīng)能觸及或遠遠超出單臺機器的某個上限的時候,我們惟有尋找別的機器的幫助或者繼續(xù)升級的我們的硬件,但常見的方案還是橫向擴展, 通過添加更多的機器來共同承擔壓力。我們還得考慮當我們的業(yè)務(wù)邏輯不斷增長,我們的機器能不能通過線性增長就能滿足需求?Sharding可以輕松的將計算,存儲,I/O并行分發(fā)到多臺機器上,這樣可以充分利用多臺機器各種處理能力,同時可以避免單點失敗,提供系統(tǒng)的可用性,進行很好的錯誤隔離。
綜合以上因素,數(shù)據(jù)切分是很有必要的,且我們在此討論的數(shù)據(jù)切分也是將MySql作為背景的。基于成本的考慮,很多公司也選擇了Free且Open的MySql。對MySql有所了解的開發(fā)人員可能會知道,MySQL 5 之后才有了數(shù)據(jù)表分區(qū)功能,那么在此之前,很多 MySQL 的潛在用戶都對 MySQL 的擴展性有所顧慮,而是否具備分區(qū)功能就成了衡量一個數(shù)據(jù)庫可擴展性與否的一個關(guān)鍵指標(當然不是唯一指標)。數(shù)據(jù)庫擴展性是一個永恒的話題,MySQL 的推廣者經(jīng)常會被問到:如在單一數(shù)據(jù)庫上處理應(yīng)用數(shù)據(jù)捉襟見肘而需要進行分區(qū)化之類的處理,是如何辦到的呢? 答案也是Sharding,也就是我們所說的數(shù)據(jù)切分方案。
我們用免費的MySQL和廉價的Server甚至是PC做集群,達到小型機+大型商業(yè)DB的效果,減少大量的資金投入,降低運營成本,何樂而不為呢?所以,我們選擇Sharding,擁抱Sharding。
2.1.3怎么做到數(shù)據(jù)切分
說到數(shù)據(jù)切分,再次我們講對數(shù)據(jù)切分的方法和形式進行比較詳細的闡述和說明。
數(shù)據(jù)切分可以是物理上的,對數(shù)據(jù)通過一系列的切分規(guī)則將數(shù)據(jù)分布到不同的DB服務(wù)器上,通過路由規(guī)則路由訪問特定的數(shù)據(jù)庫,這樣一來每次訪問面對的就不是單臺服務(wù)器了,而是N臺服務(wù)器,這樣就可以降低單臺機器的負載壓力。
數(shù)據(jù)切分也可以是數(shù)據(jù)庫內(nèi)的,對數(shù)據(jù)通過一系列的切分規(guī)則,將數(shù)據(jù)分布到一個數(shù)據(jù)庫的不同表中,比如將article分為article_001,article_002等子表,若干個子表水平拼合有組成了邏輯上一個完整的article表,這樣做的目的其實也是很簡單的。舉個例子說明,比如article表中現(xiàn)在有5000w條數(shù)據(jù),此時我們需要在這個表中增加(insert)一條新的數(shù)據(jù),insert完畢后,數(shù)據(jù)庫會針對這張表重新建立索引,5000w行數(shù)據(jù)建立索引的系統(tǒng)開銷還是不容忽視的。但是反過來,假如我們將這個表分成100個table呢,從article_001一直到article_100,5000w行數(shù)據(jù)平均下來,每個子表里邊就只有50萬行數(shù)據(jù),這時候我們向一張只有50w行數(shù)據(jù)的table中insert數(shù)據(jù)后建立索引的時間就會呈數(shù)量級的下降,極大了提高了DB的運行時效率,提高了DB的并發(fā)量。當然分表的好處還不知這些,還有諸如寫操作的鎖操作等,都會帶來很多顯然的好處。
綜上,分庫降低了單點機器的負載;分表,提高了數(shù)據(jù)操作的效率,尤其是Write操作的效率。行文至此我們依然沒有涉及到如何切分的問題。接下來,我們將對切分規(guī)則進行詳盡的闡述和說明。
上文中提到,要想做到數(shù)據(jù)的水平切分,在每一個表中都要有相冗余字符作為切分依據(jù)和標記字段,通常的應(yīng)用中我們選用user_id作為區(qū)分字段,基于此就有如下三種分庫的方式和規(guī)則:(當然還可以有其他的方式)
按號段分:
(1) user_id為區(qū)分,1~1000的對應(yīng)DB1,1001~2000的對應(yīng)DB2,以此類推;
優(yōu)點:可部分遷移
缺點:數(shù)據(jù)分布不均
(2)hash取模分:
對user_id進行hash(或者如果user_id是數(shù)值型的話直接使用user_id的值也可),然后用一個特定的數(shù)字,比如應(yīng)用中需要將一個數(shù)據(jù)庫切分成4個數(shù)據(jù)庫的話,我們就用4這個數(shù)字對user_id的hash值進行取模運算,也就是user_id%4,這樣的話每次運算就有四種可能:結(jié)果為1的時候?qū)?yīng)DB1;結(jié)果為2的時候?qū)?yīng)DB2;結(jié)果為3的時候?qū)?yīng)DB3;結(jié)果為0的時候?qū)?yīng)DB4,這樣一來就非常均勻的將數(shù)據(jù)分配到4個DB中。
優(yōu)點:數(shù)據(jù)分布均勻
缺點:數(shù)據(jù)遷移的時候麻煩,不能按照機器性能分攤數(shù)據(jù)
(3)在認證庫中保存數(shù)據(jù)庫配置
就是建立一個DB,這個DB單獨保存user_id到DB的映射關(guān)系,每次訪問數(shù)據(jù)庫的時候都要先查詢一次這個數(shù)據(jù)庫,以得到具體的DB信息,然后才能進行我們需要的查詢操作。
優(yōu)點:靈活性強,一對一關(guān)系
缺點:每次查詢之前都要多一次查詢,性能大打折扣
以上就是通常的開發(fā)中我們選擇的三種方式,有些復雜的項目中可能會混合使用這三種方式。通過上面的描述,我們對分庫的規(guī)則也有了簡單的認識和了解。當然還會有更好更完善的分庫方式,還需要我們不斷的探索和發(fā)現(xiàn)。
第3章 本課題研究的基本輪廓
上面的文字,我們按照人類認知事物的規(guī)律,what?why?how這樣的方式闡述了數(shù)據(jù)庫切分的一些概念和意義以及對一些常規(guī)的切分規(guī)則做了概要的介紹。本課題所討論的分布數(shù)據(jù)層并不僅僅如此,它是一個完整的數(shù)據(jù)層解決方案,它到底是什么樣的呢?接下來的文字,我將詳細闡述本研究課題的完整思想和實現(xiàn)方式。
分布式數(shù)據(jù)方案提供功能如下:
(1)提供分庫規(guī)則和路由規(guī)則(RouteRule簡稱RR),將上面的說明中提到的三中切分規(guī)則直接內(nèi)嵌入本系統(tǒng),具體的嵌入方式在接下來的內(nèi)容中進行詳細的說明和論述;
(2)引入集群(Group)的概念,保證數(shù)據(jù)的高可用性;
(3)引入負載均衡策略(LoadBalancePolicy簡稱LB);
(4)引入集群節(jié)點可用性探測機制,對單點機器的可用性進行定時的偵測,以保證LB策略的正確實施,以確保系統(tǒng)的高度穩(wěn)定性;
(5)引入讀/寫分離,提高數(shù)據(jù)的查詢速度;
僅僅是分庫分表的數(shù)據(jù)層設(shè)計也是不夠完善的,當某個節(jié)點上的DB服務(wù)器出現(xiàn)了宕機的情況的時候,會是什么樣的呢?是的,我們采用了數(shù)據(jù)庫切分方案,也就是說有N太機器組成了一個完整的DB,如果有一臺機器宕機的話,也僅僅是一個DB的N分之一的數(shù)據(jù)不能訪問而已,這是我們能接受的,起碼比切分之前的情況好很多了,總不至于整個DB都不能訪問。一般的應(yīng)用中,這樣的機器故障導致的數(shù)據(jù)無法訪問是可以接受的,假設(shè)我們的系統(tǒng)是一個高并發(fā)的電子商務(wù)網(wǎng)站呢?單節(jié)點機器宕機帶來的經(jīng)濟損失是非常嚴重的。也就是說,現(xiàn)在我們這樣的方案還是存在問題的,容錯性能是經(jīng)不起考驗的。當然了,問題總是有解決方案的。我們引入集群的概念,在此我稱之為Group,也就是每一個分庫的節(jié)點我們引入多臺機器,每臺機器保存的數(shù)據(jù)是一樣的,一般情況下這多臺機器分攤負載,當出現(xiàn)宕機情況,負載均衡器將分配負載給這臺宕機的機器。這樣一來,
就解決了容錯性的問題。所以我們引入了集群的概念,并將其內(nèi)嵌入我們的框架中,成為框架的一部分。
如上圖所示,整個數(shù)據(jù)層有Group1,Group2,Group3三個集群組成,這三個集群就是數(shù)據(jù)水平切分的結(jié)果,當然這三個集群也就組成了一個包含完整數(shù)據(jù)的DB。每一個Group包括1個Master(當然Master也可以是多個)和N個Slave,這些Master和Slave的數(shù)據(jù)是一致的。 比如Group1中的一個slave發(fā)生了宕機現(xiàn)象,那么還有兩個slave是可以用的,這樣的模型總是不會造成某部分數(shù)據(jù)不能訪問的問題,除非整個Group里的機器全部宕掉,但是考慮到這樣的事情發(fā)生的概率非常小(除非是斷電了,否則不易發(fā)生吧)。
在沒有引入集群以前,我們的一次查詢的過程大致如下:請求數(shù)據(jù)層,并傳遞必要的分庫區(qū)分字段(通常情況下是user_id)?數(shù)據(jù)層根據(jù)區(qū)分字段Route到具體的DB?在這個確定的DB內(nèi)進行數(shù)據(jù)操作。這是沒有引入集群的情況,當時引入集群會是什么樣子的呢?看圖一即可得知,我們的路由器上規(guī)則和策略其實只能路由到具體的Group,也就是只能路由到一個虛擬的Group,這個Group并不是某個特定的物理服務(wù)器。接下來需要做的工作就是找到具體的物理的DB服務(wù)器,以進行具體的數(shù)據(jù)操作。基于這個環(huán)節(jié)的需求,我們引入了負載均衡器的概念(LB)。負載均衡器的職責就是定位到一臺具體的DB服務(wù)器。具體的規(guī)則如下:負載均衡器會分析當前sql的讀寫特性,如果是寫操作或者是要求實時性很強的操作的話,直接將查詢負載分到Master,如果是讀操作則通過負載均衡策略分配一個Slave。我們的負載均衡器的主要研究放向也就是負載分發(fā)策略,通常情況下負載均衡包括隨機負載均衡和加權(quán)負載均衡。隨機負載均衡很好理解,就是從N個Slave中隨機選取一個Slave。這樣的隨機負載均衡是不考慮機器性能的,它默認為每臺機器的性能是一樣的。假如真實的情況是這樣的,這樣做也是無可厚非的。假如實際情況并非如此呢?每個Slave的機器物理性能和配置不一樣的情況,再使用隨機的不考慮性能的負載均衡,是非常不科學的,這樣一來會給機器性能差的機器帶來不必要的高負載,甚至帶來宕機的危險,同時高性能的數(shù)據(jù)庫服務(wù)器也不能充分發(fā)揮其物理性能?;诖丝紤]從,我們引入了加權(quán)負載均衡,也就是在我們的系統(tǒng)內(nèi)部通過一定的接口,可以給每臺DB服務(wù)器分配一個權(quán)值,然后再運行時LB根據(jù)權(quán)值在集群中的比重,分配一定比例的負載給該DB服務(wù)器。當然這樣的概念的引入,無疑增大了系統(tǒng)的復雜性和可維護性。有得必有失,我們也沒有辦法逃過的。
有了分庫,有了集群,有了負載均衡器,是不是就萬事大吉了呢?事情遠沒有我們想象的那么簡單。雖然有了這些東西,基本上能保證我們的數(shù)據(jù)層可以承受很大的壓力,但是這樣的設(shè)計并不能完全規(guī)避數(shù)據(jù)庫宕機的危害。假如Group1中的slave2宕機了,那么系統(tǒng)的LB并不能得知,這樣的話其實是很危險的,因為LB不知道,它還會以為slave2為可用狀態(tài),所以還是會給slave2分配負載。這樣一來,問題就出來了,客戶端很自然的就會發(fā)生數(shù)據(jù)操作失敗的錯誤或者異常。這樣是非常不友好的!怎樣解決這樣的問題呢?我們引入集群節(jié)點的可用性探測機制,或者是可用性的數(shù)據(jù)推送機制。這兩種機制有什么不同呢?首先說探測機制吧,顧名思義,探測即使,就是我的數(shù)據(jù)層客戶端,不定時對集群中各個數(shù)據(jù)庫進行可用性的嘗試,實現(xiàn)原理就是嘗試性鏈接,或者數(shù)據(jù)庫端口的嘗試性訪問,都可以做到,當然也可以用JDBC嘗試性鏈接,利用Java的Exception機制進行可用性的判斷,具體的會在后面的文字中提到。那數(shù)據(jù)推送機制又是什么呢?其實這個就要放在現(xiàn)實的應(yīng)用場景中來討論這個問題了,一般情況下應(yīng)用的DB數(shù)據(jù)庫宕機的話我相信DBA肯定是知道的,這個時候DBA手動的將數(shù)據(jù)庫的當前狀態(tài)通過程序的方式推送到客戶端,也就是分布式數(shù)據(jù)層的應(yīng)用端,這個時候在更新一個本地的DB狀態(tài)的列表。并告知LB,這個數(shù)據(jù)庫節(jié)點不能使用,請不要給它分配負載。一個是主動的監(jiān)聽機制,一個是被動的被告知的機制。兩者各有所長。但是都可以達到同樣的效果。這樣一來剛才假設(shè)的問題就不會發(fā)生了,即使就是發(fā)生了,那么發(fā)生的概率也會降到最低。
上面的文字中提到的Master和Slave,我們并沒有做太多深入的講解。如圖一所示,一個Group由1個Master和N個Slave組成。為什么這么做呢?其中Master負責寫操作的負載,也就是說一切寫的操作都在Master上進行,而讀的操作則分攤到Slave上進行。這樣一來的可以大大提高讀取的效率。在一般的互聯(lián)網(wǎng)應(yīng)用中,經(jīng)過一些數(shù)據(jù)調(diào)查得出結(jié)論,讀/寫的比例大概在10:1左右,也就是說大量的數(shù)據(jù)操作是集中在讀的操作,這也就是為什么我們會有多個Slave的原因。但是為什么要分離讀和寫呢?熟悉DB的研發(fā)人員都知道,寫操作涉及到鎖的問題,不管是行鎖還是表鎖還是塊鎖,都是比較降低系統(tǒng)執(zhí)行效率的事情。我們這樣的分離是把寫操作集中在一個節(jié)點上,而讀操作其其他的N個節(jié)點上進行,從另一個方面有效的提高了讀的效率,保證了系統(tǒng)的高可用性。讀寫分離也會引入新的問題,比如我的Master上的數(shù)據(jù)怎樣和集群中其他的Slave機器保持數(shù)據(jù)的同步和一致呢?這個是我們不需要過多的關(guān)注的問題,MySql的Proxy機制可以幫助我們做到這點,由于Proxy機制與本課題相關(guān)性不是太強,
在這里不做詳細介紹。
綜上所述,本課題中所研究的分布式數(shù)據(jù)層的大體功能就是如此。以上是對基本原理的一些討論和闡述。接下來就系統(tǒng)設(shè)計層面,進行深入的剖析和研究。
第4章 系統(tǒng)設(shè)計
4.1系統(tǒng)實現(xiàn)層面的選擇
在引言部分中提到,該系統(tǒng)的實現(xiàn)層面有兩種選擇,一種是基于JDBC層面上的選擇,一種是基于現(xiàn)有數(shù)據(jù)持久層框架層面上的選擇,比如Hibernate,ibatis。兩種層面各有長處,也各有不足之處?;贘DBC層面上的系統(tǒng)實現(xiàn),系統(tǒng)開發(fā)難度和后期的使用難度都將大大提高。大大增加了系統(tǒng)的開發(fā)費用和維護費用。本課題的定位是在成型的ibatis持久層框架的基礎(chǔ)上進行上層的封裝,而不是對ibatis源碼的直接修改,這樣一來使本系統(tǒng)不會對現(xiàn)有框架有太多的侵入性,從而也增加了使用的靈活性。之所以選擇ibatis,原因如下:
(1)ibatis的學習成本非常低,熟練的Java Programmer可在非常的短時間內(nèi)熟練使用ibatis;
(2)ibatis是輕量級的ORM,只是簡單的完成了RO,OR的映射,其查詢語句也是通過配置文件sql-map.xml文件在原生sql的層面進行簡單的配置,也就是說我們沒有引入諸如Hibernate那樣的HQL的概念,從而增強了sql的可控性,優(yōu)秀的DBA可以很好的從sql的層面對sql進行優(yōu)化,使數(shù)據(jù)層的應(yīng)用有很強的可控性。Hibernate雖然很強大,但是由于Hibernate是OR的一個重型封裝,且引入HQL的概念,不便于DBA團隊對sql語句的控制和性能的調(diào)優(yōu)。
基于以上兩點理由,本課題在ORM的產(chǎn)品的選擇上選擇了易學易用且輕量級的持久層框架ibatis。下面的討論也都是特定于ibatis的基礎(chǔ)上的討論。
4.2其他開源框架的選擇
在一些大型的Java應(yīng)用中,我們通常會采用Spring這樣的開源框架,尤其是IoC(DI)這部分,有效的幫助開發(fā)人員管理對象的依賴關(guān)系和層次,降低系統(tǒng)各層次之間的實體耦合。Spring的優(yōu)點和用處我相信這是開發(fā)人員眾所周知的,在此不再贅述。本課題的數(shù)據(jù)層也將采用Spring做為IoC(DI)的框架。
4.3系統(tǒng)開發(fā)技術(shù)和工具介紹
開發(fā)語言:Java JDK1.5
集成開發(fā)環(huán)境:Eclipse 3.3.4
Web環(huán)境下測試服務(wù)器:JBoss 4.2
構(gòu)建工具:淘寶自行研發(fā)的構(gòu)建工具Antx(類似于Maven),當然也可以用Maven
依賴的開源Jar:Spring2.0,ibaits,commons-configuration(讀取配置文件),log4j,junit等
第5章 系統(tǒng)分析
1、系統(tǒng)有那些關(guān)鍵數(shù)據(jù)需要切分
系統(tǒng)有靜態(tài)數(shù)據(jù)和動態(tài)數(shù)據(jù)。
靜態(tài)數(shù)據(jù)往往數(shù)據(jù)量小不需要切分,那么就需要獨立一個單獨的靜態(tài)配置庫,考慮到很多sql一定會用join的方式進行關(guān)聯(lián)靜態(tài)數(shù)據(jù),那么靜態(tài)數(shù)據(jù)肯定會往動態(tài)數(shù)據(jù)庫中進行復制。同時,一個單獨的靜態(tài)庫,對于靜態(tài)數(shù)據(jù)的管理非常方便。
動態(tài)數(shù)據(jù),是只有橫向切分,還是采用縱向切分加上橫向切分。比如:按照用戶和blog進行縱向切分后,在進行用戶和blog的橫向切分。
切分的粒度需要精確掌握,否則會引起開發(fā)和維護的很多困難。
2、全局唯一ID
如果采用hash分庫或者地理位置屬性分庫進行了橫向切分后,用戶ID或者blog的ID肯定具有含義,能夠通過ID定位到對應(yīng)的切分庫中。
無論那種方式,ID一定是有含義的,從字面上或者算法上都能夠識別數(shù)據(jù)歸屬那個切分庫。
3、切分數(shù)據(jù)一體化(連帶性)
如果是一個龐大的數(shù)據(jù)庫,其中必定有很多模型。比如:用戶模型,資料模型等等,是否一個用戶對應(yīng)的資料都能夠在這個用戶對應(yīng)的數(shù)據(jù)庫中找到。這樣做,會盡量減少開發(fā)的難度,不可能完全的要求開發(fā)避免關(guān)聯(lián)表的使用。
4、分表的管理
采用了橫向數(shù)據(jù)庫切分后,必然存在數(shù)據(jù)庫分表。
是否切分庫中存在一個分表,還是一個切分庫中存在多個分表。
那些分表在那個庫中,那些分表歸屬一個切分庫,這些都需要管理。
如果一個切分庫就一個類型的一張分表,也太浪費數(shù)據(jù)庫資源了。
5、分庫后的連接管理
數(shù)據(jù)庫切分后,數(shù)據(jù)庫增多,必然會導致連接的增多。
一個應(yīng)用是連接所有的分庫?還是劃分某個功能的應(yīng)用連接特定的分庫?
如果采用oracle的rac,還要考慮rac的gc buffer busy的問題。
6、開發(fā)上sql的配合
如果系統(tǒng)不大,可以采用配置sql+xml文件方式。采用分庫的系統(tǒng),一般都很龐大。
采用sql+xml的配置,一定會出現(xiàn)很多問題,開發(fā)的難度和不配合程度一定會直線上升。需要將sql下放給開發(fā)人員,針對sql中的表可以采用抽象和邏輯的管理模式。既提高了開發(fā)效率,又能管理需要執(zhí)行到分庫中的sql。
7、業(yè)務(wù)參數(shù)
如果業(yè)務(wù)邏輯很復雜,要求每一個函數(shù)或者每一個方法,都顯示的傳遞分庫參數(shù)。就將分庫的邏輯和應(yīng)用完全的柔和在一起,將導致后期的維護和升級極其的困難。
采用在頁面或者接口層面?zhèn)鬟f一次業(yè)務(wù)邏輯參數(shù),后期在orm底層使用這些參數(shù)。
8、業(yè)務(wù)的取舍
以前的應(yīng)用,可以按照名字進行查詢。分庫后,無法進行這樣的查詢,需要按照分庫屬性進行查詢。將會導致業(yè)務(wù)上或者上操作上的變更。
一般會有些業(yè)務(wù)的操作會隨著分庫的進行而變動。
9、分布式事務(wù)
切分多個庫后,難免有業(yè)務(wù)操作多個數(shù)據(jù)庫,那么就會帶來分布式事務(wù)的問題(分布式事務(wù)不僅僅出現(xiàn)在多個數(shù)據(jù)庫中)。同時,一個繁忙的數(shù)據(jù)庫,進行跨庫操作的時候,要避免跨庫的死鎖。數(shù)據(jù)庫可不會檢測到另外一個庫與自己的死鎖。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。
文章標題:MySQL數(shù)據(jù)庫中怎么實現(xiàn)水平切分-創(chuàng)新互聯(lián)
網(wǎng)頁URL:http://jinyejixie.com/article48/dipjhp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、營銷型網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計公司、外貿(mào)網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計、虛擬主機
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容