2015-10-14 59 views
3

我跑很長的MongoDB的查詢是這樣的:經過幾次PHP失去MongoDB的光標,儘管長期超時

foreach($xyz->find(...)->timeout(24 * 60 * 60 * 1000)->maxTimeMS(24 * 60 * 60 * 1000) as $document) { 
    ... 
} 

但是,儘管這些24小時超時客戶端和服務器,腳本退出了MongoCursorException分鐘:

本地主機:27017:找不到光標置於收集XYZ

我在PHP 5.4與V1.6.10 MongoDB的驅動程序。數據庫是mongoDB 3.0.4。 PHP將連接到一個mongos實例,集合xyz被分片。

任何想法可能會導致此異常?

回答

1

似乎有更多的超時並不是PHP都支持(還)。其中之一是maxIdleTimeMS

在移除和關閉之前,連接在池中保持空閒的最大毫秒數。

我的情況是,由於數據庫有時很忙,這個長時間運行的查詢空閒了很長時間,所以它的光標在服務器端下降了。

設置這個參數會一直幫助,但因爲它是不可用的,我發現有什麼解決的問題是降低batch size

$cursor->batchSize(-20) 

在這個例子中,最多20個文檔之間傳遞服務器和每個批次的客戶端。這可以降低連接閒置時間過長的可能性。當然,確切的值取決於數據庫的負載,需要多長時間處理每個文檔等。

1

我不得不說,我有類似的經歷,我有一個集合,我通過

$items = $col -> find(['data' => 'OK']); 
$items->timeout(-1); 
$items->maxTimeMS(3600*1000); 

但通過

foreach($items as $item) 
{ 
    ///... processing 
} 

走線槽照顧低谷大約12後 - 15分鐘後,我得到同樣的錯誤

could not find cursor over collection 

在收集,還有約15條記錄,以及有趣的˚F行爲是,在處理123479記錄之後總是出現錯誤,而不管第123480記錄的內容以及處理相應記錄花費的時間(處理記錄所需的時間可以根據內容而變化)。

由於找不到任何錯誤原因,經過多次嘗試改進mongo設置(包括升級PHP驅動程序)後,我現在正在批量執行整個過程,從而防止丟失遊標。它工作正常,但是,我想知道更清潔的解決方案。

0

我有同樣的問題。我曾試圖與兩位車手的最後一個版本,

發現方法返回一個遊標。我不確定這個工作的方式,但是這個光標沒有所有的文檔。需要詢問mongo在時間連線斷開後獲取下一個答案。

的解決方案,我是使用的方法的MongoDB\Driver\Cursor(驅動mongodb

toArray這返回數組的所有文件。我有一批能夠處理超過10萬個文檔的問題。