Java 偶尔失败的Cassandra查询

Java 偶尔失败的Cassandra查询,java,cassandra,Java,Cassandra,我们遇到了连续运行java应用程序更新Cassandra中计数器的问题。通过监视服务器的负载,我们看不到与负载的任何关联。这些查询非常稳定,因为它们只更新8个不同表中的值。java应用程序每分钟都会触发数千个查询(可能是20k甚至50k个查询),但偶尔会有一些查询失败。当这种情况发生时,我们会将它们连同异常消息一起写入一个文件。这条信息总是很重要 consistency ONE写入查询期间的Cassandra超时(需要1个副本,但只有0确认写入) 我们进行了一些谷歌搜索和故障排除,并采取了几项措

我们遇到了连续运行java应用程序更新Cassandra中计数器的问题。通过监视服务器的负载,我们看不到与负载的任何关联。这些查询非常稳定,因为它们只更新8个不同表中的值。java应用程序每分钟都会触发数千个查询(可能是20k甚至50k个查询),但偶尔会有一些查询失败。当这种情况发生时,我们会将它们连同异常消息一起写入一个文件。这条信息总是很重要
consistency ONE写入查询期间的Cassandra超时(需要1个副本,但只有0确认写入)

我们进行了一些谷歌搜索和故障排除,并采取了几项措施:

  • 将java应用程序中的重试策略更改为
    DefaultRetryPolicy
    ,而不是
    FallthroughRetryPolicy
    ,以便客户端在查询失败时重试查询
  • 将Cassandra节点上的
    write\u request\u timeout\u in_ms
    设置从标准值
    2000
    更改为
    4000
    ,然后更改为
    10000
这些操作减少了失败查询的数量,但仍然会发生。从每小时执行的数百万个查询中,我们可以看到大约2000个查询在24小时内失败。所有这些都有上面列出的相同异常,并且它们在不同的时间发生

当然,我们从日志中看到,当查询失败时,需要一段时间,因为它正在等待超时并执行重试

一些事实:

  • 我们运行Cassandra v2.2.5(最近从v2.2.4升级)
  • 我们有一个地理感知Cassandra集群,有6个节点:3个在欧洲,3个在美国
  • 触发查询的java应用程序是唯一与Cassandra通信的客户端(目前)
  • java应用程序的数量在欧盟是10:5,在美国是5
  • 我们异步执行所有查询(
    session.executeAsync(statement);
    ),并通过添加成功和失败的回调来跟踪各个查询
  • 复制因子为2
  • 复制因子为2
  • 我们运行Oracle Java 1.7.0_76
    Java(TM)SE运行时环境(构建1.7.0_76-b13)Java热点(TM)64位服务器虚拟机(构建24.76-b04,混合模式)
  • 6个Cassandra节点在裸机上运行,规格如下:
    • 存储是raid 5中的一组SSD
    • 每个节点有2个(6核)Intel Xeon E5-2620处理器@2.00GHz(硬件线程总数为24个)
    • 内存大小为128GB
我们如何创建集群:

private Cluster createCluster() {
    return Cluster.builder()
            .addContactPoints(contactPoints)
            .withRetryPolicy(DefaultRetryPolicy.INSTANCE)
            .withLoadBalancingPolicy(getLoadBalancingPolicy())
            .withReconnectionPolicy(new ConstantReconnectionPolicy(reconnectInterval))
            .build();
}
private LoadBalancingPolicy getLoadBalancingPolicy() {
    return DCAwareRoundRobinPolicy.builder()
            .withUsedHostsPerRemoteDc(allowedRemoteDcHosts) // == 3 
            .build();
}
如何创建键空间:

CREATE KEYSPACE IF NOT EXISTS traffic WITH REPLICATION = { 'class': 'NetworkTopologyStrategy', 'AMS1': 2, 'WDC1': 2};
示例表(它们看起来都很相似)

许多评论:

  • 首先,对于
    集群
    配置,您应该指定本地DC名称
  • 您应该使用LOCAL\u ONE而不是ONE作为一致性级别,以增强数据的局部性
  • 请勿更改
    写入请求\u超时\u in \u ms
    值。你只是在掩盖问题,你真正的问题不是超时设置
  • 您的复制系数是多少
  • java应用程序每分钟都会触发数千次查询(可能是20k甚至50k次查询)
    -->简单的数学运算假设RF=1,则每个节点每秒插入300次。它并没有那么大,但您的插入可能会受到硬件的限制。您的CPU配置(核心数)和磁盘类型(旋转磁盘或SSD)是什么
  • 是否限制异步插入?例如,点燃N批插入物,稍等集群呼吸。关于节流,请参见我的答案:
  • 许多评论:

  • 首先,对于
    集群
    配置,您应该指定本地DC名称
  • 您应该使用LOCAL\u ONE而不是ONE作为一致性级别,以增强数据的局部性
  • 请勿更改
    写入请求\u超时\u in \u ms
    值。你只是在掩盖问题,你真正的问题不是超时设置
  • 您的复制系数是多少
  • java应用程序每分钟都会触发数千次查询(可能是20k甚至50k次查询)
    -->简单的数学运算假设RF=1,则每个节点每秒插入300次。它并没有那么大,但您的插入可能会受到硬件的限制。您的CPU配置(核心数)和磁盘类型(旋转磁盘或SSD)是什么
  • 是否限制异步插入?例如,点燃N批插入物,稍等集群呼吸。关于节流,请参见我的答案:

  • 谢谢你的回答!(1) 我们提供的服务器列表是本地节点列表。这也实现了同样的目的。(2) 我们更新了代码,谢谢。(3) 同意。(4) 复制因子为2。为清楚起见,将其添加到事实中。(5) Cassandra数据存储在raid5中的SSD上。更新了事实。(6) 我们不限制插入。会考虑这一点。我们很想看到您建议的更改的效果!RAID5中的SSD组是由6个节点共享的还是每个节点的配置?每个节点都有自己的SSD。这很奇怪,通常使用SSD和24核,每个节点应该能够处理1000+插入/秒。您是否使用dstat和iostat等工具监视系统负载,以了解瓶颈是什么?阅读这篇关于C*调优的博文:是的,我们一直在使用
    iostat
    监视节点的负载和IO。他们只使用了一小部分的容量,因为他们现在唯一在运行的是Cassandra。谢谢你的回答!(1) 我们提供的服务器列表是本地节点列表。这也实现了同样的目的。(2) 我们更新了代码,谢谢。(3) 同意。(4) 复制因子为2。为清楚起见,将其添加到事实中。(5) Cassandra数据存储在raid5中的SSD上。更新了事实。
    CREATE TABLE IF NOT EXISTS traffic.per_node (
        node text,
        request_time timestamp,
        bytes counter,
        ssl_bytes counter,
        hits counter,
        ssl_hits counter,
        PRIMARY KEY (edge, request_time)
    ) WITH CLUSTERING ORDER BY (request_time DESC)
        AND compaction = {'class': 'DateTieredCompactionStrategy'};