2009-11-26 57 views
2

我不知道如何在BigTable數據存儲中處理這個問題。在BigTable數據存儲中,關於併發性,如何「鎖定」實體?

想象一下下面的例子(只是爲了解釋這個概念的例子不符合我的實際數據模型。):

  • 我有一個跟蹤交易數的數據存儲區的計數器實體。假設當前的「計數」爲100.
  • 現在兩個Web請求同時讀取此值。
  • 兩個Web請求添加一個新的交易
  • 最後兩個更新計數器(至101)。

計數器值現在不準確的。它應該是102.

有關如何處理這種情況的任何建議?我可以'鎖定'計數器,以確保第二個Web請求甚至不會讀取直到第一個Web請求完成?

回答

4

您有幾種選擇:

  • 根據您的櫃檯和你的實體的範圍,有交易的實體是計數器的子實體。然後,您可以插入交易並更新計數器transactionally。請記住,這將您的更新速率限制在約1-5 QPS。
  • 如果您的計數不必100%準確,請插入實體並分別更新計數器(使用單個實體事務)。您可以運行常規的cronjob來重新計算實體的數量,並在錯誤強制它不同步時修復計數器。
  • 你可以建立自己的limited distributed transaction support
+0

謝謝尼克。當你說「插入一個事務」時,你的意思是在db.run_in_transaction中執行一個函數嗎?當我在事務函數中執行「讀取」時,如果另一個線程嘗試訪問現在「過時」的值,它會「鎖定」對象並拋出錯誤嗎?謝謝,我還是新來的bigTable處理交易的方式:) – willem 2009-11-27 15:50:24

+0

那麼,你稱爲你的實體「交易」,所以當我說「插入交易」時,我的意思是「插入一個'交易'實體」。然而,讀取內部事務是事務性的 - 只有使用樂觀併發而不是鎖定。 – 2009-11-27 17:19:46

1

除了尼克給出了選項,你可以考慮分片計數器。

保持多個計數器,並挑選一個以這樣的方式來更新,這是比較理想的狀況是不可能或(做不到這一點)不太可能有兩個請求將同時選擇相同的碎片。

然後你有更多的選擇。您可以使用分片作爲父項進行交易(這會減少與單個計數器相比的爭用),但最終您的新交易實體會隨意選擇一個父項。或者不要爲交易而煩惱,在這種情況下,您可能需要不時地修正計數,就像Nick的非交易選項一樣。

要讀取總數,請將所有碎片合起來。你不會在「同一時間」全部閱讀它們,但通常很好。讀取任何計數器,它可能會增加之間,當你讀它,當你使用的價值,所以這個值真的只是一個下限。除了可能需要更長的時間之外,添加碎片並沒有什麼不同。

相關問題