我不想 MySQL 分片

語言: CN / TW / HK

Daniel Nichter 是《高效 MySQL 效能》( Efficient MySQL Performance )一書的作者,該由 O’Reilly 出版,目前尚無中譯版本。Nichter 在本文中又對書中第五章中關於分片的問題進行了討論。

《高效 MySQL 效能》( Efficient MySQL Performance )第五章論述了分片問題,這個問題很難寫,但並不是因為技術原因。關於這一問題,讓我多說幾句。

我的誤解

這是我從第五章中刪除的一段話和腳註:

然而,橫向擴充套件並不是關係型資料儲存的固有特性。這是歷史原因導致的:關係型資料模型創建於 20 世紀 70 年代,當時由於硬體體積龐大且價格昂貴,所以橫向擴充套件是不可能的。簡單地說,關係型資料庫不是為橫向擴充套件而設計的。_{[1]}因此,橫向擴充套件關係型資料儲存需要一個外部過程:分片。

_{[1]}儘管關係型資料庫不是為了橫向擴充套件而設計的,但這既不是對其的批評,也不是它的缺陷,關係型模型在過去 40 多年裡的流行程度不僅令人難以置信,並且毫無疑問,它已經成為技術和網際網路不可或缺的一部分。

我刪除了這一段(以及腳註),原因是其中有誤導或錯誤,正如 Fernando Ipar(我的技術審稿人之一)指出的那樣:

最好能找出一種方式(在這裡或在現有的腳註上)來表達。嚴格來說,關係模型是一種邏輯模型,與物理層沒有任何關係。這麼說可能讓人有點惱火,但以本人愚見,如果說關係模型不能擴充套件,那是因為我們已經達到了特定關係(或者更準確地說是受關係啟發的)產品的極限。那就像是在說,由於你的嘗試操作在特定型號的計算器造成了計算溢位,就斷言算術無法擴充套件。區別就是為什麼其他資料庫有可能在支援分片的情況下,同時支援一些關係特性,並且對使用者的透明程度要超過 MySQL(比如 ockroachDB、TiDB,甚至 MySQL Cluster)。我認為澄清這個問題的一個很好的建議就是《深度探索關係資料庫》( Database in Depth ,C.J. Date 著,由 O'Reilly 於 2005 年出版) 一書中第一章《模型與實施》( Model Versus Implementation )的內容。

事實上,這是 Data 在這本書第一章中的相關陳述(強調是我的觀點):

首先要知道, 效能,歸根結底是實現的問題 ,而非模型問題——儘管存在著極其普遍的、與之相反的誤解。比如,我們經常被告知“連線很慢”,但這樣的說法毫無任何意義!連線(JOIN)是模型的一部分,而模型自身也不能稱之為“快”或“慢”;只有“實現”可以說具有這樣的特性。因此,我們可以這樣說,某些特定產品 X 的連線實現比另一些特定產品 Y 更快或更慢,但也僅此而已。

我經常有 Date 和 iPar 所說的誤解,如果不是 iPar 糾正我的話,我差點也會把同樣的想法付諸印刷。更糟糕的是,我實際上還陳述了兩個有些矛盾的理由:

  1. 關係型資料模型創建於 20 世紀 70 年代,當時由於硬體體積龐大且價格和昂貴,所以橫向擴充套件是不可能的。

  2. 關係型資料庫不是為了橫向擴充套件而設計的。

從表面上來看,這不是一個明顯的邏輯錯誤,但它是錯誤的:1 是真的,但 2 並不是由 1 得出的。

誠然,從 20 世紀 70 年代一直到 21 世紀初,硬體體積都很龐大且價格昂貴(與今天的情況相比)。因此,企業不可能隨心所欲地提供 100 個新資料庫。(作為參考,亞馬遜 EC2 於 2006 年釋出。)採購任何伺服器就如同購買一輛汽車:一項謹慎而又代價高昂的決策,打算擁有並持續運營數年之久。需要更多的容量?擴大現有伺服器的規模:更多的記憶體,更大的硬碟,諸如此類。還需要更多的容量?那就購買“更大”的伺服器:支援更快的 CPU,更多的 RAM 晶片,更多的硬碟托架,諸如此類。

但是,“關係型資料庫不是為了橫向擴充套件而設計的”這一說法並不正確。我不應該加上這句話,因為這正是 Date 在他書裡第一章抨擊的誤解,這有充分的理由。引用 Date 的話:效能從根本上說是一個實現問題,而不是一個模型問題。規模是效能的一部分。

我們能避免分片嗎?

現在是 2022 年 5 月,1 TB 的記憶體是存在的,但遠非常態。最大的亞馬遜雲科技 RDS 例項型別是 db.x1e.32xlarge ,具有 3904 GB 記憶體,幾乎 4 TB。這令人印象深刻,但是我不想這樣:我希望它是 2022 年的規範。

如果 TB 級的記憶體是常態,那麼單個 MySQL 例項就有望能夠處理幾十 TB 的資料。我之所以強調“可能”,是因為儘管記憶體在避免分片時起著至關重要的作用,但它並不是唯一的因素。有時候,為了擴充套件寫操作,需要進行分片。在這種情況下,儲存 I/O 和延遲就成了更關鍵的因素。一些插到 PCIe 插槽的 NVMe 系統具有令人難以置信的效能,但就像 TB 級的記憶體一樣,它們遠非常態。即使記憶體和儲存 I/O 解決了問題,那麼網路傳輸速度呢?以 10Gbps 的速度傳輸 10TB 需要大約 2 小時。有更快的網速,但它們現在也還不是常態。

不要忘記模式遷移(OSC)和其他資料操作。目前,MySQL 只有兩個 OSC 工具:pt-online-schema-change 和 gh-ost。這兩者都可以處理 TB 級的資料,但都沒有真正地優化速度或並行性,所以 TB 級的資料需要花上很多小時才能改變。

我認為,目前使用 MySQL(或其他類似的關係型資料庫)是不可能避免分片的,原因是資料的增長速度已經遠遠超過了 MySQL 的硬體和工具。在過去的 20 年裡,MySQL 做了很好的工作,但我認為,由於普遍可用的(和可負擔得起的)硬體和工具,它已經接近了一個軟極限。現在,我想這個軟極限是 10TB 的資料——具有有利的(即輕量級)訪問模式,較小的工作集大小,以及相對穩定的模式(或一個真正有耐心的團隊/公司)。

資料增長與雲端計算

資料量不斷增加。即使不在技術領域內,人們也知道數年前的裝置能夠儲存 5GB 的資料,而現在可以儲存 256GB。iPod 就是一個例子:人們意識到“我可以儲存更多的資料”。(這個例子很及時,因為蘋果公司的 iPod 在 20 年才停產)。讓我們姑且假定這種長期存在的趨勢是合理的,而不是由於資料膨脹或浪費。(我個人覺得,我們對資料的浪費是非常嚴重的,這就是為什麼我在《 高效 MySQL 效能 》的第三章和第四章中詳細闡述了這個問題)。

自從計算機出現以來,硬體的容量就在迅速增加(而成本在下降),這在技術領域也是廣為人知的。因此,它跟上了資料增長的步伐,以至於不需要改變正規化:只要繼續購買更大的硬體(因為它變得更低廉),問題就解決了。這就是舊的正規化:擴充套件你已經擁有的硬體規模。我只是泛泛而談,總是有一些例外。

但近年來,有四件事發生了變化:

  1. 硬體容量的增長略微滯後。

  2. 資料的增長顯著增加。

  3. 雲變得普遍。

  4. 發明了編排。

第 1 點說得很謹慎,因為硬體容量肯定一直在增加;第 2 點才是掩蓋了第 1 點的主要變化,並使之複雜化。資料增長很容易爆炸,因為產生資料很容易。在市場上開發和推廣硬體要困難得多(而且緩慢),因為大的變化需要其他新的硬體(例如從 SATA 到 PCIe)、新的核心和驅動程式,以及能夠充分利用前面提到的新應用。

資料飛速增長,硬體也在努力追趕,雲(第 3 點)在 2006 年亞馬遜 EC2 推出時悄無聲息地出現。但是,雲實際上不過是另一個你租用而不是擁有的伺服器。這意味著,亞馬遜雲科技(和其他雲廠商)在幕後所使用的硬體和你可能原本計劃購買的一樣。(這不再是實際情況了,有些雲廠商定製了他們自己的硬體)。

但云還是很有用的,因為它提供了一個抽象層,隱藏了採購和管理硬體的複雜性。人們經常使用“彈性”這個詞:雲中的計算資源具有彈性。這意味著你能夠持續地將更多的資料儲存到雲端中,而無需過多關注其執行方式。

從這個角度來說,雲是一個重大的演變,因為在雲之外,真正的挑戰不在於“我可以買一個足夠大的硬碟嗎?”(你可以),而在於“我可以以多快的速度採購和配置硬體,以及它可以持續多久?”公司不可能(也不會)每年不顧一切地購置新硬體。

相反,他們會計劃、預算、購買、等待、接收、“上架”,最後(有時是幾個月後)讓新硬體上線。鑑於這種努力,公司要求硬體工作多年以徹底收回投資。這就是公司難以與爆炸性增長的資料保持同步的原因。但是,雲改變了這一點。它抽象化了採購和管理硬體的複雜性:你只要按需租用你所需的任何東西就可以了。

雲對於改變這種正規化來說是必要條件,但還並不夠。你可以提供所有你想要的資源,但是如果你這麼做了,你又會遇到另外一個問題:如何放養這些傳說中的貓?這句話的意思是:你可以提供一個資源叢集,但你如何控制並管理它?

在 2013 年和 2014 年,Docker 和 Kubernetes 相繼問世。這些都是容器化的技術(以及延伸到微服務),但它們都是使編排大規模的雲資源叢集變得可行的最終必需。所以,我們現在能夠用程式設計方式(而且有點容易)來提供並編排幾乎無限的雲資源,並以“彈性”方式(通常是建立和銷燬並重新建立資源)。

現在正規化已經改變了,因為在雲中,實際上沒有任何限制;這只是一個你能負擔得起的問題。籠統地說,新的正規化是:“只要在雲中擴充套件規模”。(其中“只要”一詞意味著,考慮到編排工具,這應該是很容易的,但“容易”這個詞顯然是高度相對的。)

新正規化中的 MySQL

回到 MySQL,圍繞它的正規化已經發生了改變。

一方面,我們有像 MySQL 這樣的關係型資料庫,這些資料庫是在正規化改變之前很久就建立了——當時的正規化仍然是“擴大規模”:購買更大、更快的硬體。我認為對於 2000 年以後出生的工程師來說,瞭解這段歷史很重要。

MySQL、Postgres 和類似的產品是在雲或 Kubernetes 之前很久就問世了。在那時, 無論你想要多少資源, “啟動”的想法根本不可能。標準是擴大你已經擁有的資源,因為公司不願意也不喜歡購買新硬體。這就是為什麼 MySQL 在擴充套件方面非常出色,但卻不能原生橫向擴充套件的部分原因(為什麼需要分片)。

另一方面,現代軟體開發正在轉向新正規化,在新正規化幾乎沒有資源限制:只要為你想要的大小/規模配置 Kubernetes(或任何編排工具),它(通常)就會提供任何需要的東西。(說“通常”是因為,如果你不知道,雲有時確實會暫時耗盡資源)。

不足為奇的是,開發人員希望他們的資料庫也可以做到這一點,但發現他們無法使用 MySQL、Postgres 和其他類似的資料庫。這可如何是好?

NewSQL 與創新者的困境

我們越來越多地看到 NewSQL 資料儲存,它將資料庫的計算層和儲存層分開,這樣就可以通過編排在雲中進行橫向擴充套件。考慮到正規化的變化,這樣做是有意義的;考慮到硬體和工具沒有保持在資料增長曲線的前面,這也是有意義的。

例如,如果有硬體和工具可以輕鬆處理單個 100TB 的 MySQL 例項,那麼 NewSQL 很可能就不會有市場。但目前情況並非如此。因此,為了使 MySQL 達到一定規模,開發人員必須實施和維護應用級分片,或者轉向 NewSQL。

雖然分片已經被證明是行之有效的(關於 MySQL 分片已經有了很多知識和成功案例),但這仍然是一項非開發任務,開發人員經常告訴我他們不想做。

我不能責怪他們:他們被僱來開發應用程式的功能——而我被僱來為他們擴充套件資料庫。(當然,我希望他們不要再這麼浪費資料了,不過我要這麼說就是跑題了。)

我認為我們正在見證“ 創新者的困境 ”。單一例項上的 SQL 是現任者:一個巨大的價值網路,它紮根於四十年的成功經驗。NewSQL 是一家顛覆性的小微初創企業,目前正致力於解決一個利基問題,而且它似乎沒有佔據主要的市場份額(小的價值網路)。NewSQL 有可能取代現任者,包括 MySQL,特別是當 TiDB 等產品明確地與 MySQL 相容,以進入現任者的價值網路時。

而毫不奇怪的是,NewSQL 的一個障礙是成本。NewSQL 資料庫更為複雜,這需要更多的雲資源,而且成本也更高。但我們也看到了這種情況:隨著顛覆者市場份額的增加,成本也會下降。

題外話:Vitess 和類似產品並不是顛覆者:它們是現有價值網路到新價值網路的橋樑。如果真正的顛覆者獲勝,這些橋樑就將慢慢消失。

那麼,重點是什麼?

對 MySQL 進行分片仍然是必要的,因為我們還處於一個不確定的時期,還不知道怎麼可以避免分片:要麼是負擔得起的硬體容量大爆發(這實際上只是提供了更多的跑道,將問題進一步推向未來),要麼是 NewSQL 成功顛覆了傳統 SQL,成為主流。

似乎符合邏輯的是,在未來,軟體工程師將不必處理應用級別的分片,因為那並不是他們真正的工作,而且 NewSQL 已經證明它不需要存在。這就是為什麼我個人認為 NewSQL 會獲勝,但是至少需要 5 年時間,更現實的是 10 年。

不過不用擔心,MySQL 和其他單例項關係型資料庫將在更長時間內繼續發揮重要作用,以至於今天學習 MySQL 幾乎是必需的,因為它無處不在。

原文連結:

http://hackmysql.com/post/book-5/