數(shù)據(jù)庫(kù)專家:MySQL分片水很深
本文作者Peter Zaitsev是知名數(shù)據(jù)庫(kù)專家,2006年聯(lián)合創(chuàng)立了Percona。負(fù)責(zé)維護(hù)網(wǎng)站“MySQL性能”。同時(shí),他也是《高性能MySQL》一書的聯(lián)合作者。以下是他對(duì)MySQL分片的建議:
在與客戶討論分片決策的時(shí)候,我經(jīng)常會(huì)先給他們講下面這個(gè)真實(shí)的故事。
幾年前,有客戶來找我,希望獲得關(guān)于如何對(duì)系統(tǒng)分片的一些指導(dǎo)建議。他告訴我說,自從他知道很多應(yīng)用MySQL的巨頭(比如Facebook和Twitter)都在使用分片技術(shù)以后他就也想這么做。他們(這些巨頭)都是聰明人,所以很自然他也相信自己需要這么做。
我停了一會(huì)然后問他的數(shù)據(jù)庫(kù)有多大規(guī)模。
他說:“有10GB”。
我點(diǎn)頭表示理解,并繼續(xù)問他是否要處理許多查詢或者有很多非常復(fù)雜的查詢。
他回答說:“沒有。每秒鐘只有幾百個(gè)查詢,這些查詢給系統(tǒng)帶來的性能消耗只占很少的百分比。
我有問他是否預(yù)期在不遠(yuǎn)的未來數(shù)據(jù)量有指數(shù)級(jí)增長(zhǎng),比如每周數(shù)據(jù)量就會(huì)翻倍之類的情況。
“不會(huì)的。我們的負(fù)載和數(shù)據(jù)規(guī)模去年增長(zhǎng)了大約7%,我們預(yù)計(jì)今年乃至可預(yù)見的未來增長(zhǎng)率也差不多。”
我給他的建議是不要在分片上浪費(fèi)時(shí)間和精力了,因?yàn)樗镜那闆r需要的不是這個(gè)。
是否真的需要分片
在你決定如何分片之前,你***從一開始弄明白你是否真的需要分片。誠(chéng)然,在超大規(guī)模數(shù)據(jù)庫(kù)需求的情況下,分片是唯一的途徑。不只是對(duì)于MySQL,對(duì)大部分同類技術(shù)都是一樣。
然而,由于出現(xiàn)了很多新興技術(shù),越來越多的應(yīng)用都支持無需分片運(yùn)行數(shù)據(jù)庫(kù)?,F(xiàn)在,我們可以很輕松地在每個(gè)MySQL實(shí)例上運(yùn)行TB級(jí)數(shù)據(jù),并在許多OLTP環(huán)境下支持?jǐn)?shù)以萬計(jì)的查詢??梢娢覀兛梢詷?gòu)建非常龐大的應(yīng)用而無需分片。
我們應(yīng)該銘記:分片對(duì)所有環(huán)境都是不得已而為的做法。即便你使用的數(shù)據(jù)庫(kù)支持開箱即用的分片功能,那也會(huì)由于引入更多組件和復(fù)雜度而帶來麻煩。構(gòu)建良好的分布式查詢執(zhí)行計(jì)劃是非常復(fù)雜的任務(wù),需要考慮網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)和負(fù)載情況,另外還要考慮數(shù)據(jù)分布和每個(gè)獨(dú)立節(jié)點(diǎn)的負(fù)載。
在判斷是否需要分片之前,你應(yīng)該首先考慮是否有替代方法可以擴(kuò)展你的應(yīng)用。在MySQL的世界里,通常有以下一些方案可以考慮。
分片的替代方案
功能分區(qū):在許多環(huán)境中,單獨(dú)的MySQL實(shí)例變成了各種數(shù)據(jù)庫(kù)的傾銷之所。你可能最終讓你的主應(yīng)用與Drupal共享一個(gè)數(shù)據(jù)庫(kù)實(shí)例,用 WordPress增強(qiáng)你的站點(diǎn),用vBulletin增強(qiáng)你的博客,甚至論壇。把所有這些應(yīng)用碎片分入不同的數(shù)據(jù)庫(kù)實(shí)例是你首先應(yīng)該考慮的,而不是直接考慮分片??蛻舳ㄖ葡到y(tǒng)經(jīng)常有不同數(shù)據(jù)集的應(yīng)用,所以這個(gè)分法很容易實(shí)現(xiàn)。
復(fù)制:許多應(yīng)用都是“讀操作”的壓力大,而擴(kuò)展讀操作性能要比擴(kuò)展寫性能更容易一些。如果是這種情況,那么復(fù)制就是非常好的選擇。MySQL有自帶的復(fù)制功能非常健壯,雖然其異步特性增加了應(yīng)用的復(fù)雜性。這種情況下,開發(fā)人員必須判斷從哪臺(tái)復(fù)制服務(wù)器上讀取信息,不可以從哪里獲取。因?yàn)槟惚仨毥^對(duì)保證你讀取到的是***的實(shí)際數(shù)據(jù)。這也正是針對(duì)MySQL出現(xiàn)的可替代的異步復(fù)制技術(shù)廣受歡迎的原因(例如PerconaXtraDB)。這些工具把大部分集群環(huán)境下的功能提供給向單個(gè)數(shù)據(jù)庫(kù)操作的能力。
緩存和隊(duì)列:緩存是降低數(shù)據(jù)庫(kù)讀取量的出色技術(shù)。有許多應(yīng)用使用這種技術(shù)可以降低數(shù)據(jù)庫(kù)讀負(fù)載高達(dá)80-95%。與之相對(duì)的是隊(duì)列,它是用來優(yōu)化寫操作的。通過合并多次寫操作,提高了對(duì)數(shù)據(jù)庫(kù)操作的效率。大部分大型應(yīng)用都應(yīng)該重點(diǎn)考慮這兩種技術(shù)。Memcached和Redis是MySQL領(lǐng)域非常流行的兩種緩存技術(shù)。對(duì)于隊(duì)列,***的技術(shù)是ActiveMQ和RabbitMQ。
外部支持技術(shù):MySQL在很多方面都很出色,但也不是所有方面都強(qiáng)。如果你需要高性能全文檢索,應(yīng)該考慮ElasticSearch、Sphinx或者 Lucene。如果你想做大規(guī)模數(shù)據(jù)分析,可以考慮基于Hadoop的基礎(chǔ)架構(gòu)或者Vertica也是不錯(cuò)的選擇。你應(yīng)該讓MySQL處理它擅長(zhǎng)的事,把其它事留給外部支持工具來做。
分片之前應(yīng)該做的優(yōu)化
擴(kuò)展不只是針對(duì)架構(gòu)而言。你還需要確保你的系統(tǒng)經(jīng)過了合理的優(yōu)化。許多人決定采用分片其實(shí)不是真正必要的,雖然對(duì)于他們來說這是獲得性能提升更容易而且更有效的方式。我想說的是,如果分片最終也必須選擇的話,之前做的所有這一切優(yōu)化也仍然是有價(jià)值的。
硬件??紤]一下你使用的硬件合適嗎?我見過好多人在尋求分片方案,但事實(shí)上只要購(gòu)買其十分之一的硬件就能解決他們的問題,并保證在未來多年有效。如果你使用的數(shù)據(jù)庫(kù)比較大,請(qǐng)確保你有大量?jī)?nèi)存和高性能閃存。在許多情況下,它幾乎像變魔術(shù)一樣可以極大地提升你的系統(tǒng)。
MySQL版本和配置。建議使用***的MySQL版本。我指的是***的GA版本(本文發(fā)布時(shí)***版本是MySQL 5.6)。Percona Server是免費(fèi)的,它通??梢詾樾枰呢?fù)載提供額外的性能提升。同樣也推薦采用***版本的操作系統(tǒng),尤其是如果你使用的是***的硬件時(shí)更需如此。***,確保MySQL配置合適。MySQL配置好壞會(huì)導(dǎo)致其性能的天壤之別,性能差距可能會(huì)達(dá)到十倍甚至更多。
模式與查詢。相同的應(yīng)用邏輯可以由多重模式和查詢來表達(dá)。我見過有許多類似的應(yīng)用采用不同的方法來實(shí)現(xiàn),采用優(yōu)化方法和性能糟糕的方法(確實(shí)應(yīng)用于生產(chǎn)環(huán)境了)其性能差異可能達(dá)到一百倍甚至更多。許多修改可能會(huì)調(diào)整現(xiàn)有結(jié)構(gòu)模式,比如對(duì)索引結(jié)構(gòu)的微小調(diào)整。然而,如果你的結(jié)構(gòu)不能很好適合你的應(yīng)用需求,那么你需要的可能是重新設(shè)計(jì)。因此,盡早開始考慮問題是很有必要的。
何時(shí)考慮分片
那么我們什么時(shí)候可以開始考慮分片呢?一般來講,如果以上列舉的方法都不能令你獲得滿意的性能,那么就是時(shí)候考慮分片了。分片確實(shí)有使用低成本硬件或者更廉價(jià)的云實(shí)例獲得潛在性能的優(yōu)勢(shì)。
當(dāng)今的大部分開發(fā)者們都在使用敏捷開發(fā)方法,有一種通用的說法叫“架構(gòu)跑道”,它說明了應(yīng)用基于當(dāng)前架構(gòu)可以發(fā)展多遠(yuǎn)。如果你已經(jīng)使用復(fù)制獲得了成功,那么再使用分片可能是一種糟糕的選擇,因?yàn)樗鼤?huì)強(qiáng)迫開發(fā)人員處理分片和異步復(fù)制的復(fù)雜性。然而,盡管你已經(jīng)使用了分片,復(fù)制通常仍然會(huì)用于獲得更高的可用性,但是這種情況下就不只是未來擴(kuò)展讀能力了。
如果你已經(jīng)確信到了必須做分片的地步,那么下面這些問題你可以自查一下,都是關(guān)于如何實(shí)施分片策略的。
分片層次:我們應(yīng)該在哪個(gè)層次上做分片呢?分片并不是必須在數(shù)據(jù)庫(kù)層面上做的。許多應(yīng)用(尤其是SaaS)經(jīng)常在更高層次上做分片,可以部署完整應(yīng)用堆的多份副本實(shí)現(xiàn)完全獨(dú)立的可用性、性能、安全等等。在許多大型擴(kuò)展應(yīng)用中你會(huì)看到許多完整的副本,每份副本都有其各自的分片MySQL環(huán)境。
分片關(guān)鍵:我們?nèi)绾芜M(jìn)行分片?在許多情況下,選擇的方案取決于你是否對(duì)用戶賬號(hào)或者你的組織做了認(rèn)證,但是也有一些情況下并不是那么明顯。在選擇分片方案的時(shí)候,你需要考慮兩件事:1)要讓盡可能多的數(shù)據(jù)訪問點(diǎn)安排在一起,因?yàn)榭绶制L問代價(jià)很昂貴(而且前提是支持的情況下);2)確保要做的分片方案不會(huì)產(chǎn)生新的分片,也就是說新的分片不能太大以至于不能處理相關(guān)數(shù)據(jù)規(guī)模或者訪問量。例如,按國(guó)家分片就不是一個(gè)好主意,因?yàn)樘幚肀壤麜r(shí)的訪問量和處理美國(guó)或者中國(guó)的訪問量絕對(duì)不是等同的,后者要更多的資源。
模式或者實(shí)例共享:你做分片的粒度是什么呢?一般的選擇是MySQL實(shí)例或者數(shù)據(jù)庫(kù)(模式)。我喜歡對(duì)數(shù)據(jù)庫(kù)分片的方式,因?yàn)樗粫?huì)限制每個(gè)物理節(jié)點(diǎn)只能有一個(gè)MySQL實(shí)例。這種方式不必運(yùn)行太多MySQL實(shí)例,但是如果應(yīng)用在這種情況下運(yùn)行更好,你可以運(yùn)行更多實(shí)例。
分片單元:如果你按每個(gè)獨(dú)立的MySQL服務(wù)器做分片,你很快會(huì)遇到高可用性的問題。如果你有一百臺(tái)MySQL服務(wù)器,相比于只有一臺(tái)的情況,發(fā)生故障的概率大概達(dá)到一百倍。因此確保實(shí)現(xiàn)高可用性的解決方案就成為了關(guān)鍵。處理針對(duì)MySQL服務(wù)器節(jié)點(diǎn)做分片,我們通??梢园磸?fù)制集群節(jié)點(diǎn)做分片(比如一臺(tái)作為MySQL主節(jié)點(diǎn),另一臺(tái)或多臺(tái)作為復(fù)制服務(wù)器或者PXC,即Percona XtraDB集群)。
分片技術(shù):你計(jì)劃采用什么技術(shù)幫助實(shí)現(xiàn)分片呢?在MySQL的世界中,沒有通用的分片技術(shù)適合于所有人使用。大部分大型web站點(diǎn)都根據(jù)他們自己的分片需求實(shí)現(xiàn)一定的定制,其中一些已經(jīng)把它們的解決方案發(fā)布為開源項(xiàng)目。Vitess就是一個(gè)例子,它是由谷歌公司貢獻(xiàn)的。另一個(gè)例子是JetPants,是由 Tumblr公司貢獻(xiàn)的。推出我們自己的分片框架在一些開發(fā)人員看來貌似容易,但一般都會(huì)遇到一些難以處理的實(shí)際問題,比如平衡分片、更大規(guī)模下的再分片等。有許多專門用途的技術(shù)可以幫助實(shí)現(xiàn)分片,它們可能與你的團(tuán)隊(duì)現(xiàn)在管理分片的方式不同。
分片技術(shù)
這里列出了一些技術(shù)你可以參考。
MySQL Fabric:這是Oracle公司的MySQL團(tuán)隊(duì)開發(fā)的分片技術(shù)。MySQL Fabric是GA版本,但是目前它的功能還相當(dāng)有限,尤其是在支持多分片查詢方面。不過,如果再多經(jīng)過一段時(shí)間,它有潛力成為MySQL的標(biāo)準(zhǔn)分片技術(shù)。
Tesora:Tesora為MySQL分片技術(shù)提供了基于代理的解決方案,前段時(shí)間它已開放源代碼。如果你考慮部署OpenStack,我特別推薦Tesora,因?yàn)樗麄冊(cè)诩煞矫嫱度肓撕芏唷?/p>
ScaleArc:ScaleArc是商業(yè)數(shù)據(jù)庫(kù)代理解決方案,可以實(shí)現(xiàn)緩存、過濾、路由和分配。它是相當(dāng)成熟的解決方案了,可以處理多種數(shù)據(jù)庫(kù)而不只是MySQL。
ScaleBase:ScaleBase是專門為MySQL和云計(jì)算設(shè)計(jì)的一種分配解決方案,與MySQL類似,運(yùn)營(yíng)在代理層面。
在MySQL領(lǐng)域還有許多技術(shù)可以在無需分配的情況下擴(kuò)展你的應(yīng)用。不過,如果你打算成為下一個(gè)“Facebook”,那你是得考慮分片了。也有許多技術(shù)可以幫助你盡可能無痛地實(shí)現(xiàn)分片。以大規(guī)模數(shù)據(jù)庫(kù)為基礎(chǔ)的大型應(yīng)用總會(huì)帶來復(fù)雜度,針對(duì)這種應(yīng)用做開發(fā)和管理是更復(fù)雜的是。付出才會(huì)成功。