pymongo.errors.CursorNotFound: Cursor not found
故事背景:先從數據庫中取得所有數據 db['test'].find(),然后對結果進行for循環,但是當do_something函數耗時過長,在cursor上長時間沒有進行操作,引發cursor在mongodb服務端超時。
分析原因:你在用 db.collection.find() 的時候,它返回的不是所有的數據,而實際上是一個“cursor”。它的默認行為是:第一次向數據庫查詢 101 個文檔,或 1 MB 的文檔,取決於哪個條件先滿足;之后每次 cursor 中的文檔用盡后,查詢 4 MB 的文檔。另外,find() 的默認行為是返回一個 10 分鍾無操作后超時的 cursor。如果我一個 batch 的文檔十分鍾內沒處理完,過后再處理完了,再用同一個 cursor id 向服務器取下一個 batch,這時候 cursor id 當然已經過期了,這也就能解釋為啥我得到 cursor id 無效的錯誤了。
思路總結:默認 mongo server維護連接的時間窗口是十分鍾;默認 單次從 server獲取數據是101條或者 大於1M小於16M的數據,所以默認情況下,如果10分鍾內未能處理完數據,則拋出該異常。
解決方案:
1. 修改每批次獲取數據量的條數,即batch size:
collection.find(condition).batch_size(10)
批量數需 估算十分鍾內能處理的數據量
2.設置no_cursor_timeout = True,永不超時,游標連接不會主動關閉,需要手動關閉
cursor=db.images.find({}{'_id':0},no_cursor_timeout=True)
筆者建議:感覺方案二不是很妥當,假設執行do_something的過程中,邏輯上報錯,直接跳出,那么此時游標仍然處於打開的狀態?