我正在使用 MongoDB 测试 Node.js 的性能。我知道这些中的每一个都很好,独立于另一个,但我正在尝试一些测试来感受它们。我遇到了这个问题,但我无法确定来源。
问题
我正在尝试在单个 Node.js 程序中插入 1,000,000 条记录。 它绝对是爬行。我们说的是 20 分钟的执行时间。无论是我的 Mac 还是 CentOS,都会发生这种情况,尽管两者之间的行为略有不同。它最终会完成。
效果类似于交换,尽管不是(内存永远不会超过 2 GB)。只有 3 个连接打开到 MongoDB,并且大部分时间没有插入数据。它似乎在进行大量上下文切换,并且 Node.js CPU 内核已达到极限。
效果与this thread中提到的类似.
我尝试使用 PHP 进行同样的操作,并在 2-3 分钟内完成。没有戏剧性。
为什么?
可能的原因
我目前认为这要么是 Node.js 套接字问题,要么是 libev 在幕后发生的问题,要么是其他一些 node-mongodb-native 问题。我可能完全错了,所以我在这里寻找一些指导。
至于其他 Node.js MongoDB 适配器,我已经尝试过 Mongolian,它似乎要对文档进行排队以便批量插入它们,但最终会耗尽内存。所以就这样了。 (旁注:我也不知道为什么要这样做,因为它甚至没有接近我的 16 GB 盒子限制——但我没有费心去进一步调查。)
我应该提一下,我确实测试了一个有 4 个工作人员的主/工作集群(在四核机器上),它在 2-3 分钟内完成。
代码
这是我的 Node.js CoffeeScript 程序:
mongodb = require "mongodb"
microtime = require "microtime"
crypto = require "crypto"
times = 1000000
server = new mongodb.Server "127.0.0.1", 27017
db = mongodb.Db "test", server
db.open (error, client) ->
throw error if error?
collection = mongodb.Collection client, "foo"
for i in [0...times]
console.log "Inserting #{i}..." if i % 100000 == 0
hash = crypto.createHash "sha1"
hash.update "" + microtime.now() + (Math.random() * 255 | 0)
key = hash.digest "hex"
doc =
key: key,
foo1: 1000,
foo2: 1000,
foo3: 1000,
bar1: 2000,
bar2: 2000,
bar3: 2000,
baz1: 3000,
baz2: 3000,
baz3: 3000
collection.insert doc, safe: true, (error, response) ->
console.log error.message if error
下面是大致等效的 PHP 程序:
<?php
$mongo = new Mongo();
$collection = $mongo->test->foo;
$times = 1000000;
for ($i = 0; $i < $times; $i++) {
if ($i % 100000 == 0) {
print "Inserting $i...\n";
}
$doc = array(
"key" => sha1(microtime(true) + rand(0, 255)),
"foo1" => 1000,
"foo2" => 1000,
"foo3" => 1000,
"bar1" => 2000,
"bar2" => 2000,
"bar3" => 2000,
"baz1" => 3000,
"baz2" => 3000,
"baz3" => 3000
);
try {
$collection->insert($doc, array("safe" => true));
} catch (MongoCursorException $e) {
print $e->getMessage() . "\n";
}
}
最佳答案
听起来您遇到了 V8 中的默认堆限制。我写了一个blog post关于取消此限制。
垃圾收集器可能会发疯并占用 CPU,因为它会不断执行直到您低于 1.4GB 限制。
关于php - node-mongodb-native 的插入性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11111281/
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0
我正在寻找一个用ruby演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent
如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:
我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?
我已经通过提供MagickWand.h的路径尝试了一切,我安装了命令工具。谁能帮帮我?$geminstallrmagick-v2.13.1Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingrmagick:ERROR:Failedtobuildgemnativeextension./Users/ghazanfarali/.rvm/rubies/ruby-1.8.7-p357/bin/rubyextconf.rbcheckingforRubyversion>=1.8.5...yescheckingfor/
所以,Ruby1.9.1现在是declaredstable.Rails应该与它一起工作,并且正在慢慢地将gem移植到它。它具有native线程和全局解释器锁(GIL)。自从GIL到位后,原生线程是否比1.9.1中的绿色线程有任何优势? 最佳答案 1.9中的线程是原生的,但它们被“放慢了速度”,一次只允许一个线程运行。这是因为如果线程真的并行运行,它会混淆现有代码。优点:IO现在在线程中是异步的。如果一个线程阻塞在IO上,那么另一个线程将继续执行直到IO完成。C扩展可以使用真正的线程。缺点:任何非线程安全的C扩展都可能存在使用Thre
在我的用户模型中,我有一堆属性,例如is_foos_admin和is_bars_admin,它们决定允许用户编辑哪些类型的记录。我想干掉我的编辑链接,目前看起来像这样:'edit'ifcurrent_user.is_foos_admin?%>...'edit'ifcurrent_user.is_bars_admin?%>我想做一个帮助程序,让我传入一个foo或bar并返回一个链接来编辑它,就像这样:助手可能看起来像这样(这不起作用):defedit_link_for(thing)ifcurrent_user.is_things_admin?link_to'Edit',edit_poly
我有以下现有的Dog对象数组,它们按age属性排序:classDogattr_accessor:agedefinitialize(age)@age=ageendenddogs=[Dog.new(1),Dog.new(4),Dog.new(10)]我现在想插入一条新的狗记录,并将它放在数组中的正确位置。假设我想插入这个对象:another_dog=Dog.new(8)我想把它插入到数组中,让它成为数组中的第三项。这是一个人为的示例,旨在演示我特别想如何将一个项目插入到现有的有序数组中。我意识到我可以创建一个全新的数组并重新对所有对象进行排序,但这不是我的目标。谢谢!