簡體   English   中英

為什么在使用基於仲裁的讀寫時 Cassandra 不可線性化

[英]Why is Cassandra not linearizable when quorum based read and writes are used

您能否解釋為什么即使使用基於仲裁的讀寫,Cassandra 也不能線性化?

線性化定義為

如果操作 B 在操作 A 成功完成后開始,則操作 B 必須看到系統處於與操作 A 完成時相同的狀態,或更新的狀態。

編輯考慮 Cassandra 前景讀取修復:

由於僅更新了部分副本而失敗的寫入可能會導致兩個不同的讀取器看到兩個不同的數據值。 這是因為在簡單的基於仲裁的一致性方法中缺乏回滾。 這種行為破壞了單鍵讀取的線性化保證。 如本次討論中所述,Raft 或 Paxos 等分布式共識協議是此類保證的必備條件。

在此處輸入圖片說明

此外,時鍾漂移閏秒等其他現象可能會破壞 Cassandra 會話的一致性。

較早的答案(不考慮 Cassandra 前台讀取修復):

總結:在 Cassandra 中寫入可能沒有原子性。 一些節點的寫入速度比其他節點快,因此即使我們依賴仲裁,結果也取決於返回值的節點集以及它們在該點持有的值。

此外,為了解釋線性化的定義,添加到粗體的定義

如果操作 B 在操作 A 成功完成后開始,則操作 B 必須看到系統處於與操作 A 完成時相同的狀態,或者更新的狀態(但不再是舊狀態)

從 Martin Klepmann 的《數據密集型應用程序》一書中復制

可線性化和仲裁直覺上,嚴格的仲裁讀取和寫入似乎應該在 Dynamo 風格的模型中線性化。 然而,當我們有可變的網絡延遲時,就有可能出現競爭條件,如圖 9-6 所示。

在此處輸入圖片說明

在圖 9-6 中,x 的初始值為 0,並且寫入客戶端通過將寫入發送到所有三個副本(n = 3,w = 3)來將 x 更新為 1。 同時,客戶端 A 從兩個節點 (r = 2) 的仲裁中讀取,並在其中一個節點上看到新值 1。 同樣在寫入的同時,客戶端 B 從兩個節點的不同仲裁讀取,並從兩個節點取回舊值 0。

滿足法定人數條件 (w + r > n),但此執行仍然不可線性化:B 的請求在 A 的請求完成后開始,但 B 返回舊值而 A 返回新值。 (這又是圖 9-1 中 Alice 和 Bob 的情況。)

有趣的是,有可能以降低性能為代價使 Dynamo 風格的仲裁線性化:在將結果返回給應用程序 [23] 之前,讀取器必須同步執行讀取修復(請參閱第 178 頁的“讀取修復和反熵”),並且寫入者必須在發送其寫入之前讀取法定節點的最新狀態 [24, 25]。 然而,由於性能損失,Riak 不執行同步讀取修復 [26]。 Cassandra 確實會在仲裁讀取 [27] 上等待讀取修復完成,但是如果對同一個鍵有多個並發寫入,它會失去線性化能力,因為它使用了最后寫入獲勝的沖突解決方案。

而且這種方式只能實現線性化的讀寫操作; 線性化的比較和設置操作不能,因為它需要一個共識算法[28]。

總之,假設具有 Dynamo 式復制的無領導系統不提供線性化是最安全的。

關於線性化與可串行化的更多解釋:

在此處輸入圖片說明

編輯:事后看來,這不是最好的解釋。 我建議閱讀下面 Anurag 的答案,它更簡潔。

由於正常的 Cassandra 操作不會觀察到它正在改變的現有狀態,因此單獨的仲裁一致性不被視為“可線性化”。

例如,如果您要調整銀行帳戶的余額,則需要知道當前余額才能進行調整。 考慮一個執行以下操作的客戶端:

A. SELECT balance FROM account WHERE id='x' (assume this returns 5.12)
B. UPDATE account SET balance=4.12 WHERE id='x' (subtract 1$ from balance)

問題是,從 Cassandra 的角度來看,操作B沒有有效地“看到” A因為它沒有考慮數據的現有狀態或可能為此發生的任何其他操作。 在提交B期間,另一個客戶可能正在更新同一帳戶的余額。

Cassandra 2.0中的輕量級事務描述了輕量級事務如何通過提供確保操作按順序執行給定分區且不會被其他分區中斷的構造來提供“可線性化一致性”。 因此,您現在可以執行以下操作,而不是我之前的示例:

A. SELECT balance FROM account WHERE id='x' (assume this returns 5.12)
B. UPDATE account SET balance=4.12 WHERE id='x' IF balance=5.12

使用IF balance=5.12指示 Cassandra 開始輕量級交易,該交易使用paxos consesus 協議進行領導選舉並確保操作按順序應用。 如果余額狀態不滿足條件,則不會應用更新(在成功響應中使用was_applied布爾列表示)。 如果 C* 無法在某個超時內實現此目的(由於爭用或其他一些因素),則操作將失敗,不會被應用,並且客戶端將出現超時。

根據您的定義,當 Cassandra 的讀寫設置設置為法定人數時,它是可以線性化的。

關於串行一致性的舊文檔

然而,似乎無條件更新是“破壞”線性化的原因,並且需要在驅動程序級別禁用這些更新才能將 cassandra 標記為“可線性化”。

因此可以使用 Cassandra 實現線性化。 但是 cassandra 本身不會強制線性化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM