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