用cassandra快速加载数据

时间:2015-08-26 13:19:24

标签: cassandra

现在我正在运行一个ec2集群m3xlarge,并且正以大约2700rows /秒的速度加载到cassandra中。我发现了这篇文章Cassandra: Load large data fast,但它似乎有点过时,并没有说明如何加载已映射数据的csv。

您可以使用sstableloader加载映射数据吗?另外,如果我增加ec2实例的规格(更多ram,cpu,iops),那会增加cql的加载速度吗?

2 个答案:

答案 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的速度非常慢。