带有DataStax Java驱动程序的单个多线程Java客户端,用于Apache Cassandra,不使用系统资源

时间:2016-04-25 15:45:50

标签: cassandra cassandra-2.0 datastax datastax-enterprise datastax-java-driver

对于使用适用于Apache Cassandra的DataStax Java驱动程序的多线程,高吞吐量低延迟Java客户端的最佳设置,我表示感谢。我不赞赏“滚动你自己”的基准测试,但是这项任务也是为了实现高TPS的实际应用的概念验证。

设定:

客户端:Java 8客户端,可配置数量的多线程执行程序线程(由lmax disruptor推动), cassandra-driver-core-3.0.0.jar ,运行在Redhat 6.3,24核心机器上,dl360s 服务器端:3个节点Cassandra集群( apache-cassandra-2.2.4 ,在Redhat 6上使用Java 8),复制因子= 3,在Redhat 6.3上运行,24核机器dl360s

测试

使用cl = LOCAL_QUORUM测试从相对简单的模式开始,每秒测试 3.5K INSERTS和6.5K READS ,延迟分别大约为6和2毫秒,CPU使用率大约为20整个盒子里的百分比。

问题

然而,我无法解决的问题是 - 当我创建我的加载客户端应用程序的多个单独实例时,我可以实现跨实例的显着更高的TPS总和,以及比我在单个内容中实现的更高的CPU使用率JVM 即可。这表明我的Java客户端应用程序既不是IO也不是CPU绑定,服务器端的Cassandra集群也不是瓶颈。同样,当我发出Cassandra调用时,我获得了更高的TPS,从而让我相信应用程序没有遭受任何争用。

所以我的问题是:这是一个常见的问题 - 使用DataStax Java Driver for Apache Cassandra的单个Java客户端在某种程度上限制了它的吞吐量吗?如果没有,任何人都可以指出我正确的方向进行调查。

我测试了多个序列(READ和WRITE),还有execute和executeAsync,并且可变数量的并发线程。正如您所期望的那样,我使用executeAsync看到更高的数字,但在我的应用程序中仍然存在相同的限制。

我已经使用多个连接池设置进行了测试,并尝试为每个客户端应用程序创建/构建1个群集实例,并为每个应用程序创建/构建多个群集实例,并尝试改变CoreConnections,maxRequestsPerConnection和newConnectionThreshold值,但迄今为止没有成功。

我当前最好的结果是有50个执行程序线程,5个实例; MaxRequestsPerConnection(L)= 1024; ; NewConnectionThreshold(L)= 800; CoreConnectionsPerHost(L)= 20

这只产生~4 / 4 TPS BUT只使用了18%的CPU,当我启动一个单独的应用程序实例时,我使用30%的CPU实现了7.5K TPS,但是我无法在保存JVM中实现这个7.5K < / p>

代码:创建群集

    LoadBalancingPolicy tokenAwarePolicy =
            new TokenAwarePolicy(new RoundRobinPolicy());
    Cluster cluster = Cluster.builder()
            .addContactPoints(node)
            .withLoadBalancingPolicy(tokenAwarePolicy)
            .withPoolingOptions(new PoolingOptions()) // Have tried various options here
            .build();

代码:准备声明(一次)

        String insertSqlString =  "INSERT INTO " + keySpaceName + ".test_three ("
                + "user_id, field_a, field_b, field_c, field_d) values "
                + "( ?, ?, ?, ?);";
        statementInsertDataTablePS = session.prepare(insertSqlString);
        statementInsertDataTablePS.setConsistencyLevel(configuredConsistencyLevel); //2

代码:执行

    BoundStatement boundStatement = new BoundStatement(statementInsertDataTablePS);

  session.executeAsync(boundStatement.bind(
            sequence,  // userID
            sequence + "value_for_field_a", 
            sequence + "value_for_field_b", 
            sequence + "value_for_field_c", 
            sequence + "value_for_field_d") );

0 个答案:

没有答案