2011-04-17 129 views
4

我目前有一些代码需要为数千名用户对每个用户执行多次更新,根据他们为了跟踪正在执行的操作而采取的操作增加计数器。每个动作由需要更新计数的子动作组成。这些需要每天跟踪。如何在PHP中批量插入mongodb?

所以我存储“动作”:“actionName”,“天”:一天,“算”:计算,每天的行动(如从外部网页来料,开始游戏,通过退出停止比赛,以级联许多游戏的游戏名称)。

每一天,我收到了几千行(每独特的动作之一)加入其几十万次,每天增加计数更新。

相关的代码如下所示(创建动作阵列不包括)。

$m = new Mongo(); 
$db = $m->actionsDB; 
$collection = $db->action_count; 

foreach ($arr as $action) { 
    $collection->update(array("action" => $action, "day" => $day),array('$inc' => array("count" => 1)),array("upsert" => true));) 
} 
$collection->ensureIndex(array("action" => 1, "day" => -1)); 

系列上的动作和子动作所进行的更新的一个例子是: startGame,20110417; startGameZork,20110417; startGameZorkWindows,20110417

问题似乎是,在服务器上运行此代码时,shell中的mongo命令会排队等待。

目前我不能确定,为什么,我猜有可能是每秒这么多的更新性能问题。

我想知道的是如何提高性能?我对mongo很陌生,所以不能完全确定哪些选项可用。我查看了PHP的batchInsert,但是我看不到有关执行batchUpdate的任何提及(所以不是更新,而是创建一个数组来保存我当前更新的所有数据,然后在一次到DB中执行batchUpdate)。

蒙戈驱动程序版本为1.2.0,因此持久连接是默认。

编辑:db.serverStatus()之前,期间和之后在〜每秒1600次更新(30秒)。 Test Data

+0

好奇心驱使我。如果服务器现在正在运行,你可以在shell'db.serverStatus()'中运行吗?并更新结果?虽然我对mongodb不太熟悉,但队列问题很可能是由于锁定机制或可用连接的数量。 – Khez 2011-04-17 04:27:09

+0

服务器正在运行,但现在我们禁用了mongo更新代码。似乎没有影响客户的速度,但希望确保周末没有问题。 – BongoFlat 2011-04-17 04:45:29

+0

“”“目前我不确定为什么,我猜可能会出现性能问题,每秒有很多更新。”“” - 除非您提供基准测试,否则会疯狂索赔。编写一个基准,他们回来了坚实的数字。没有证据提出索赔是不值得质疑的。 – 2011-04-17 04:49:35

回答

1

有更新/ upserts没有内置的配料。您只能通过调整查询表达式并添加一些用于“模拟”批处理的进一步过滤器来限制文档更新。 MongoDB在这里不会帮你。更新/ Upserts是一个或全部。

+0

了解,谢谢你的信息。 – BongoFlat 2011-04-17 05:56:02

+0

接受并投票请 – 2011-04-17 07:31:53

+2

稍微不正确。有一个mongoimport批处理插件。但是不能使用更新运算符,如$ inc,$ set,$ addToSet等。 – Tom 2012-03-27 06:15:51

1

如果您有机会将数据存储在文件(json或csv)中,则可以尝试使用命令行mongoimport实用程序插入数据。

这样你可以使用--upsert标志更新/插入文件,如果他们已经存在/新

例如从PHP:

exec("mongoimport --db <bdname> --collection <collection_name> --jsonArray --upsert --file $data_file");