2014-02-13 96 views
17

根據cassandra的日誌(見下文),由於存在太多tombstones,查詢將會中止。發生這種情況的原因是每週一次清理(刪除)行數過低的計數器。這「刪除」 幾十萬行的(它們標記爲這樣一個tombstone。)當達到邏輯刪除限制時會發生什麼

這根本不是一個問題,如果在該表中,已刪除的行再次出現,因爲在一個節點宕機清理過程,因此我將單個受影響表的gc grace time設置爲10小時(從默認的10天減少),因此可以相對較快地將邏輯刪除的行永久刪除。

無論如何,我必須設置tombstone_failure_threshold非常高,以避免以下例外。 (一億,從十萬增加)我的問題是,這是必要的嗎?我完全不知道什麼類型的查詢會中止;插入,選擇,刪除?

如果僅僅是一些被中止的選擇,那不是什麼大不了的事情。但是,假設中止意味着'封頂',因爲查詢過早停止並返回它在搜索到太多墓碑之前設法收集的任何實時數據。

好吧,問個簡單吧;當超過tombstone_failure_threshold時會發生什麼?

INFO [HintedHandoff:36] 2014-02-12 17:44:22,355 HintedHandOffManager.java (line 323) Started hinted handoff for host: fb04ad4c-xxxx-4516-8569-xxxxxxxxx with IP: /XX.XX.XXX.XX 
ERROR [HintedHandoff:36] 2014-02-12 17:44:22,667 SliceQueryFilter.java (line 200) Scanned over 100000 tombstones; query aborted (see tombstone_fail_threshold) 
ERROR [HintedHandoff:36] 2014-02-12 17:44:22,668 CassandraDaemon.java (line 187) Exception in thread Thread[HintedHandoff:36,1,main] 
org.apache.cassandra.db.filter.TombstoneOverwhelmingException 
    at org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:201) 
    at org.apache.cassandra.db.filter.QueryFilter.collateColumns(QueryFilter.java:122) 
    at org.apache.cassandra.db.filter.QueryFilter.collateOnDiskAtom(QueryFilter.java:80) 
    at org.apache.cassandra.db.filter.QueryFilter.collateOnDiskAtom(QueryFilter.java:72) 
    at org.apache.cassandra.db.CollationController.collectAllData(CollationController.java:297) 
    at org.apache.cassandra.db.CollationController.getTopLevelColumns(CollationController.java:53) 
    at org.apache.cassandra.db.ColumnFamilyStore.getTopLevelColumns(ColumnFamilyStore.java:1516) 
    at org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1335) 
    at org.apache.cassandra.db.HintedHandOffManager.doDeliverHintsToEndpoint(HintedHandOffManager.java:351) 
    at org.apache.cassandra.db.HintedHandOffManager.deliverHintsToEndpoint(HintedHandOffManager.java:309) 
    at org.apache.cassandra.db.HintedHandOffManager.access$300(HintedHandOffManager.java:92) 
    at org.apache.cassandra.db.HintedHandOffManager$4.run(HintedHandOffManager.java:530) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 

忘了提及;運行Cassandra版本2.0.4

回答

18

當向Cassandra發出返回一個或多個行(或列)範圍的查詢時,它必須掃描表以收集結果集(稱爲片)。現在,刪除的數據以與常規數據相同的方式進行存儲,除了它被標記爲邏輯刪除直到被壓縮爲止。但桌上閱讀器不得不掃描它。所以如果你有很多墓碑躺在周圍,你會有大量的工作要做,以滿足你表面上有限的切片。

一個具體的例子:比方說,你有兩行聚簇鍵1和3,以及十萬行集羣鍵2的死行,它們位於表中的第1行和第3行之間。現在,當您發出一個SELECT查詢,其中密鑰要> = 1和< 3時,您必須掃描100002行,而不是預期的兩行。

更糟糕的是,Cassandra不僅掃描這些行,而且在準備響應時還必須將它們累積在內存中。這可能會導致節點上出現內存不足錯誤,如果有多個節點正在爲請求提供服務,則甚至可能會導致多個故障導致整個羣集無法運行。爲防止發生這種情況,如果服務檢測到危險數量的墓碑,該服務會中止查詢。你可以自由發揮,但如果你的Cassandra堆在這些峯值期間即將耗盡,那麼存在風險。

這個異常是在最近的一個修補程序中引入的,首次在2.0.2中提供。 Here是描述更改試圖解決的問題的錯誤條目。以前一切都會好起來的,直到你的一個節點或者可能有幾個節點突然崩潰。

如果僅僅是一些被中止的選擇,那不是什麼大不了的事情。 但是,假設中止意味着「封頂」,因爲查詢提前停止 並返回它在所搜索到的所有實時數據之前 發現了太多的墓碑。

該查詢不返回一個有限的集合,它實際上完全丟棄了該請求。如果你想緩解,也許值得做寬容行刪除與寬限期相同的節奏,所以你不會每週都有大量的墓碑涌入。

+0

根據我的問題中的錯誤日誌,在提示切換期間發生異常。這似乎意味着這個問題不僅發生在SELECT查詢期間,而且還發生在「節點間通信」期間。它是否正確?重要的原因是這個表有一個「複合鍵」,並且一個常規選擇只能通過這些鍵中的第一個來查詢,這使得在所述查詢期間墓碑的數量不重要。 – natli

+1

是的,hinting是節點之間交換信息的協議,但它是一個可選功能,旨在提高節點停機期間的集羣性能。您可以通過http://www.datastax.com/dev/blog/modern-hinted-handoff閱讀更多內容。提示存儲在系統表中,因此發送一個涉及執行該切片以及關於邏輯刪除的所有潛在問題。 –

+1

我對「HintedHandoffManager」沒有深入的瞭解,所以我不能說在提示表中獲取過多數量的墓碑是否表示使用模式不正確。我只能提到你並不是唯一一個看到這些的人。有關相關討論,請參閱http://cassandra-user-incubator-apache-org.3065146.n2.nabble.com/Crash-with-TombstoneOverwhelmingException-td7592018.html。 如果您可以將這些崩潰與特定操作或週期性任務關聯起來,它可能會爲您帶來領先,爲什麼首先會生成如此多的提示。 –

相關問題