時鐘約束等待

在讀寫值之前等待涵蓋叢集節點間時間不確定性,以便可以在叢集節點間正確排序值。

問題

考慮一個使用時間戳記來儲存值的鍵值儲存,以指定每個版本。處理客戶端要求的任何叢集節點都將能夠使用要求處理節點上的目前時間戳記來讀取最新版本。

在以下圖表中,值Before Dawn在時間 2 根據 Green 的時鐘更新為值After Dawn。Alice 和 Bob 都嘗試讀取title的最新值。雖然 Alice 的要求由叢集節點 Amber 處理,但 Bob 的要求由叢集節點 Blue 處理。Amber 的時鐘落後於 1,這表示當 Alice 讀取最新值時,它會傳送值Before Dawn。Blue 的時鐘為 2,因此當 Bob 讀取最新值時,它會將值傳回為After Dawn

這違反了外部一致性。如果 Alice 和 Bob 現在打電話,Alice 會感到困惑:Bob 會告訴她最新值是After Dawn,而她的叢集節點顯示Before Dawn

如果 Green 的時鐘很快,而且寫入根據 Amber 的時鐘發生在未來,也是一樣的。

如果系統的時間戳記用於儲存值的版本,這會是個問題,因為系統時間戳記並非單調遞增。來自兩個不同伺服器的時脈值無法且不應該進行比較。當 混合時脈 用於 版本化值 中的版本時,它允許在單一伺服器以及在因果相關的不同伺服器上對值進行排序。然而,混合時脈(或任何其他類型的 Lamport 時脈)只能提供「部分排序」。這表示任何在不同節點上由兩個不同用戶端儲存且無因果關係的值都無法排序。當使用時間戳記在叢集節點間讀取值時,這會造成問題。如果讀取要求來自時脈落後的叢集節點,它可能無法讀取給定值的最新版本。

解決方案

在讀取或寫入時,叢集節點會等到叢集中每個節點的時脈值保證高於指定給值的 timestamp。

如果時脈之間的差異很小,寫入要求可以在不增加太多負擔的情況下等待。例如,假設叢集節點之間的最大時脈偏移為 10 毫秒。(這表示在任何特定時間點,叢集中最慢的時脈落後最快的時脈最多 10 毫秒。)為了保證每個其他叢集節點的時脈都超過時間 t,處理任何寫入操作的叢集節點必須等到 t + 10 毫秒後才能儲存值。

有關更多詳細資訊,請參閱 oreilly.com 上線上電子書的 第 24 章

此模式是 分散式系統模式 的一部分

2023 年 11 月 23 日