偶尔失败的Cassandra查询

时间:2016-02-18 17:01:32

标签: java cassandra

我们遇到了连续运行在Cassandra中更新计数器的java应用程序的问题。通过监视服务器的负载,我们看不到与负载的任何相关性。查询非常不变,因为它们仅在8个不同的表中更新值。 java应用程序每分钟都会触发数千个查询(可能是20k甚至50k查询),但偶尔会有一些查询失败。当发生这种情况时,我们将它们与异常消息一起写入文件。这条消息总是如此  Cassandra timeout during write query at consistency ONE (1 replica were required but only 0 acknowledged the write)

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

  • 将java应用程序中的重试策略更改为DefaultRetryPolicy而不是FallthroughRetryPolicy,以使客户端在失败时重试查询。
  • 将Cassandra节点上的write_request_timeout_in_ms设置从标准值2000更改为4000,然后更改为10000

这些操作减少了失败查询的数量,但仍然会发生。从每小时执行的数百万条查询中,我们可以看到在24小时内发生的大约2000次失败查询。所有都具有上面列出的相同例外,并且它们在不同时间发生。

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

一些事实:

  • 我们运行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 Runtime Environment (build 1.7.0_76-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)
  • 6个Cassandra节点在裸机上运行,​​具有以下规格:
    • 存储是raid 5中的一组SSD。
    • 每个节点都有2x(6核)Intel Xeon E5-2620 CPU的@ 2.00GHz(总硬件线程数为24)。
    • RAM大小为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};

示例表(它们看起来都很相似)

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'};

1 个答案:

答案 0 :(得分:2)

许多评论:

  1. 首先针对Cluster配置,您应指定本地DC名称
  2. 您应该使用 LOCAL_ONE 而不是 ONE 来保持一致性级别以增强数据位置
  3. 请勿更改write_request_timeout_in_ms值。你只是在地毯下扫描问题,你真正的问题不是超时设置
  4. 您的复制因子是什么?
  5. Every minute the java applications fires thousands of queries (can be 20k or even 50k queries) - >简单的数学给出了每个节点~300次插入/秒,假设RF = 1。它不是那么大,但您的插入可能受到硬件的限制。什么是CPU配置(内核数)和磁盘类型(旋转磁盘或SSD)?
  6. 您是否限制了异步插入?例如。在一批N个插入物中点燃那些并等待群集呼吸。请参阅我的答案以获取限制:What is the best way to get backpressure for Cassandra Writes?