我需要在3个节点的Cassandra(2.1.11)集群中写入近1000万条记录,复制因子为1, 我的步骤几乎与datastax的Java Driver:
相同 String insert_query = "insert into " + keyspace + "." + tblName
+ " (a, b, c, d,"
+ "e, f, g, h, i, j,"
+ "k, l, m, n) VALUES "
+ "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
List<ResultSetFuture> futures = new ArrayList<ResultSetFuture>();
PreparedStatement statement = session.prepare(insert_query);
BoundStatement bind = null;
int max = 5000000 or 6000000 or 7000000
for(int i = 0; i < max ; i++) {
bind = statement.bind(
id,
...
null,
null,
null
);
ResultSetFuture resultSetFuture = session.executeAsync(bind);
futures.add(resultSetFuture);
} //for
for(ResultSetFuture future : futures){
future.getUninterruptibly(15000, TimeUnit.MILLISECONDS);
}
然后,我的应用程序在具有16个核心的机器下运行,我监视进程'CPU消耗:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25502 pengcz 20 0 30.8g 27g 19m S 1263.7 25.8 104:28.82 java
我发现CPU使用率太高(1263.7%
),我发现高CPU使用时间更长,或者如果我写了更多记录,甚至写入失败。
我不知道我的错误步骤会导致这种情况吗?任何建议将不胜感激!
答案 0 :(得分:3)
您实际上是在同时提交5,6或700万个请求,然后等待所有请求立即完成。由于您构建的期货列表最多可达请求数,因此您不仅要提交许多请求,还要使用大量内存跟踪这些响应。我想在不等待响应的情况下提交许多请求会产生大量的CPU生成请求有效负载并将其写入网络,此外还有不断增加的GC压力使这些期货保持在一个巨大的列表中。
你应该做的只是一次只有这么多的飞行请求(500可能?),等待它们完成,然后提交下一组等等。肯定有更好和更优化的技术,而且这也不能很好地处理错误情况,但它应该降低你的内存占用并防止你用许多请求锤击C *。以下是一个示例:
String insert_query = "insert into " + keyspace + "." + tblName
+ " (a, b, c, d,"
+ "e, f, g, h, i, j,"
+ "k, l, m, n) VALUES "
+ "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
List<ResultSetFuture> futures = new ArrayList<ResultSetFuture>();
PreparedStatement statement = session.prepare(insert_query);
BoundStatement bind = null;
int max = 1000000;
for (int i = 0; i < max; i++) {
bind = statement.bind(i,
null,
null,
null
);
ResultSetFuture resultSetFuture = session.executeAsync(bind);
futures.add(resultSetFuture);
if (futures.size() % 500 == 0 || i == max - 1) {
for (ResultSetFuture future : futures) {
future.getUninterruptibly(15000, TimeUnit.MILLISECONDS);
}
futures.clear();
}
}
如需进一步指导,请查看Asynchronous queries with the Java driver。