使用Ruby进行MongoDB基准测试

时间:2014-07-13 08:20:55

标签: ruby-on-rails ruby performance mongodb mongodb-query

我为早期创业公司工作,目前我们正在选择托管的MongoDB服务。我们的要求相当简单,我们需要一个“中型”Mongo服务器,其中每日作业将导入大约100K JSON对象(附加报告)。受这些片段(link)的启发,我编写了一个简单的基准测试工具(链接here)。但令我惊讶的是,结果非常缓慢(使用托管的MongoDB服务大约需要2秒/插入)。我确信,我的实施有问题。你们中的任何人都可以帮助我吗?你如何使用Ruby对Mongo INSERT操作进行基准测试。

1 个答案:

答案 0 :(得分:2)

您的代码看起来很好,并且在主轴磁盘上的适度mongod VM
2 vcpu@3.3ghz / 512MiB / VDI文件上运行良好。

counter: 20 timer: 0.17177268
counter: 40 timer: 0.169776753
counter: 60 timer: 0.170003466...

要演示网络延迟对这些结果的影响,请向mongo服务器界面添加100毫秒的延迟。

sudo tc qdisc add dev eth1 root handle 1:0 netem delay 100ms

这导致每批次的时间约为2秒:

counter: 20 timer: 2.17708192
counter: 40 timer: 2.080139019
counter: 60 timer: 2.074216244


Mongo版本< 2.6

要检查的另一件事是您正在测试的服务是否运行早于2.6的服务器版本。 initialize_ordered_bulk_op方法无法按照您的预期执行< 2.6。代码仍然有效,但每个insert都需要往返mongo实例。这可能不是这种情况,因为您需要大约5毫秒的回程才能获得~2秒的结果。您可以打开MongoClient的日志记录以检查以防万一...

require 'logger'
logger = Logger.new(STDOUT)
db = MongoClient.new(HOST, PORT, { :logger => logger ).db(DBNAME)

如果您的20个插入中的每一个都有一个日志行而不是批处理的一个,那么您需要寻找另一个服务。

MONGODB (XX.Xms) dummyDB['dummyDB.dummyCollection'].insert...


延迟不好

在任何情况下,如果您使用外部托管数据库,网络延迟将在您的系统中发挥重要作用。

从基础架构到Mongo服务的往返时间将为每个事务时间增加开销。因此,与大批量的多线程测试相比,小批量的单线程测试将在整体时间上受到影响。

使用您的测试设置值并以100ms往返行程为例

20000 inserts / 20 per batch * 100ms delay = 100 seconds total.   

Reworking your code a little可让您查看各种批量操作尺寸在100毫秒延迟时产生的差异。

Bulk Insert batch of [5]
counter[500] timer[10.2571]
counter[1000] timer[10.2656]

Bulk Insert batch of [20]
counter[500] timer[2.6140]
counter[1000] timer[2.6152]

Bulk Insert batch of [50]
counter[500] timer[1.0550]
counter[1000] timer[1.0543]

Bulk Insert batch of [100]
counter[500] timer[0.5396]
counter[1000] timer[0.5380]

Bulk Insert batch of [500]
counter[500] timer[0.3282]
counter[1000] timer[0.2300]

与您的mongodb基准测试一起,收集您正在考虑的任何服务的延迟信息是一个好主意。您可以使用类似mtr的内容来监控网络,或者只需在较长时间内从MongoClient记录器中提取每个查询的数据。延迟的峰值和差异可能比稍微慢一致的值更糟,因为它们会给系统增加不可预测性。