与MongoDB相比,Apache Cassandra写的原因是如此之慢,Redis& MySQL的

时间:2014-03-02 13:15:07

标签: mongodb cassandra cassandra-2.0 nosql

我最近开始为客户尝试一些noSQL原型。他们有一个实时应用程序,它可以执行大量插入操作,但读取次数较少(目前他们正在使用MySql并希望尝试一些noSQL解决方案)

周末我尝试将Cassandra 2.0,MongoDB 2.4.9和Redis与普通的Mysql 5.5 DB进行比较。所有都在我的Windows i3核心2.30 Ghz / 8GB RAM笔记本电脑上运行,所以没有高端花式机。

表结构如下所示。虽然它是MySql DESC,但Cassandra具有相同的结构,而在MongoDb中它存储为JSON / BSON,但具有相同的结构和索引。所有三个数据库都有两个索引(oneway_id和twoway_id)。

结构(适用于所有四个数据库)

+--------------+---------------------+
| Field        | Type                |
+--------------+---------------------+
| tmstamp      | bigint(20) unsigned |
| field_1      | bigint(20) unsigned |
| field_2      | varchar(64)         |
| field_3      | varchar(64)         |
| field_4      | tinyint(3) unsigned |
| field_5      | bigint(20) unsigned |
| field_6      | varchar(25)         |
| field_7      | varchar(15)         |
| field_8      | varchar(15)         |
| field_9      | varchar(15)         |
+--------------+---------------------+

数据库/环境详情

  • MySql 5.6(64位),带有mysql java连接器5.1.28
  • 带有datastax 2.0 Java驱动程序的Apache Cassandra 2.0
  • MongoDB 2.4.6 with mongo Java driver 2.12.0
  • 在Linux机器上运行Redis 2.8.17
  • Oracle Java 1.6(64位)
  • Microsoft Windows 7(64位)
  • Intel i3核心2.30 Ghz处理器
  • 8GB RAM

创建了一个简单的java测试用例,这些是我得到的结果(尽管不是一致的数字,但是延迟几乎是一样的):

100,000条记录

  • MySql 1000,000 - 46秒
  • Cassandra - 54秒
  • MongoDb - 2秒

500,000条记录

  • MySql 1000,000 - 142秒
  • Cassandra - 299秒
  • MongoDb - 41秒

1,000,000条记录

  • MySql 1000,000 - 349秒
  • 卡桑德拉 - 699秒
  • MongoDb - 51秒
  • Redis - 34秒
  

我的问题是为什么卡桑德拉需要这么长时间才能获得如此小的优势   简单的表插入?

在Cassandra中,我尝试了内联循环sql插件和放大器。批量插入。有趣的是批量插入需要更多时间。我为批量插入而遵循的文件是:

http://www.datastax.com/dev/blog/client-side-improvements-in-cassandra-2-0

我不想使用 asyncExecute ,因为它没有给我准确的插入时间。

我使用的批量插入是这样的(比正常插入需要更多的时间)

PreparedStatement ps = session.prepare("INSERT INTO some_table (val_1, val_2, val_3, val_4) VALUES (?, ?, ?, ?)");
BatchStatement batch = new BatchStatement();

//for loop start
batch.add(ps.bind(uid, mid1, title1, body1));
//for loop end

session.execute(batch);

内联循环我使用insert就是这样

String sqlInsert = "INSERT INTO some_table (val_1, val_2, val_3, val_4) VALUES (";

// for loop start

sqlInsert += uid+", "+", "+mid1+", "+title1+", "+body1+")";
session.execute(sqlInsert);

// for loop end
  

现在为什么Cassandara比mysql慢,更重要的是 - 为什么是   MongoDB比Cassandra快得多?我真的希望我这样做   有什么不对吗?

     

有没有办法可以像MongoDB那样将JSON / BSON对象直接插入Cassandra?一世   猜猜可能会让它变快?有些专家可以帮助我   这个?如果没有答案,我会得出结论,MongoDB比Cassandra更好!

1 个答案:

答案 0 :(得分:16)

您的代码使用的是串行插入。每个插入必须等待前一个插入完成,并在下一个插入开始之前返回确认。这是对可以处理多个传入连接的任何数据库进行基准测试的不良方法。如果你真的不想使用execute_async(正确的方法),你应该编写一个多线程压力程序,以便插入不阻塞(在客户端)并且你真的受到Cassandra节点的限制。基本上你所看到的是客户端程序运行的速度而不是数据库的能力。

博客文章感兴趣点:

http://www.datastax.com/dev/blog/how-not-to-benchmark-cassandra

  

正确的负载生成只有两个原则:

     

Feed Cassandra足够的工作在不同的机器上生成工作负载   而已!但它经常做错了,来自极端情况   与Cassandra 在同一台笔记本电脑上运行的单线程客户端   Python全局解释器锁更微妙的问题。它似乎   就像二元搜索一样,建立一个好的东西是非常困难的   负载发生器。如果可能的话,避免卷起自己的诱惑   并使用经过实战考验的东西。