2013-12-11 74 views
6

我在一個DC中有兩個C * 2.0.2節點(在cassandra.yaml中有一個默認配置)和一個RF = 2的密鑰空間。兩臺客戶機通過Datastax Java Driver 1.0.3連接到此DC。客戶端讀寫CL/ONE中的數據,並且沒有任何錯誤。 但是當我關閉一個節點下兩個客戶端獲得巨大的例外量:Cassandra NoHostAvailableException存在活動節點時

com.datastax.driver.core.exceptions.NoHostAvailableException: 
All host(s) tried for query failed (no host was tried) 

那一堆例外客戶繼續與仍然活着另一個節點成功運行後。我應該怎麼做才能接收NoHostAvailableException,因爲一次至少有一個活動節點,並且CL = ONE被使用?

UPDATE: 當我關閉兩個節點我有時會看到我的應用程序日誌中的以下異常之一:

[Reconnection-1] [ERROR] [Control connection] Cannot connect to 
any host, scheduling retry 

爲什麼這兩個節點不可用,如果我關只有一個了嗎?第二個在這一刻仍然活着,我可以用cqlsh連接它。

+0

對不起,我的回答沒有幫助。您是否嘗試啓用com.datastax.driver.core.RequestHandler的跟蹤日誌記錄?它看起來像當你關閉第一個節點時,第二個出於某種原因被拋出池。 RequestHandler.logError()方法中記錄的異常的堆棧跟蹤(「查詢bla-bla-bla錯誤」)可能有助於找出它。 – Wildfire

+0

我會試試看,謝謝。 – tilex

回答

0

如果您執行CL = ONE的請求,驅動程序將嘗試僅查詢單個節點。因此,如果對該節點的請求失敗(或節點不可用),則會立即引發異常。此行爲由創建Cluster時指定的com.datastax.driver.core.policies.RetryPolicy控制。

我想說,一個RetryPolicy,使固定的重試次數將符合您的需求。不幸的是,Cassandra Driver 1.0.3沒有捆綁它(我不確定是否有更高版本)。儘管如此,它可能實現這樣的:

public class MyRetryPolicy implements RetryPolicy { 

    final int attempts; 

    public MyRetryPolicy(int attempts) { 
     this.attempts = attempts; 
    } 

    @Override 
    public RetryDecision onReadTimeout(Query query, ConsistencyLevel cl, int requiredResponses, int receivedResponses, boolean dataRetrieved, int nbRetry) { 
     return (nbRetry >= attempts) ? RetryDecision.rethrow() : RetryDecision.retry(cl) 
    }   

    ... <onWriteTimeout & onUnavailable methods with similar implementation> 
} 

我不知道,如果MyRetryPolicy(2)就足夠了,因爲我沒有深入到驅動程序的內部深。可能會發出另一個向同一主機發送相同請求的嘗試。你可以嘗試MyRetryPolicy(10),它至少應該大大減少失敗的次數。

如果仍然存在某些故障(如1000中的1個),則可能值得查看com.datastax.driver.core.ConvictionPolicy,查找其用法並進一步調查。

+1

自定義'RetryPolicy'是我嘗試的第一件事,但是當引發'NoHostAvailableException'時,它的回調方法都沒有被調用。 – tilex