新聞中心
對(duì)于數(shù)據(jù)切分,我們可能還不是很熟悉,但是它對(duì)于MySQL數(shù)據(jù)庫(kù)來(lái)說(shuō)也是相當(dāng)重要的一門技術(shù),本文我們就詳細(xì)介紹一下MySQL數(shù)據(jù)庫(kù)的數(shù)據(jù)切分的相關(guān)知識(shí),接下來(lái)就讓我們一起來(lái)了解一下這部分內(nèi)容。

成都創(chuàng)新互聯(lián)公司是一家以成都網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、品牌設(shè)計(jì)、軟件運(yùn)維、成都網(wǎng)站推廣、小程序App開(kāi)發(fā)等移動(dòng)開(kāi)發(fā)為一體互聯(lián)網(wǎng)公司。已累計(jì)為木屋等眾行業(yè)中小客戶提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開(kāi)發(fā)服務(wù)。
什么是數(shù)據(jù)切分
"Shard" 這個(gè)詞英文的意思是"碎片",而作為數(shù)據(jù)庫(kù)相關(guān)的技術(shù)用語(yǔ),似乎最早見(jiàn)于大型多人在線角色扮演游戲中。"Sharding" 姑且稱之為"分片"。Sharding 不是一門新技術(shù),而是一個(gè)相對(duì)簡(jiǎn)樸的軟件理念。眾所周知,MySQL 5 之后才有了數(shù)據(jù)表分區(qū)功能,那么在此之前,很多MySQL的潛在用戶都對(duì)MySQL的擴(kuò)展性有所顧慮,而是否具備分區(qū)功能就成了衡量一個(gè)數(shù)據(jù)庫(kù)可擴(kuò)展性與否的一個(gè)關(guān)鍵指標(biāo)(當(dāng)然不是唯一指標(biāo))。
數(shù)據(jù)庫(kù)擴(kuò)展性是一個(gè)永恒的話題,MySQL 的推廣者經(jīng)常會(huì)被問(wèn)到:如在單一數(shù)據(jù)庫(kù)上處理應(yīng)用數(shù)據(jù)捉襟見(jiàn)肘而需要進(jìn)行分區(qū)化之類的處理,是如何辦到的呢? 答案是:Sharding。 Sharding 不是一個(gè)某個(gè)特定數(shù)據(jù)庫(kù)軟件附屬的功能,而是在具體技術(shù)細(xì)節(jié)之上的抽象處理,是水平擴(kuò)展(Scale Out,亦或橫向擴(kuò)展、向外擴(kuò)展)的解決方案,其主要目的是為突破單節(jié)點(diǎn)數(shù)據(jù)庫(kù)服務(wù)器的 I/O 能力限制,解決數(shù)據(jù)庫(kù)擴(kuò)展性問(wèn)題。
通過(guò)一系列的切分規(guī)則將數(shù)據(jù)水平分布到不同的DB或table中,在通過(guò)相應(yīng)的DB路由 或者 table路由規(guī)則找到需要查詢的具體的DB或者table,以進(jìn)行Query操作。這里所說(shuō)的“sharding”通常是指“水平切分”, 這也是本文討 論的重點(diǎn)。具體將有什么樣的切分方式呢和路由方式呢?行文至此,讀者難免有所疑問(wèn),接下來(lái)舉個(gè)簡(jiǎn)單的例子:我們針對(duì)一個(gè)Blog應(yīng)用中的日志來(lái)說(shuō)明, 比如日志文章(article)表有如下字段:article_id(int),title(varchar(128)),content(varchar(1024)),user_id(int).
面對(duì)這樣的一個(gè)表,我們?cè)鯓忧蟹帜??怎樣將這樣的數(shù)據(jù)分布到不同的數(shù)據(jù)庫(kù)中的表中去呢?其實(shí) 分析blog的應(yīng)用,我們不難得出這樣的結(jié)論:blog的應(yīng)用中,用戶分為兩種:瀏覽者和blog的主人。瀏覽者瀏覽某個(gè)blog,實(shí)際上是在一個(gè)特定的 用戶的blog下進(jìn)行瀏覽的,而blog的主人管理自己的blog,也同樣是在特定的用戶blog下進(jìn)行操作的(在自己的空間下)。所謂的特定的用戶,用數(shù)據(jù)庫(kù)的字段表示就是“user_id”。就是這個(gè)“user_id”,它就是我們需要的分庫(kù)的依據(jù)和規(guī)則的基礎(chǔ)。我們可以這樣做,將user_id為 1~10000的所有的文章信息放入DB1中的article表中,將user_id為10001~20000的所有文章信息放入DB2中的 article表中,以此類推,一直到DBn。
這樣一來(lái),文章數(shù)據(jù)就很自然的被分到了各個(gè)數(shù)據(jù)庫(kù)中,達(dá)到了數(shù)據(jù)切分的目的。接下來(lái)要解決的問(wèn)題就是怎樣找 到具體的數(shù)據(jù)庫(kù)呢?其實(shí)問(wèn)題也是簡(jiǎn)單明顯的,既然分庫(kù)的時(shí)候我們用到了區(qū)分字段user_id,那么很自然,數(shù)據(jù)庫(kù)路由的過(guò)程當(dāng)然還是少不了 user_id的。考慮一下我們剛才呈現(xiàn)的blog應(yīng)用,不管是訪問(wèn)別人的blog還是管理自己的blog,總之我都要知道這個(gè)blog的用戶是誰(shuí)吧,也 就是我們知道了這個(gè)blog的user_id,就利用這個(gè)user_id,利用分庫(kù)時(shí)候的規(guī)則,反過(guò)來(lái)定位具體的數(shù)據(jù)庫(kù),比如user_id是234,利 用該才的規(guī)則,就應(yīng)該定位到DB1,假如user_id是12343,利用該才的規(guī)則,就應(yīng)該定位到DB2。以此類推,利用分庫(kù)的規(guī)則,反向的路由到具體 的DB,這個(gè)過(guò)程我們稱之為“DB路由”。
當(dāng)然考慮到數(shù)據(jù)切分的DB設(shè)計(jì)必然是非常規(guī),不正統(tǒng)的DB設(shè)計(jì)。那么什么樣的DB設(shè)計(jì)是正統(tǒng)的DB設(shè)計(jì)呢?
我們平常規(guī)規(guī)矩矩用的基本都是。平常我們會(huì)自覺(jué)的按照范式來(lái)設(shè)計(jì)我們的數(shù)據(jù)庫(kù),負(fù)載高點(diǎn)可能 考慮使用相關(guān)的Replication機(jī)制來(lái)提高讀寫的吞吐和性能,這可能已經(jīng)可以滿足很多需求,但這套機(jī)制自身的缺陷還是比較顯而易見(jiàn)的(下文會(huì)提 及)。上面提到的“自覺(jué)的按照范式設(shè)計(jì)”??紤]到數(shù)據(jù)切分的DB設(shè)計(jì),將違背這個(gè)通常的規(guī)矩和約束,為了切分,我們不得不在數(shù)據(jù)庫(kù)的表中出現(xiàn)冗余字段,用 作區(qū)分字段或者叫做分庫(kù)的標(biāo)記字段,比如上面的article的例子中的user_id這樣的字段(當(dāng)然,剛才的例子并沒(méi)有很好的體現(xiàn)出user_id的 冗余性,因?yàn)閡ser_id這個(gè)字段即使就是不分庫(kù),也是要出現(xiàn)的,算是我們撿了便宜吧)。當(dāng)然冗余字段的出現(xiàn)并不只是在分庫(kù)的場(chǎng)景下才出現(xiàn)的,在很多大型應(yīng)用中,冗余也是必須的,這個(gè)涉及到高效DB的設(shè)計(jì),本文不再贅述。
為什么要數(shù)據(jù)切分
上面對(duì)什么是數(shù)據(jù)切分做了個(gè)概要的描述和解釋,讀者可能會(huì)疑問(wèn),為什么需要數(shù)據(jù)切分呢?像 Oracle這樣成熟穩(wěn)定的數(shù)據(jù)庫(kù),足以支撐海量數(shù)據(jù)的存儲(chǔ)與查詢了?為什么還需要數(shù)據(jù)切片呢?的確,Oracle的DB確實(shí)很成熟很穩(wěn)定,但是高昂的使 用費(fèi)用和高端的硬件支撐不是每一個(gè)公司能支付的起的。試想一下一年幾千萬(wàn)的使用費(fèi)用和動(dòng)輒上千萬(wàn)元的小型機(jī)作為硬件支撐,這是一般公司能支付的起的嗎?即 使就是能支付的起,假如有更好的方案,有更廉價(jià)且水平擴(kuò)展性能更好的方案,我們?yōu)槭裁床贿x擇呢?
但是,事情總是不盡人意。平常我們會(huì)自覺(jué)的按照范式來(lái)設(shè)計(jì)我們的數(shù)據(jù)庫(kù),負(fù)載高點(diǎn)可能考慮使 用相關(guān)的Replication機(jī)制來(lái)提高讀寫的吞吐和性能,這可能已經(jīng)可以滿足很多需求,但這套機(jī)制自身的缺陷還是比較顯而易見(jiàn)的。首先它的有效很依賴 于讀操作的比例,Master往往會(huì)成為瓶頸所在,寫操作需要順序排隊(duì)來(lái)執(zhí)行,過(guò)載的話Master首先扛不住,Slaves的數(shù)據(jù)同步的延遲也可能比較大,而且會(huì)大大耗費(fèi)CPU的計(jì)算能力,因?yàn)閣rite操作在Master上執(zhí)行以后還是需要在每臺(tái)slave機(jī)器上都跑一次。這時(shí)候 Sharding可能會(huì)成為雞肋了。
Replication搞不定,那么為什么Sharding可以工作呢?道理很簡(jiǎn)單,因?yàn)樗梢院芎玫臄U(kuò)展。我們知道每臺(tái)機(jī)器無(wú)論配置多么好它都有自身的 物理上限,所以當(dāng)我們應(yīng)用已經(jīng)能觸及或遠(yuǎn)遠(yuǎn)超出單臺(tái)機(jī)器的某個(gè)上限的時(shí)候,我們惟有尋找別的機(jī)器的幫助或者繼續(xù)升級(jí)的我們的硬件,但常見(jiàn)的方案還是橫向擴(kuò) 展, 通過(guò)添加更多的機(jī)器來(lái)共同承擔(dān)壓力。我們還得考慮當(dāng)我們的業(yè)務(wù)邏輯不斷增長(zhǎng),我們的機(jī)器能不能通過(guò)線性增長(zhǎng)就能滿足需求?Sharding可以輕松的將計(jì) 算,存儲(chǔ),I/O并行分發(fā)到多臺(tái)機(jī)器上,這樣可以充分利用多臺(tái)機(jī)器各種處理能力,同時(shí)可以避免單點(diǎn)失敗,提供系統(tǒng)的可用性,進(jìn)行很好的錯(cuò)誤隔離。
綜合以上因素,數(shù)據(jù)切分是很有必要的,且我們?cè)诖擞懻摰臄?shù)據(jù)切分也是將MySql作為背景的?;诔杀镜目紤],很多公司也選擇了Free且Open的MySql。對(duì)MySql有所了解的開(kāi)發(fā)人員可能會(huì)知道,MySQL 5之后才有了數(shù)據(jù)表分區(qū)功能,那么在此之前,很多MySQL的潛在用戶都對(duì)MySQL的擴(kuò)展性有所顧慮,而是否具備分區(qū)功能就成了衡量一個(gè)數(shù)據(jù)庫(kù)可擴(kuò)展性與否的一個(gè)關(guān)鍵指標(biāo)(當(dāng)然不是唯一指標(biāo))。數(shù)據(jù)庫(kù)擴(kuò)展性是一個(gè)永恒的話題,MySQL的推廣者經(jīng)常會(huì)被問(wèn)到:如在單一數(shù)據(jù)庫(kù)上處理應(yīng)用數(shù)據(jù)捉襟見(jiàn)肘而需要進(jìn)行分區(qū)化之類的處理,是如何辦到的呢? 答案也是Sharding,也就是我們所說(shuō)的數(shù)據(jù)切分方案。
怎么做到數(shù)據(jù)切分
說(shuō)到數(shù)據(jù)切分,再次我們講對(duì)數(shù)據(jù)切分的方法和形式進(jìn)行比較詳細(xì)的闡述和說(shuō)明。
數(shù)據(jù)切分可以是物理上的,對(duì)數(shù)據(jù)通過(guò)一系列的切分規(guī)則將數(shù)據(jù)分布到不同的DB服務(wù)器上,通過(guò)路由規(guī)則路由訪問(wèn)特定的數(shù)據(jù)庫(kù),這樣一來(lái)每次訪問(wèn)面對(duì)的就不是單臺(tái)服務(wù)器了,而是N臺(tái)服務(wù)器,這樣就可以降低單臺(tái)機(jī)器的負(fù)載壓力。
數(shù)據(jù)切分也可以是數(shù)據(jù)庫(kù)內(nèi)的 ,對(duì)數(shù)據(jù)通過(guò)一系列的切分規(guī)則,將數(shù)據(jù)分布到一個(gè)數(shù)據(jù)庫(kù)的不同表 中,比如將article分為article_001,article_002等子表,若干個(gè)子表水平拼合有組成了邏輯上一個(gè)完整的article表,這 樣做的目的其實(shí)也是很簡(jiǎn)單的。 舉個(gè)例子說(shuō)明,比如article表中現(xiàn)在有5000w條數(shù)據(jù),此時(shí)我們需要在這個(gè)表中增加(insert)一條新的數(shù) 據(jù),insert完畢后,數(shù)據(jù)庫(kù)會(huì)針對(duì)這張表重新建立索引,5000w行數(shù)據(jù)建立索引的系統(tǒng)開(kāi)銷還是不容忽視的。
但是反過(guò)來(lái),假如我們將這個(gè)表分成100 個(gè)table呢,從article_001一直到article_100,5000w行數(shù)據(jù)平均下來(lái),每個(gè)子表里邊就只有50萬(wàn)行數(shù)據(jù),這時(shí)候我們向一張 只有50w行數(shù)據(jù)的table中insert數(shù)據(jù)后建立索引的時(shí)間就會(huì)呈數(shù)量級(jí)的下降,極大了提高了DB的運(yùn)行時(shí)效率,提高了DB的并發(fā)量。當(dāng)然分表的好 處還不知這些,還有諸如寫操作的鎖操作等,都會(huì)帶來(lái)很多顯然的好處。
綜上,分庫(kù)降低了單點(diǎn)機(jī)器的負(fù)載;分表,提高了數(shù)據(jù)操作的效率,尤其是Write操作的效率。 行文至此我們依然沒(méi)有涉及到如何切分的問(wèn)題。接下來(lái),我們將對(duì)切分規(guī)則進(jìn)行詳盡的闡述和說(shuō)明。
關(guān)于MySQL數(shù)據(jù)切分的相關(guān)概念和原理的知識(shí)就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!
【編輯推薦】
- Star Schema的設(shè)計(jì)思路與總結(jié)
- MySQL性能分析及explain的使用
- Oracle數(shù)據(jù)庫(kù)悲觀鎖與樂(lè)觀鎖詳解
- SQL Server多表查詢優(yōu)化方案總結(jié)
- Oracle執(zhí)行計(jì)劃不走索引的原因總結(jié)
名稱欄目:MySQL數(shù)據(jù)切分的相關(guān)概念和原理詳解
轉(zhuǎn)載來(lái)源:http://fisionsoft.com.cn/article/coijdjd.html


咨詢
建站咨詢
