现在我正在运行一个ec2集群m3xlarge,并且正以大约2700rows /秒的速度加载到cassandra中。我发现了这篇文章Cassandra: Load large data fast,但它似乎有点过时,并没有说明如何加载已映射数据的csv。
您可以使用sstableloader加载映射数据吗?另外,如果我增加ec2实例的规格(更多ram,cpu,iops),那会增加cql的加载速度吗?
答案 0 :(得分:1)
如果您想隔离性能问题,从有效的方法开始总是一个好主意... 尝试执行这个简单的测试(此测试假设您在localhost端口9042上运行cassandra。
@Test
public void testThroughput() throws Exception {
Cluster cluster = Cluster.builder()
.addContactPoint("localhost")
.withProtocolVersion(ProtocolVersion.V2)
.withPort(9042)
.build();
Session session = cluster.connect();
session.execute("CREATE KEYSPACE IF NOT EXISTS test" +
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}");
session.execute("USE test");
session.execute("CREATE TABLE IF NOT EXISTS parent_children (" +
" parentId uuid," +
" childId uuid," +
" PRIMARY KEY (parentId, childId))");
UUID parent = UUID.randomUUID();
long beforeInsert = System.currentTimeMillis();
List<ResultSetFuture> futures = new ArrayList<>();
int n = 1000000;
for (int i = 0; i < n; i++) {
UUID child = UUID.randomUUID();
futures.add(session.executeAsync("INSERT INTO parent_children (parentId, childId) VALUES (?, ?)", parent, child));
if (i % 10000 == 0) {
System.out.println("Inserted " + i + " of " + n + " items (" + (100 * i / n) + "%)");
}
}
//to be honest with ourselves let's wait for all to finish and succeed
List<ResultSet> succeeded = Futures.successfulAsList(futures).get();
Assert.assertEquals(n, succeeded.size());
long endInsert = System.currentTimeMillis();
System.out.println("Time to insert: " + (endInsert-beforeInsert) + "ms; " + 1000 * n/(endInsert-beforeInsert) + " per second");
cluster.close();
}
自动创建&#34;测试&#34;具有单个父/子表的键空间,并使用executeAsync将1M行插入同一分区。 (如果需要,您可以轻松修改它以插入多分区)。
你得到了多少?在我的Mac Pro笔记本电脑上,我每秒获得25k。 我很确定这会随着cassandra节点的数量线性扩展,但只有当你插入多个分区时(最终你可能还需要增加并发客户端的数量)。
答案 1 :(得分:0)
这很大程度上取决于你的数据模型对于一行是什么&#34; 2700rows / sec&#34;但是你应该能够通过一个简单的应用程序获得每秒多次写入10x-50x。关于你的应用程序,为什么它如此缓慢可能有些东西。你在使用异步写入吗?
在许多情况下,编写数据比使用批量加载程序选项更快。但是来自http://www.datastax.com/dev/blog/using-the-cassandra-bulk-loader-updated
的一些例子// Prepare SSTable writer
CQLSSTableWriter.Builder builder = CQLSSTableWriter.builder();
// set output directory
builder.inDirectory(outputDir)
// set target schema
.forTable(SCHEMA)
// set CQL statement to put data
.using(INSERT_STMT)
// set partitioner if needed
// default is Murmur3Partitioner so set if you use different one.
.withPartitioner(new Murmur3Partitioner());
CQLSSTableWriter writer = builder.build();
另一种选择是在cqlsh中使用copy命令,但我不确定它是多么高效 http://docs.datastax.com/en/cql/3.1/cql/cql_reference/copy_r.html
cqlsh> COPY music.imported_songs from 'songs-20140603.csv';
我会首先尝试优化您的客户端,因为2700w / s的速度非常慢。