2012-06-25 28 views
3

我們在讀取和寫入仲裁時遇到了使用Hector和Cassandra的一致性問題。Cassandra中的數據與法定配置不一致

我使用MultigetSubSliceQuery來查詢超級列限制大小爲100的行,然後讀取它,然後將其刪除。並從另一個角度開始。

我發現應該從我的在先查詢中刪除的行仍然顯示在下一個查詢中。

同樣來自一個正常的Column Family,我將status列中的一列的值更新爲status ='TRUE',下一次查詢時狀態仍然爲'FALSE'。

的更多細節:

  1. 它每一次(1/10,000)
  2. 兩個查詢之間的時間是大約500毫秒沒有發生不(但我們發現查詢中的一個對在其中2秒已經過去了,仍然表明存在一致性問題)
  3. 我們使用ntp作爲我們的集羣時間同步解決方案。
  4. 我們有6個節點,複製因子爲3

據我所知,卡桑德拉應該是「最終一致」了,裏面卡桑德拉寫之前讀可能不會發生。但是兩秒鐘?!如果是這樣,那麼擁有Quorum或其他一致性級別配置是否沒有意義?因此,首先,它是卡桑德拉的正確行爲,如果不是,我們需要分析哪些數據用於進一步的投資?

+0

的細節/讀取所有,問題解決了,所以它應該是卡桑德拉無法合併數據時,才發現「彙總不匹配」,從寫/讀定額寫開關後,但它並不是所有的「文摘不匹配」都失敗了。真的很奇怪,Cassandra版本是1.0.3 –

回答

3

在檢查與系統日誌的源代碼後,我發現不一致的根本原因。 三個因素導致此問題:

  • 創建和不同節點
  • 本地系統時間不同步不夠準確(儘管我們使用NTP)
  • 一致性水平QUORUM更新相同的記錄

以下是問題所在,以下爲事件序列

seqID NodeA   NodeB   NodeC 
1.  New(.050)  New(.050)  New(.050) 
2.  Delete(.030) Delete(.030) 

首先創建請求Ç來自節點與本地時間戳00:00:00.050,假設請求在節點A節點B第一個記錄,則在後面同步節點C

然後刪除請求來自節點A與本地時間戳00:在節點A節點B 00.030,並記錄:00。

要求來,卡桑德拉會做版本衝突合併,但合併只有依靠時間戳,所以雖然刪除發生後創建,但合併的最終結果是「 「由於當地時間同步問題,它有最新的時間戳。

0

被刪除的行可能會顯示爲,因爲分佈式的方式「範圍內鬼」刪除工作:看http://wiki.apache.org/cassandra/FAQ#range_ghosts

如果你正在讀無論是在CL_QUORUM寫入單個列,那麼你應該總是得到完全一致,無論時間間隔如何(仍然遵守嚴格的順序,即您確定讀取總是在寫入之後)。如果你沒有看到這個,那麼某個地方是錯誤的。首先,我會建議a)驗證客戶端是否正確地同步到NTP,和/或重複問題時間在某種程度上在客戶端之間交叉檢查,以及b)也許嘗試用CL_ALL重現問題。

另一個想法 - 是你的客戶端與NTP同步,還是隻與Cassandra服務器節點同步?請記住,Cassandra使用客戶端時間戳來確定哪個值是最近的。

+0

對於「範圍幽靈」,我們查詢了列鍵而不是行鍵,並且也查詢了列值。 對於NTP,首先,刪除和查詢來自同一節點和同一個應用程序。然後我們將本地時間與NTP服務器,應用程序和Cassandra同步,全部使用本地時間。 –

+0

這一切聽起來都正確,所以你看到的行爲是意想不到的。我認爲沒有什麼不尋常的東西顯示日誌? – DNA

+0

沒有特別的錯誤,但啓用cassandra日誌後,我發現刪除請求被髮送到另外兩個節點,並且當讀請求到達本地節點時,發現數據不一致,並且有以下日誌,但最後它會返回髒的本地數據。 DEBUG [pool-2-thread-20] 2012-06-26 23:09:00,105 StorageProxy.java(第705行)摘要不匹配:org.apache.cassandra.service.DigestMismatchException:關鍵DecoratedKey不匹配(76499729728376587390748888639933581556,33323130537570657254616e6730 )(b20ac6ec0d29393d70e200027c094d13 vs d41d8cd98f00b204e9800998ecf8427e) –

-1

我遇到了這個問題與我的一個客戶端/節點。我正在測試的其他2個客戶端(以及另外2個節點)運行順利。我有一個在所有讀取和所有寫入中使用QUORUM的測試,並且它很快失敗。實際上,一些進程看不到其他的進程,其他進程甚至在我QUORUM刪除它之後也可能會看到數據。

在我來說,我打開日誌和打算用尾巴-F命令來測試壯舉:

tail -F /var/lib/cassandra/log/system.log 

,看看我是否得到了一些錯誤,這裏介紹。令我驚訝的是,尾部進程本身返回了一個錯誤:

tail: inotify cannot be used, reverting to polling: Too many open files 

並且來自另一個線程,這意味着某些進程將無法打開文件。換句話說,Cassandra節點可能沒有按預期做出響應,因爲它無法正確訪問磁盤上的數據。

我不太確定這是否與發佈問題的用戶相關,但是尾部-F肯定是確定是否達到文件限制的好方法。我只有5臺相對較重的服務器運行在同一臺機器上,所以我對這個事實並不感到驚訝,我必須考慮增加ulimit,如果我得到它我會再次報告固定用這種方式)

有關文件限制和ulimit命令行選項更多信息:https://askubuntu.com/questions/181215/too-many-open-files-how-to-find-the-culprit

---------更新1

以防萬一,我第一次測試使用Oracle的Java 1.7.0-11(如下所述,我首先使用了3,000的限制而沒有成功!)同樣的錯誤會在大約同時彈出摹我卡桑德拉測試(加連3000的的ulimit仍會出現尾巴-F錯誤...)

---------更新2

好吧!這工作。我將ulimit更改爲32,768,問題消失了。請注意,我必須放大/etc/security/limits.conf中的每個用戶限制並運行sudo sysctl -p,然後才能將最大值限制爲如此之高。以某種方式默認上限3000是不夠的,即使舊的限制是只有 1024.

0

我也遇到過類似的問題。由於cassandra驅動程序默認使用服務器時間戳來檢查哪個查詢是最新的,所以發生此問題。然而,在最新版本的cassandra驅動程序中,它們已經改變了它,現在默認情況下它們使用客戶端時間戳。

我所描述的問題here