Mongodb億級資料量的效能測試

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   使用   strong   ar   

進行了一下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來摘要資料,

      理論上來說在某些情況下效能會有點提高,基於以上的種種假設,猜測某些情況效能會下降,某些情況效能會提高,那麼來看一下最後的測試結果怎麼樣?

備忘:測試的儲存伺服器是 E5620  @ 2.40GHz,24GB記憶體,CentOs作業系統,打壓機器是E5504 @ 2.0GHz,4GB記憶體,

         Windows Server 2003作業系統,兩者千兆網卡直連。

從這個測試可以看出,對於單進程的方式:

1) Mongodb的非安全插入方式,在一開始插入效能是非常高的,但是在達到了兩千萬條資料之後效能驟減,

       這個時候恰巧是伺服器24G記憶體基本佔滿的時候(隨著測試的進行mongodb不斷佔據記憶體,一直到作業系統的記憶體全部佔滿),

      也就是說Mongodb的記憶體映射方式,使得資料全部在記憶體中的時候速度飛快,當部分資料需要換出到磁碟上之後,效能下降很厲害。

      (這個效能其實也不算太差,因為我們對三個列的資料做了索引,即使在記憶體滿了之後每秒也能插入2MB的資料,在一開始更是每秒插入25MB資料)。

      Foursquare其實也是把Mongodb當作帶持久化的記憶體資料庫使用的,只是在查不到達到記憶體瓶頸的時候Sharding沒處理好。

2) 對於批量插入功能,其實是一次提交一批資料,但是相比一次一條插入效能並沒有提高多少,一來是因為網路頻寬已經成為了瓶頸,二來我想寫鎖也會是一個原因。

3) 對於安全插入功能,相對來說比較穩定,不會波動很大,我想可能是因為安全插入是確保資料直接持久化到磁碟的,而不是插入記憶體就完事。

4) 對於一列條件的查詢,效能一直比較穩定,別小看,每秒能有8000-9000的查詢次數,每次返回10KB,相當於每秒查詢80MB資料,

      而且資料庫記錄是2億之後還能維持這個水平,效能驚人。

5) 對於二列條件返回小資料的查詢,總體上效能會比4)好一點,可能返回的資料量小對效能提高比較大,但是相對來說效能波動也厲害一點,

      可能多了一個條件就多了一個從磁碟換頁的機會。

6) 對於一列資料外加Sort和Skip的查詢,在資料量大了之後效能明顯就變差了(此時是索引資料量超過記憶體大小的時候,不知道是否有聯絡),

      我猜想是Skip比較消耗效能,不過和4)相比效能也不是差距特別大。

7) 對於返回大資料的查詢,一秒瓶頸也有800次左右,也就是80M資料,這就進一步說明了在有索引的情況下,順序查詢和按條件搜尋效能是相差無幾的,

      這個時候是IO和網路的瓶頸。

8) 在整個過程中索引占的資料量已經佔到了總資料量的相當大比例,在達到1億4千萬資料量的時候,光索引就可以佔據整個記憶體,

      此時查詢效能還是非常高,插入效能也不算太差,mongodb的效能確實很牛。

看看Sharding模式有什麼亮點:

1) 非安全插入和單進程的配置一樣,在記憶體滿了之後效能急劇下降。安全插入效能和單進程相比慢不少,但是非常穩定。

2) 對於一個條件和兩個條件的查詢,效能都比較穩定,但條件查詢效能相當於單進程的一半,但是在多條件下有的時候甚至會比單進程高一點。

      我想這可能是某些時候資料區塊位於兩個Sharding,這樣Mongos會並行在兩個Sharding查詢,然後在把資料進行合并匯總,

      由於查詢返回的資料量小,網路不太可能成為瓶頸了,使得Sharding才有出頭的機會。

3) 對於Order和Skip的查詢,Sharding方式的差距就出來了,我想主要效能損失可能在Order,因為我們並沒有按照排序欄位作為Sharding的Key,

      使用的是_id作為Key,這樣排序就比較難進行。

4) 對於返回大資料量的查詢,Sharding方式其實和單進程差距不是很大,我想資料的轉寄可能是一個效能損耗的原因(雖然mongos位於打壓機本機,

      但是資料始終是轉手了一次)。

5) 對於磁碟空間的佔用,兩者其實是差不多的,其中的一些差距可能是因為多個進程都會多分配一點空間,加起來有的時候會比單進程多佔用點磁碟

      (而那些佔用比單進程少的地方其實是開始的編碼錯誤,把實際資料大小和磁碟檔案佔用大小搞錯了)。

測試最後的各個Sharding分布情況如下:

 1 { 2         "sharded" : true, 3         "ns" : "testdb.test", 4         "count" : 209766143, 5         "size" : 214800530672, 6         "avgObjSize" : 1024.0000011441311, 7         "storageSize" : 222462757776, 8         "nindexes" : 4, 9         "nchunks" : 823,10         "shards" : {11                 "shard0000" : {12                         "ns" : "testdb.test",13                         "count" : 69474248,14                         "size" : 71141630032,15                         "avgObjSize" : 1024.0000011515058,16                         "storageSize" : 74154252592,17                         "numExtents" : 65,18                         "nindexes" : 4,19                         "lastExtentSize" : 2146426864,20                         "paddingFactor" : 1,21                         "flags" : 1,22                         "totalIndexSize" : 11294125824,23                         "indexSizes" : {24                                 "_id_" : 2928157632,25                                 "Number_1" : 2832745408,26                                 "Number1_1" : 2833974208,27                                 "Date_-1" : 269924857628                         },29                         "ok" : 130                 },31                 "shard0001" : {32                         "ns" : "testdb.test",33                         "count" : 70446092,34                         "size" : 72136798288,35                         "avgObjSize" : 1024.00000113562,36                         "storageSize" : 74154252592,37                         "numExtents" : 65,38                         "nindexes" : 4,39                         "lastExtentSize" : 2146426864,40                         "paddingFactor" : 1,41                         "flags" : 1,42                         "totalIndexSize" : 11394068224,43                         "indexSizes" : {44                                 "_id_" : 2969355200,45                                 "Number_1" : 2826453952,46                                 "Number1_1" : 2828403648,47                                 "Date_-1" : 276985542448                         },49                         "ok" : 150                 },51                 "shard0002" : {52                         "ns" : "testdb.test",53                         "count" : 69845803,54                         "size" : 71522102352,55                         "avgObjSize" : 1024.00000114538,56                         "storageSize" : 74154252592,57                         "numExtents" : 65,58                         "nindexes" : 4,59                         "lastExtentSize" : 2146426864,60                         "paddingFactor" : 1,61                         "flags" : 1,62                         "totalIndexSize" : 11300515584,63                         "indexSizes" : {64                                 "_id_" : 2930942912,65                                 "Number_1" : 2835243968,66                                 "Number1_1" : 2835907520,67                                 "Date_-1" : 269842118468                         },69                         "ok" : 170                 }71         },72         "ok" : 173 }
View Code

 

雖然在最後由於時間的關係,沒有測到10億層級的資料量,但是通過這些資料已經可以證明Mongodb的效能是多麼強勁了。

另外一個原因是,在很多時候可能資料只達到千萬我們就會對庫進行拆分,不會讓一個庫的索引非常龐大。

在測試的過程中還發現幾個問題需要值得注意:

1) 在資料量很大的情況下,對服務進行重啟,那麼服務啟動的初始化階段,雖然可以接受資料的查詢和修改,但是此時效能很差,

      因為mongodb會不斷把資料從磁碟換入記憶體,此時的IO壓力非常大。

2) 在資料量很大的情況下,如果服務沒有正常關閉,那麼Mongodb啟動修復資料庫的時間非常可觀,在1.8中退出的-dur貌似可以解決這個問題,

      據官方說對讀取沒影響,寫入速度會稍稍降低,有空我也會再進行下測試。

3) 在使用Sharding的時候,Mongodb時不時會對資料拆分搬遷,這個時候效能下降很厲害,雖然從測試圖中看不出(因為我每一次測試都會測試比較多的迭代次數),

      但是我在實際觀察中可以發現,在搬遷資料的時候每秒插入效能可能會低到幾百條。其實我覺得能手動切分資料庫就手動切分或者手動做曆史庫,

     不要依賴這種自動化的Sharding,因為一開始資料就放到正確的位置比分隔再搬遷效率不知道高多少。

     個人認為Mongodb單資料庫儲存不超過1億的資料比較合適,再大還是手動分庫吧。

4) 對於資料的插入,如果使用多線程並不會帶來效能的提高,反而還會下降一點效能(並且可以在http介面上看到,有大量的線程處於等待)。

5) 在整個測試過程中,批量插入的時候遇到過幾次串連被遠端電腦關閉的錯誤,懷疑是有的時候Mongodb不穩定關閉了串連,

      或是官方的C#用戶端有BUG,但是也僅僅是在資料量特別大的時候遇到幾次。

 

附:

在之後我又進行了幾天測試,把測試資料量進一步加大到5億,總磁碟佔用超過500G,發現和2億資料量相比,所有效能都差不多,

只是測試6和測試7在超過2億層級資料之後,每400萬記錄作為一個迴圈,上下波動30%的效能,非常有規律。

 

Mongodb億級資料量的效能測試

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.