2013-02-04 50 views
6

我們正在使用MongoDB 2.2.0。數據庫包含大約51GB的數據(目前),我想對我們迄今爲止收集的用戶數據做一些分析。問題是,這是現場機器,我們目前無法承受另一個奴隸。我知道MongoDB有一個讀鎖,可能會影響任何特別是在複雜查詢時發生的寫操作。有沒有辦法告訴MongoDB以最低優先級處理我的(特定)查詢?無鎖mongodb讀取

+0

寫的能效,但讀,但讀的這麼快,它的動力是這樣的,有一個讀影響寫opreation的1/1000000-機會。更像是使用JS鎖和錯誤的寫操作會導致查詢問題。至於告訴MongoDB有關優先級,我不相信有一種方法 – Sammaye

回答

6

在MongoDB中讀取和寫入操作互不影響。讀鎖是共享的,但是讀鎖可以阻止寫鎖被獲取,當然在寫鎖被保持時沒有其他的讀或寫操作正在發生。 MongoDB操作會定期產生,以防止其他線程等待鎖死。你可以閱讀更多關於here的詳細信息。

這對您的用例意味着什麼?因爲沒有辦法告訴MongoDB在沒有讀鎖的情況下訪問數據,也沒有辦法優先處理這些請求(至少現在還不是)讀取是否會顯着影響寫入的性能取決於您有多少「空間」在寫入活動正在進行時可用。

一個建議我可以是計算時如何運行的分析,而不是掃描整個數據集(即做了所有歷史數據聚集查詢)儘量短的時間片運行的更小的聚集查詢。這將完成兩件事:

  1. 讀取作業將會更短,因此可以更快完成,這將使您有機會評估查詢對「實時」性能的影響。
  2. 你不會拉的所有舊的數據到RAM一次 - 由間隔這些分析查詢隨着時間的推移,你將盡量減少它的影響將會對當前的寫入性能。

根據你不能獲得另一臺服務器的承受能力 - 你可能會考慮獲得一個短暫的AWS實例,這個實例可能不是很強大,但可以運行一個長的分析查詢,你的數據集。將它作爲數據副本時要小心 - 在生產系統中完全同步會給它帶來沉重的負擔(更有效的方法是使用最近的備份/文件快照恢復)。

+0

感謝您的回答。我認爲切片部分是一個好主意。我會給你一個鏡頭。我們有_id字段的索引,基於這個字段切片的最好方法是什麼?我正在考慮編寫一個'.js'文件,它將接受切片參數,然後通過shell腳本或其他東西來觸發。糾正我,如果我錯了,但我猜在mongo運行一個JavaScript文件將創建一個整個腳本的鎖,因此調用JavaScript的shell腳本。這樣我就可以運行一個調用mongo 100次的shell腳本,每次處理1%的數據 –

+0

運行一個JavaScript文件將不會創建任何鎖(它只是調用沒有鎖的shell)。我假設js文件將包含您想運行的實際查詢(參數化爲範圍?)前四個字節的_id字段表示創建ObjectId值的日期時間,因此任何順序分區都可以工作。 –

2

這種操作是最好的一個副本集的奴隸離開。首先,可以共享讀鎖以允許一次讀取多次,但寫入鎖將阻止讀取。而且,雖然您不能優先查詢,但mongodb會產生長時間運行的讀/寫查詢。 Their concurrency docs應該幫助

如果你買不起另一臺服務器,你可以在同一臺機器上設置一個slave,前提是你有一些備用的RAM /磁盤空間,並且你輕輕地/偶爾地使用slave。你必須小心,但是你的磁盤I/O會顯着增加。

+0

雖然你的大部分觀察是正確的,但讀鎖*做*塊寫入 - 如果存在讀鎖,則不能獲取寫鎖(否則讀不能保證是一致的!) –

+0

@AsyaKamsky他說:「讀鎖不會阻止寫入」,但他們不是嗎?我的意思是,如你所說,你如何判斷閱讀的一致性。我不確定是否很好,直接給我這個答案 – Sammaye

+0

@AsyaKamsky,我站在糾正。 – Adil