資料庫毀了所有好主意 - squarism

banq發表於2021-07-18

本文假設是一個三層網路堆疊。它有很多 Web 和應用程式伺服器,但只有一個資料庫框。你可以用雲來代替它,但原理是一樣的。我敢打賭你的基礎設施看起來非常相似。對於本文的其餘部分,假設我說的資料庫是指傳統的 RDMS。
為什麼資料庫總是一個?
我們可以總結在整個堆疊中擴充套件每一層,如下所示:
  • 客戶端:不是我們能左右干預的問題,會有數以百萬計的客戶端
  • web 層:easy-peasy,它是一個守護程式加上一個配置檔案
  • 應用層:這是我們的程式碼/東西;它在負載均衡器池中,即使它有狀態我們也有擴充套件它的技巧
  • 資料庫層:不要碰它!只有一個!

 除了資料庫之外,每一層都很容易理解橫向擴充套件。這裡發生了什麼?我將討論一些好主意以及它們為什麼會死在資料庫層上。
  

讓我們負載平衡?
負載均衡器池非常適合沒有狀態的層。當您需要有某種狀態時,您可以使用諸如粘性會話session之類的技巧。但生命週期很短。儲存這些狀態在資料庫不是好的想法,因為連線很長而且整個狀態都只是本地的,只與某個客戶端有關,如果客戶端成千百萬會消耗很多資料庫空間。您不能將資料庫卷放在共享驅動器上並期望它工作(很好)。所以問題至少是有關狀態的。
 

讓我們DOCKERIZE?
Docker 非常適用於沒有狀態的層。您可以對資料庫進行 dockerize,但無法獲得其他層的可擴充套件性和一致性優勢。Docker 非常適合生產和部署,但您通常不會在沒有很多花哨的正常執行時間工具的情況下部署資料庫。
關於 dockerizing 其他層的話題和爭論很少。Dockerizing 資料庫層可以爭論。
 

讓我們多主雙活?
水平擴充套件不適用於資料庫層。您不能輕易擁有讀/寫(活動)對。有替代的守護程式和方法 (NewSQL),但這裡我指的是常見的關係 SQL 資料庫。
 

讓我們做不可變或配置管理?
NixOS 呢?或者其他一些熱門和時尚的新想法?當我聽說 NixOS 時,我的第一個擔憂和問題是關於資料庫層。我問過這個關於 NixOS 的問題,顯然可以這樣做。但是,我並不完全理解這一點,但我想這是我觀點的一部分。資料庫層又是一個特例。
 

讓我們模擬測試我們的資料庫?
在單元測試期間,只能模擬測試應用伺服器。那麼為什麼人們不能測試資料庫?
你可以在 Python 中找到 fakeRedis 介面卡,在 Ruby 中找到假快取,在 C# 中找到記憶體資料庫。但這一切都被警告所包圍。建立測試資料庫更容易,因為資料庫會破壞所有好的想法。
關聯式資料庫中有如此多的狀態和來回協議,將其視為客戶端/伺服器訊息傳遞太簡單了。所有的狀態和資料都存在於資料庫中。即使是觸發器和內部結構也太複雜而無法解釋。建立測試資料庫更容易,因為資料庫名稱空間/集合非常容易建立。資料庫還具有在事務中回滾的優勢,這對於單元測試非常多餘。
  

讓我們使用雲?
租用大箱子通常在經濟上沒有意義。上面的資料庫縮放和池化問題不會改變。即使是 SaaS 也有同樣的問題。在這種情況下,奇異一個資料庫盒子只是移動到雲中而已。
 

一個可怕的故事
很久以前,我在一個需要大量專業軟體、硬體、管理和配置的 Oracle 叢集上工作。幾乎整個想法都是關於可用性和效能的。CEO 無法忍受系統的一半因為只讀而浪費金錢。他想在兩個節點上讀寫:多主雙活。這是很久以前的事了,但 CAP定理 是無法被改變的。我主要是透過這些創傷學到了很多關於裂腦的知識。
當時,您不能只下載一個可以進行水平擴充套件的關聯式資料庫。您必須購買所有這些供應商選項和東西。這是超級昂貴的。我忘記了價格,db 許可證可能是 4 萬美元,叢集外掛可能是 2 萬美元。然後您需要專門的磁碟和卷軟體。硬體也非常昂貴,因為當時是 Sun公司的。
在叢集安裝期間,它會告訴您將交叉電纜插入專用 NIC。就像,你有 eth1 只是免費坐在那裡,或者你必須為它購買 NIC。我想我們買了一個網路卡。除非您執行此交叉操作,否則安裝將無法進行。此外,您需要在 SAN 上設定仲裁磁碟以充當決勝局(稍後會詳細介紹)。這條交叉電纜上的所有流量都是 SSH。它所做的只是透過 SSH 進行關聯式資料庫協議。您無需進行資料分片或拆分,所以要麼全有要麼全無。始終完整的 ACID 協議。這就是為什麼由於網路負載而需要專用 NIC 的原因。
所以你終於擊敗了 CAP 理論。你有你的雙活Active-Active資料庫,你根本不需要改變你的應用程式。
現在到了權衡,魔鬼的細節:ACID 意味著我們必須 100% 及時同步每次查詢。這意味著所有節點上同步資料,這就是擴充套件節點如此糟糕的原因。您在第二個節點上獲得了大約 50%同步資料,然後在第三個節點上獲得了 +25%。它在第4個之後酒停止擴充套件。請記住,每個節點都非常昂貴。此外,您的神經系統就如同這條交叉電纜(實際上是一對)。如果我拿剪刀剪它會怎樣?
好吧,db01 認為它已經完成。db02 認為它已經結束。但是 db02 認為 db01 不見了。db01 認為 db02 不見了。那麼現在怎麼辦?如果寫入同時進入 db01 和 db02,會發生什麼情況?

db01:  foo=bar
db02:  foo=ohno

foo 應該是什麼? 裂腦!
這就是您配置仲裁磁碟的原因。當叢集失去仲裁時,就會出現仲裁磁碟的競爭。它在磁碟扇區的開始處寫入一個幻數(甚至不像在磁碟 iirc 的正常部分),無論誰到達第二個,都會引起恐慌。現在你已經從腦裂中倖存下來了。但是出於任意原因,您甚至需要瘋狂的共享磁碟技術才能做到這一點。
那是一段瘋狂的時光,我應該在稍後的某個時候分享這一點,因為這是在製作一部恐怖片。這個故事中的很多技術都非常古老。但有些現在還沒有改變。當我學習 Mongo 時,我從這種恐怖中獲得了高度的背景知識,我不必經常問“是的,但為什麼”。
回到過去,我們的 CEO 無法忍受讓一半的硬體無所事事。他想讓它參與進來。這不是一個“愚蠢的想法”。這是個好主意!很多人對資料庫有很好的想法。
不過對我來說,資料庫毀了所有的好主意。


 

相關文章