5

我最近开始为客户尝试一些 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
  • 带有 mongo Java 驱动程序 2.12.0 的 MongoDB 2.4.6
  • 在 linux 机器上运行的 Redis 2.8.17
  • Oracle Java 1.6(64 位)
  • 微软视窗 7(64 位)
  • 英特尔 i3 核心 2.30 Ghz 处理器
  • 8GB 内存

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

100,000 条记录

  • MySql 1000,000 - 46 秒
  • 卡桑德拉 - 54 秒
  • MongoDb - 2 秒

500,000 条记录

  • MySql 1000,000 - 142 秒
  • 卡桑德拉 - 299 秒
  • MongoDb - 41 秒

1,000,000 条记录

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

我的问题是,为什么 Cassandra 需要这么长时间来插入这么小而简单的表格?

在 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);

我使用的内联循环插入是这样的

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 更好!

4

1 回答 1

16

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

兴趣点的博客文章:

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

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

为 Cassandra 提供足够的工作量 在不同的机器上生成工作负载 就是这样!但它经常做错,从在与 Cassandra 相同的笔记本电脑上运行单线程客户端的极端情况,到 Python 全局解释器锁的更微妙的问题。看起来就像二分搜索一样,构建一个好的负载生成器非常困难。如果可能的话,避免自己动手的诱惑,并使用经过实战考验的东西。

于 2014-03-02T20:42:49.727 回答