Clustering

為什麼 RDBM 的集群不能像 NoSQL 那樣?

  • September 5, 2018

nosql DBMS 的一大優點是它們可以更輕鬆地進行集群。假設使用 NoSQL,您可以創建數百台廉價的機器來儲存不同的數據並同時查詢所有數據。

我的問題是,為什麼關係型 DBMS 不能像 mysql 或 sql server 那樣做呢?是供應商只是還沒有找到一種技術方法來使用他們現有的產品來做到這一點,還是關係模型存在一些問題,阻止了這種做法的可行性?NoSQL 儲存和訪問數據(鍵/值、文件等)的方式有什麼好處,它使集群更容易,如果這是真的的話?

分佈式數據庫系統 101

或者,分佈式數據庫 - FK 的“網路規模”實際上是什麼意思?

分佈式數據庫系統是複雜的生物,有許多不同的風格。如果我深入了解我在大學時對這方面的記憶模糊的研究,我將嘗試解釋建構分佈式數據庫系統的一些關鍵工程問題。

一、一些術語

ACID(原子性、一致性、隔離性和持久性)屬性:這些是必須強制執行的關鍵不變數,以使事務能夠可靠地實現而不會導致不良的副作用。

原子性要求事務完成或完全回滾。部分完成的交易不應該是可見的,並且系統必須以防止這種情況發生的方式建構。

一致性要求事務永遠不應違反數據庫模式所保證的任何不變數(例如聲明性引用完整性)。例如,如果存在外鍵,則應該不可能插入對不存在的父項表示敬意的子記錄。

隔離要求事務不應相互干擾。如果事務並行或順序執行,系統應保證相同的結果。在實踐中,大多數 RDBMS 產品都允許在隔離與性能之間進行權衡。

持久性要求一旦送出,事務以一種對硬體或軟體故障具有強韌性的方式保留在持久儲存中。

我將在下面解釋這些要求在分佈式系統上存在的一些技術障礙。

共享磁碟架構:集群中的所有處理節點都可以訪問所有儲存的架構。這可能會成為數據訪問的核心瓶頸。共享磁碟系統的一個範例是Oracle RACExadata

無共享架構:集群中的處理節點具有對其他集群節點不可見的本地儲存的架構。無共享系統的範例是TeradataNetezza

共享記憶體架構:多個 CPU(或節點)可以訪問共享記憶體池的架構。大多數現代伺服器屬於共享記憶體類型。共享記憶體有助於某些操作,例如記憶體或原子同步原語,這些操作在分佈式系統上更難完成。

同步:一個通用術語,描述了確保多個程序或執行緒對共享資源進行一致訪問的各種方法。這在分佈式系統上比在共享記憶體系統上更難做到,儘管一些網路架構(例如 Teradata 的 BYNET)在網路協議中有同步原語。同步也可能帶來大量成本。

半聯接:用於聯接分佈式系統的兩個不同節點中保存的數據的原語。本質上,它包含有關要連接的行的足夠資訊,這些資訊被捆綁並由一個節點傳遞給另一個節點以解決連接問題。在大型查詢中,這可能涉及大量網路流量。

最終一致性:用於描述事務語義的術語,該術語在分佈式系統的所有節點上權衡立即更新(讀取的一致性)以換取寫入的性能(因此更高的事務吞吐量)。最終一致性是使用Quorum Replication作為性能優化來加速分佈式數據庫中的事務送出的副作用,

Lamport 算法:一種用於在沒有共享記憶體的系統之間實現互斥(同步)的算法。通常,系統內的互斥需要原子讀取-比較-寫入或類似類型的指令,該指令通常僅在共享記憶體系統上實用。存在其他分佈式同步算法,但 Lamport 是最早的算法之一,也是最著名的算法。與大多數分佈式同步機制一樣,Lamport 的算法在很大程度上依賴於集群節點之間的準確定時和時鐘同步。

兩階段送出 (2PC):確保涉及多個物理系統的數據庫更新一致地送出或回滾的一系列協議。無論 2PC 是在一個系統內使用還是通過事務管理器跨多個系統使用,它都會帶來很大的成本。

在兩階段送出協議中,事務管理器要求參與節點以這樣一種方式保持事務,即它們可以保證它將送出,然後發出此狀態的信號。當所有節點都返回“快樂”狀態時,它會向節點發出信號以送出。該事務仍然被認為是打開的,直到所有節點都發送一個表示送出完成的回复。如果一個節點在發出送出完成的信號之前關閉,事務管理器將在它恢復時重新查詢該節點,直到它得到一個表明事務已送出的肯定回复。

多版本並發控制 (MVCC):通過將新版本的數據寫入不同的位置並允許其他事務查看舊版本的數據,直到送出新版本來管理爭用。這減少了數據庫爭用,但會犧牲一些額外的寫入流量來寫入新版本,然後將舊版本標記為過時。

選舉算法:涉及多個節點的分佈式系統本質上不如單個系統可靠,因為存在更多故障模式。在許多情況下,集群系統需要某種機制來處理節點故障。選舉算法是一類算法,用於在“領導者”節點不是 100% 確定或不可靠的情況下選擇領導者來協調分佈式計算。

水平分區:一個表可以通過其鍵跨多個節點或儲存捲進行拆分。這允許將大數據量拆分為較小的塊並分佈在儲存節點上。

分片:數據集可以在無共享架構中的多個物理節點上水平分區。在這種分區不透明的情況下(即客戶端必須知道分區方案並確定要顯式查詢哪個節點),這稱為分片。一些系統(例如 Teradata)會跨節點拆分數據,但位置對客戶端是透明的;該術語通常不與此類系統一起使用。

Consistent Hashing:一種用於根據密鑰將數據分配到分區的算法。它的特點是雜湊鍵分佈均勻,並且能夠有效地彈性擴展或減少桶的數量。這些屬性使其可用於跨節點集群分區數據或負載,其中大小可以隨著節點的添加或從集群中刪除(可能是由於故障)而動態變化。

多主複製:一種允許跨集群中多個節點的寫入複製到其他節點的技術。這種技術通過允許一些表在伺服器之間進行分區或分片,而其他表在集群中同步來促進擴展。寫入必須複製到所有節點而不是仲裁,因此事務送出在多主複製架構上比在仲裁複製系統上更昂貴。

非阻塞交換機:一種網路交換機,它使用內部硬體並行性來實現與埠數量成正比的吞吐量,而沒有內部瓶頸。一個簡單的實現可以使用交叉開關機制,但這對於 N 個埠具有 O(N^2) 複雜性,將其限制為較小的交換機。較大的交換機可以使用更複雜的內部拓撲(稱為非阻塞最小跨接交換機)來實現線性吞吐量擴展,而無需 O(N^2) 硬體。

製作分佈式 DBMS - 有多難?

一些技術挑戰使這在實踐中很難做到。除了建構分佈式系統的額外複雜性之外,分佈式 DBMS 的架構師還必須克服一些棘手的工程問題。

**分佈式系統上的原子性:**如果事務更新的數據分佈在多個節點上,則必須協調節點的送出/回滾。這增加了無共享系統的顯著成本。在共享磁碟系統上,這不是一個問題,因為所有節點都可以看到所有儲存,因此單個節點可以協調送出。

**分佈式系統的一致性:**以上面引用的外鍵範例為例,系統必須能夠評估一致的狀態。例如,如果外鍵關係的父子關係可能駐留在不同的節點上,則需要某種分佈式鎖定機制來確保不使用過時的資訊來驗證事務。如果不強制執行此操作,您可能會有(例如)一個競爭條件,其中在允許插入子項之前驗證其存在後刪除父項。

約束的延遲執行(即等待直到送出驗證 DRI)需要在事務期間保持鎖定。這種分佈式鎖定會帶來很大的成本。

如果保存了多個數據副本(這在無共享系統上可能是必要的,以避免來自半連接的不必要的網路流量),則必須更新所有數據副本。

**分佈式系統上的隔離:**在事務上受影響的數據駐留在多個系統節點上時,鎖和版本(如果正在使用 MVCC)必須跨節點同步。保證操作的可串列性,特別是在可能儲存冗餘數據副本的無共享架構上,需要分佈式同步機制,例如 Lamport 算法,這也帶來了網路流量的大量成本。

**分佈式系統的持久性:**在共享磁碟系統上,持久性問題與共享記憶體系統基本相同,不同之處在於仍然需要跨節點的分佈式同步協議。DBMS 必須記錄寫入日誌並一致地寫出數據。在無共享系統上,可能有多個數據副本或部分數據儲存在不同節點上。需要一個兩階段送出協議來確保送出在節點之間正確發生。這也會產生很大的成本。

在無共享系統上,節點失去可能意味著系統無法使用數據。為了緩解這種情況,數據可能會在多個節點上複製。這種情況下的一致性意味著必須將數據複製到它通常所在的所有節點。這可能會導致寫入的大量成本。

在 NoSQL 系統中進行的一項常見優化是使用仲裁複製和最終一致性來允許數據被延遲複製,同時通過在將事務報告為已送出之前寫入仲裁來保證數據的一定程度的彈性。然後將數據延遲複製到數據副本所在的其他節點。

請注意,“最終一致性”是對一致性的主要權衡,如果在送出事務後必須以一致的方式查看數據,則可能無法接受。例如,在財務應用程序中,更新後的餘額應立即可用。

共享磁碟系統

共享磁碟系統是所有節點都可以訪問所有儲存的系統。因此,計算與位置無關。許多 DBMS 平台也可以在這種模式下工作——Oracle RAC 就是這種架構的一個例子。

共享磁碟系統可以大幅擴展,因為它們可以支持儲存節點和處理節點之間的 M:M 關係。一個 SAN 可以有多個控制器,並且多個伺服器可以執行數據庫。這些架構將交換機作為中心瓶頸,但交叉開關允許此交換機擁有大量頻寬。一些處理可以解除安裝到儲存節點上(如 Oracle 的 Exadata),這可以減少儲存頻寬上的流量。

儘管交換機在理論上是一個瓶頸,但可用頻寬意味著共享磁碟架構將非常有效地擴展到大事務量。大多數主流 DBMS 架構都採用這種方法,因為它提供了“足夠好”的可擴展性和高可靠性。使用冗餘儲存架構(例如光纖通道),不會出現單點故障,因為在任何處理節點和任何儲存節點之間至少有兩條路徑。

無共享系統

無共享系統是這樣的系統,其中至少一些數據保存在一個節點本地,並且對其他節點不直接可見。這消除了中央交換機的瓶頸,允許數據庫(至少在理論上)隨節點數量而擴展。水平分區允許跨節點拆分數據;這對客戶端可能是透明的,也可能不是(參見上面的分片)。

因為數據本質上是分佈式的,所以查詢可能需要來自多個節點的數據。如果連接需要來自不同節點的數據,則使用半連接操作來傳輸足夠的數據以支持從一個節點到另一個節點的連接。這可能會導致大量的網路流量,因此優化數據的分佈會對查詢性能產生很大影響。

通常,數據在無共享系統的節點之間複製,以減少半連接的必要性。這在數據倉庫設備上效果很好,因為維度通常比事實表小很多數量級,並且可以輕鬆地跨節點複製。它們通常也分批載入,因此複製成本比事務應用程序上的問題要小。

無共享架構固有的並行性使其非常適合數據倉庫的表掃描/聚合查詢特性。這種操作幾乎可以隨著處理節點的數量線性擴展。跨節點的大型連接往往會產生更多成本,因為半連接操作會產生大量網路流量。

移動大數據量對於事務處理應用程序的用處不大,其中多次更新的成本使得這種類型的架構不如共享磁碟有吸引力。因此,這種類型的架構往往不會在數據倉庫應用程序之外廣泛使用。

分片、仲裁複製和最終一致性

Quorum Replication 是一種 DBMS 複製數據以實現高可用性的工具。這對於旨在在沒有內置高可用性功能(如 SAN)的廉價商品硬體上工作的系統很有用。在這種類型的系統中,為了讀取性能和冗餘儲存,數據在多個儲存節點之間複製,以使系統對節點的硬體故障具有彈性。

但是,對於 M 個節點和 N 次寫入,將寫入複製到所有節點是 O(M x N)。如果必須在允許送出事務之前將寫入複製到所有節點,這會使寫入變得昂貴。仲裁複製是一種折衷方案,它允許立即將寫入複製到節點的子集,然後通過後台任務延遲寫入其他節點。寫入可以更快地送出,同時通過確保在將事務報告為已送出給客戶端之前將它們複製到最小的節點子集(仲裁)來提供一定程度的冗餘。

這意味著,在後台程序完成將數據寫入其餘節點之前,仲裁以外的節點可以看到數據的過時版本。語義被稱為“最終一致性”,根據應用程序的要求可能會或可能不會被接受,但這意味著事務送出在資源使用方面更接近 O(1) 而不是 O(n)。

分片要求客戶端了解數據庫中數據的分區,通常使用一種稱為“一致雜湊”的算法。在分片數據庫中,客戶端對密鑰進行雜湊處理,以確定向集群中的哪個伺服器發出查詢。由於請求分佈在集群中的節點上,因此單個查詢協調器節點沒有瓶頸。

這些技術允許數據庫通過向集群添加節點以接近線性的速率擴展。理論上,只有當底層儲存介質被認為不可靠時,才需要仲裁複製。如果要使用商品伺服器,這很有用,但如果底層儲存機制有自己的高可用性方案(例如,具有鏡像控制器和與主機的多路徑連接的 SAN),則價值較小。

例如,Google 的 BigTable 本身並沒有實現 Quorum Replication,儘管它確實位於 GFS 上,GFS 是一個使用仲裁複製的集群文件系統。BigTable(或任何無共享系統)可以使用具有多個控制器的可靠儲存系統,並在控制器之間劃分數據。然後將通過對數據進行分區來實現並行訪問。

返回 RDBMS 平台

這些技術不能與 RDBMS 一起使用並沒有內在的原因。然而,在這樣的系統上,鎖定和版本管理會非常複雜,並且這樣的系統的任何市場都可能非常專業化。沒有一個主流的 RDBMS 平台使用仲裁複製,而且我也沒有特別了解任何 RDBMS 產品(至少沒有一個有任何顯著吸收的產品)。

共享磁碟和無共享系統可以擴展到非常大的工作負載。例如,Oracle RAC 可以支持 63 個處理節點(它們本身可能是大型 SMP 機器)和 SAN 上的任意數量的儲存控制器。一個 IBM Sysplex(zSeries 大型機集群)可以支持多個大型機(每個都具有強大的處理能力和自己的 I/O 頻寬)和多個 SAN 控制器。這些架構可以支持具有 ACID 語義的非常大的事務量,儘管它們確實假設了可靠的儲存。Teradata、Netezza 和其他供應商基於可擴展到超大數據量的無共享設計製造高性能分析平台。

到目前為止,廉價但超大容量的全 ACID RDBMS 平台市場由支持分片和多主複製的 MySQL 主導。MySQL 不使用仲裁複製來優化寫入吞吐量,因此事務送出比在 NoSQL 系統上更昂貴。分片允許非常高的讀取吞吐量(例如 Facebook 廣泛使用 MySQL),因此這種類型的架構在讀取繁重的工作負載上可以很好地擴展。

一場有趣的辯論

BigTable是一種無共享架構(本質上是分佈式鍵值對),如下面的 Michael Hausenblas 所指出的。我最初對它的評估包括 MapReduce 引擎,它不是 BigTable 的一部分,但通常會在其最常見的實現中與它一起使用(例如 Hadoop/HBase 和 Google 的 MapReduce 框架)。

將此架構與 Teradata 進行比較,後者在儲存和處理之間具有物理關聯(即節點具有本地儲存而不是共享 SAN),您可能會認為 BigTable/MapReduce 是通過全域可見的並行儲存系統實現的共享磁碟架構。

MapReduce 風格系統(如 Hadoop)的處理吞吐量受到非阻塞網路交換機頻寬的限制。1然而,由於設計中固有的並行性, 非阻塞交換機可以處理大頻寬聚合,因此它們很少對性能造成重大的實際限制。這意味著共享磁碟架構(也許更好地稱為共享儲存系統)可以擴展到大型工作負載,即使網路交換機在理論上是一個中心瓶頸。

最初的觀點是,儘管共享磁碟系統中存在這個中心瓶頸,但具有多個儲存節點(例如 BigTable 平板伺服器或 SAN 控制器)的分區儲存子系統仍然可以擴展到大型工作負載。非阻塞交換機架構(理論上)可以處理與埠一樣多的目前連接。

1當然,可用的處理和 I/O 吞吐量也構成了性能限制,但網路交換機是所有流量通過的中心點。

關係數據庫可以像 NoSQL 解決方案一樣集群。維護 ACID 屬性可能會使這更加複雜,並且必須意識到為維護這些屬性所做的權衡。不幸的是,究竟是什麼權衡取決於工作量,當然還有在設計數據庫軟體時做出的決定。

例如,主要 OLTP 工作負載可能具有額外的單個查詢延遲,即使集群的吞吐量可以很好地擴展。額外的延遲可能會被忽視或成為真正的交易破壞者,這一切都取決於應用程序。一般來說,集群會提高吞吐量並減少延遲,但如果應用程序的查詢特別適合併行處理,那麼即使是“規則”也是值得懷疑的。

我工作的公司Clustrix提供的是一系列由相對高速網路連接的同構計算和儲存節點。關係數據在每個索引的基礎上散列在節點上,我們稱之為“切片”。每個切片將有兩個或更多副本分佈在整個集群中,以便在節點或磁碟發生故障時保持持久性。客戶端可以連接到集群中的任何節點,以使用 MySQL 有線協議發出查詢。

獨立地考慮 ACID 數據庫的組件有點不自然,因為其中很多都相互吻合,但這裡有:

原子性- Clustrix 使用兩階段送出來確保原子性。UPDATE 和 DELETE 操作也將通過我們的分佈式鎖管理器鎖定行,因為我們在內部將這些操作轉換為 SELECT,然後是精確的 UPDATE/DELETE 操作。

原子性顯然增加了參與事務的節點之間的消息傳遞量,並增加了這些節點處理送出協議的負載。這是分佈式系統成本的一部分,如果每個節點都參與每個事務,則會限制可伸縮性,但節點只有在寫入其中一個副本時才參與事務。

一致性- 外鍵作為觸發器實現,在送出時進行評估。大範圍的 UPDATE 和 DELETE 操作會由於鎖定而損害我們的性能,但幸運的是我們並不經常看到這些。看到事務更新/刪除幾行然後送出更為常見。

一致性的另一部分是通過PAXOS 共識協議維護仲裁,該協議確保只有具有大多數已知節點的集群才能進行寫入。當然,集群有可能具有仲裁但仍然缺少數據(切片的所有副本都離線),這將導致訪問其中一個切片的事務失敗。

隔離- Clustrix 在容器級別提供 MVCC 隔離。我們的原子性保證在我們報告送出的事務之前所有適用的副本都會收到特定的寫入,這主要將隔離問題減少到您在非集群情況下所遇到的問題。

持久性 - 每個關係數據片都儲存到兩個或多個節點,以在節點或磁碟發生故障時提供彈性。在這裡可能還值得注意的是,我們產品的設備版本有一個 NVRAM 卡,出於性能原因在其中儲存了 WAL。許多單實例數據庫將通過間隔檢查點而不是每次送出來提高其 WAL 的性能。這種方法在分佈式系統中是有問題的,因為“重播到哪裡?” 一個複雜的問題。我們通過提供堅固的耐用性保證在設備中迴避這一點。

引用自:https://dba.stackexchange.com/questions/34892