2011-04-17 155 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");