天天看點

Mongodb億級資料量的性能測試

  (所有插入都是單線程進行,所有讀取都是多線程進行)

  1) 普通插入性能 (插入的資料每條大約在1kb左右)

  2) 批量插入性能 (使用的是官方c#用戶端的insertbatch),這個測的是批量插入性能能有多少提高

  3) 安全插入功能 (確定插入成功,使用的是safemode.true開關),這個測的是安全插入性能會差多少

  4) 查詢一個索引後的數字列,傳回10條記錄(也就是10kb)的性能,這個測的是索引查詢的性能

  5) 查詢兩個索引後的數字列,傳回10條記錄(每條記錄隻傳回20位元組左右的2個小字段)的性能,這個測的是傳回小資料量以及多一個查詢條件對性能的影響

  6) 查詢一個索引後的數字列,按照另一個索引的日期字段排序(索引建立的時候是倒序,排序也是倒序),并且skip100條記錄後傳回10條記錄的性能,這個測的是skip和order對性能的影響

  7) 查詢100條記錄(也就是100kb)的性能(沒有排序,沒有條件),這個測的是大資料量的查詢結果對性能的影響

  8) 統計随着測試的進行,總磁盤占用,索引磁盤占用以及資料磁盤占用的數量

  并且每一種測試都使用單程序的mongodb和同一台伺服器開三個mongodb程序作為sharding(每一個程序大概隻能用7gb左右的記憶體)兩種方案

  其實對于sharding,雖然是一台機器放3個程序,但是在查詢的時候每一個并行程序查詢部分資料,再有運作于另外一個機器的mongos來彙總資料,理論上來說在某些情況下性能會有點提高

  基于以上的種種假設,猜測某些情況性能會下降,某些情況性能會提高,那麼來看一下最後的測試結果怎麼樣?

Mongodb億級資料量的性能測試

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank"> 從這個測試可以看出,對于單程序的方式:</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  1) mongodb的非安全插入方式,在一開始插入性能是非常高的,但是在達到了兩千萬條資料之後性能驟減,這個時候恰巧是伺服器24g記憶體基本占滿的時候(随着測試的進行mongodb不斷占據記憶體,一直到作業系統的記憶體全部占滿),也就是說mongodb的記憶體映射方式,使得資料全部在記憶體中的時候速度飛快,當部分資料需要換出到磁盤上之後,性能下降很厲害。(這個性能其實也不算太差,因為我們對三個列的資料做了索引,即使在記憶體滿了之後每秒也能插入2mb的資料,在一開始更是每秒插入25mb資料)</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  2) 對于批量插入功能,其實是一次送出一批資料,但是相比一次一條插入性能并沒有提高多少,一來是因為網絡帶寬已經成為了瓶頸,二來我想寫鎖也會是一個原因。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  3) 對于安全插入功能,相對來說比較穩定,不會波動很大,我想可能是因為安全插入是確定資料直接持久化到磁盤的,而不是插入記憶體就完事。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  4) 對于一列條件的查詢,性能一直比較穩定,别小看,每秒能有8000-9000的查詢次數,每次傳回10kb,相當于每秒查詢80mb資料,而且資料庫記錄是2億之後還能維持這個水準,性能驚人。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  5) 對于二列條件傳回小資料的查詢,總體上性能會比4)好一點,可能傳回的資料量小對性能提高比較大,但是相對來說性能波動也厲害一點,可能多了一個條件就多了一個從磁盤換頁的機會。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  6) 對于一列資料外加sort和skip的查詢,在資料量大了之後性能明顯就變差了(此時是索引資料量超過記憶體大小的時候,不知道是否有聯系),我猜想是skip比較消耗性能,不過和4)相比性能也不是差距特别大。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  7) 對于傳回大資料的查詢,一秒瓶頸也有800次左右,也就是80m資料,這就進一步說明了在有索引的情況下,順序查詢和按條件搜尋性能是相差無幾的,這個時候是io和網絡的瓶頸。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  8) 在整個過程中索引占的資料量已經占到了總資料量的相當大比例,在達到1億4千萬資料量的時候,光索引就可以占據整個記憶體,此時查詢性能還是非常高,插入性能也不算太差,mongodb的性能确實很牛。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  那麼在來看看sharding模式有什麼亮點:</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  1) 非安全插入和單程序的配置一樣,在記憶體滿了之後性能急劇下降。安全插入性能和單程序相比慢不少,但是非常穩定。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  2) 對于一個條件和兩個條件的查詢,性能都比較穩定,但條件查詢性能相當于單程序的一半,但是在多條件下有的時候甚至會比單程序高一點。我想這可能是某些時候資料塊位于兩個sharding,這樣mongos會并行在兩個sharding查詢,然後在把資料進行合并彙總,由于查詢傳回的資料量小,網絡不太可能成為瓶頸了,使得sharding才有出頭的機會。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  3) 對于order和skip的查詢,sharding方式的差距就出來了,我想主要性能損失可能在order,因為我們并沒有按照排序字段作為sharding的key,使用的是_id作為key,這樣排序就比較難進行。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  4) 對于傳回大資料量的查詢,sharding方式其實和單程序差距不是很大,我想資料的轉發可能是一個性能損耗的原因(雖然mongos位于打壓機本機,但是資料始終是轉手了一次)。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  5) 對于磁盤空間的占用,兩者其實是差不多的,其中的一些差距可能是因為多個程序都會多配置設定一點空間,加起來有的時候會比單程序多占用點磁盤(而那些占用比單程序少的地方其實是開始的編碼錯誤,把實際資料大小和磁盤檔案占用大小搞錯了)。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  雖然在最後由于時間的關系,沒有測到10億級别的資料量,但是通過這些資料已經可以證明mongodb的性能是多麼強勁了。另外一個原因是,在很多時候可能資料隻達到千萬我們就會對庫進行拆分,不會讓一個庫的索引非常龐大。在測試的過程中還發現幾個問題需要值得注意:</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  1) 在資料量很大的情況下,對服務進行重新開機,那麼服務啟動的初始化階段,雖然可以接受資料的查詢和修改,但是此時性能很差,因為mongodb會不斷把資料從磁盤換入記憶體,此時的io壓力非常大。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  2) 在資料量很大的情況下,如果服務沒有正常關閉,那麼mongodb啟動修複資料庫的時間非常可觀,在1.8中退出的-dur貌似可以解決這個問題,我簡單測試了一下,開啟dur對插入和查詢性能影響都不是很大。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  3) 在使用sharding的時候,mongodb時不時會對資料拆分搬遷,這個時候性能下降很厲害,雖然從測試圖中看不出(因為我每一次測試都會測試比較多的疊代次數),但是我在實際觀察中可以發現,在搬遷資料的時候每秒插入性能可能會低到幾百條。</a>

<a href="http://www.51testing.com/batch.download.php?aid=44054" target="_blank">  4) 對于資料的插入,如果使用多線程并不會帶來性能的提高,反而還會下降一點性能(并且可以在http接口上看到,有大量的線程處于等待)。</a>

最新内容請見作者的github頁:http://qaseven.github.io/

繼續閱讀