我应该为 "com.datastax.driver.core.exceptions.ReadTimeoutException" 做什么?

what should I do for "com.datastax.driver.core.exceptions.ReadTimeoutException"?

我把几乎 190 million records 放在具有 3 个节点的 Cassandra(2.1.11) 集群中,复制因子是 1 ,然后我编写客户端应用程序以使用 [=28 计算所有记录=],代码段如下:

Statement stmt = new SimpleStatement("select * from test" );

System.out.println("starting to read records ");
stmt.setFetchSize(10000);
ResultSet rs = session.execute(stmt);

//System.out.println("rs.size " + rs.all().size());
long cntRecords = 0;

for(Row row : rs){
    cntRecords++;

    if(cntRecords % 10000000 == 0){
        System.out.println("the " + cntRecords/10000000 + " X 10 millions of records");
    }
}

上面的变量cntRecords超过3000万后,总是报异常:

Exception in thread "main" com.datastax.driver.core.exceptions.ReadTimeoutException: 
Cassandra timeout during read query at consistency ONE (1 responses were required but only 
0 replica responded)

我在google中得到了几个结果并更改了关于堆和GC的设置,以下是我的相关设置:

-XX:InitialHeapSize=17179869184 
-XX:MaxHeapSize=17179869184 
-XX:MaxNewSize=12884901888 
-XX:MaxTenuringThreshold=1 
-XX:NewSize=12884901888 
-XX:+UseCMSInitiatingOccupancyOnly 
-XX:+UseCompressedOops 
-XX:+UseConcMarkSweepGC 
-XX:+UseCondCardMark 
-XX:+UseGCLogFileRotation 
-XX:+UseParNewGC 
-XX:+UseTLAB 
-XX:+UseThreadPriorities
-XX:+CMSClassUnloadingEnabled 

我用GCViewer分析了gc日志文件,througputs分别是99.95%、98.15%和95.75%。

更新开始: 而我用jstat去监控三个节点之一,发现当S1的值变成100.00时,很快就会出现上面的错误:

/usr/java/jdk1.7.0_80/bin/jstat -gcutil 8862 1000 
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
0.00 100.00  28.57  36.29  74.66     55   14.612     2    0.164   14.776

而一旦S1变成100.00S1就不会再减少了,不知道这是相对的错误?或者我应该为此设置什么 属性 in cassandra.yaml or cassandra-env.sh

如何完成统计所有记录的任务?提前致谢!

附加: 以下是其他选项:

-XX:+CMSEdenChunksRecordAlways 
-XX:CMSInitiatingOccupancyFraction=75 
-XX:+CMSParallelInitialMarkEnabled 
-XX:+CMSParallelRemarkEnabled 
-XX:CMSWaitDuration=10000 
-XX:CompileCommandFile=bin/../conf/hotspot_compiler 
-XX:GCLogFileSize=94371840 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:NumberOfGCLogFiles=90 
-XX:OldPLABSize=16 
-XX:PrintFLSStatistics=1 
-XX:+PrintGC 
-XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCDateStamps 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintHeapAtGC 
-XX:+PrintPromotionFailure 
-XX:+PrintTenuringDistribution 
-XX:StringTableSize=1000003 
-XX:SurvivorRatio=8 
-XX:ThreadPriorityPolicy=42 
-XX:ThreadStackSize=256 

检查为什么您需要知道行数。您的应用程序真的需要知道这些吗?如果它可以在 "just" 一个很好的近似值下存活下来,那么创建一个计数器并在加载数据时递增它。

http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html

您可以尝试的事情:

  • Select 单列而不是 *。这可能会减少 GC 压力和网络消耗。最好选择一个字节数少并且是主键一部分的列:select column1 from test
  • 每 1M 条记录后添加一个短暂停顿。每 1M 条记录让循环暂停 500 毫秒左右。这可能会给节点一个快速的喘息机会来处理像 GC
  • 这样的事情
  • 在您的节点上编辑 cassandra.yaml 并增加 range_request_timeout_in_msread_request_timeout_in_ms
  • 找出分配给每个节点的令牌范围,并对每个令牌范围发出单独的查询。添加每个查询的计数。这利用了令牌感知驱动程序将每个 "token range" 查询直接发送到可以回答它的节点。请参阅此 blog article 以获取包含示例代码的完整说明。