MongoDB數據量大於2億後遇到的問題 及原因分析

MongoDB數據量大於2億後遇到的問題 及原因分析



一、數據增長情況


    每月增長量最大達到了1.9億,每天增長約300W-500W
    (增長數據具體可看頁尾)


二、遇到的情況及解決方法


    1.數據量過大,並且都集中在一個表,所以此表數據插入變慢。

        表索引越多越明顯,

        優化處理方法:
            1.優化索引,以前的startTime日期字段索引,
            修改爲客戶端用日期生成ObjectId,再用_id 來進行查找。
            2.TraceId 字段(一個TraceId 對應多條記錄)計劃也刪除,後面再用ES 系統先查詢到_id 後,
            再從mongoDB 進行查找。

        原因分析:
            當表數據增長到千萬級後,內存數據中的索引數據增加,內存越來越不夠用,需要刷新髒數據增多,            
            mongostat 分析的 dirty % > 3,後從16G 內存升級到32G 內存後,情況稍有好轉。




    2.數據量過大後,從節點時爾出現CPU load 負載過高,從節點尤其明顯。

        
        在把表重命名,新數據插入到新表處理後:
        db.TraceLogs.renameCollection("TraceLogs_bak170210");
        (新數據插入時,會自動生成表TraceLogs)


        歷史數據表統計信息    
            Log:PRIMARY> db.TraceLogs_bak170210.stats()
            {
                "ns" : "RavenLogs.TraceLogs_bak170210",
                "count" : 384453917,
                "size" : 865594958942,
                "avgObjSize" : 2251,
                "storageSize" : 444,613,255,168,
                .....
                "nindexes" : 2,
                "totalIndexSize" : 15275057152,
                "indexSizes" : {
                    "_id_" : 3,973,029,888,
                    "TraceId_1" : 11,302,027,264
                },
                "ok" : 1
            }
            從此統計信息中可以看到:
                    表存儲大小:    444G,
                    索引 _id_ 3.9G, TraceId_1 大小:11G


        再次查看數據庫性能

        從以前的:
        load average: > 5.47, 5.47, 5.47
        降到了:
        load average: 0.88, 1.34, 1.69
        (主從節點,皆已下降)

        在做歷史數據遷移期間,又升到了> 8 並且時頻繁出現。

        完成數據遷移後,回落到  2 < load avg <: 4 之間        (升級到MongoDB3.4 之後)
            

        原因分析:
            個人認爲,主因還是因爲內存不夠。索引+熱數據遠遠超過了16G的MongoDB使用內存。
            從而導致大量的IO,相對的CPU load 也上去了。
            在把原大表TraceLogs 改名後(TraceLogs_bak170210),大量的熱塊數據已被清除出內存,



    3.此前數據庫從節點內存升級後(16G --> 32G),參數配置不當,節點實例當機情況:

        wiredTiger:
            engineConfig:
          cacheSizeGB: 28    (限制mongoDB 使用內存最大值)

        後調整爲默認值
                #cacheSizeGB: 28    (限制mongoDB 使用內存最大值),默認值爲50%
        mongoDB實例恢復正常,但CPU load 也一直居高不下。

        原因分析:
            系統使用內存太少,可能是磁盤緩存過低,而無法讀寫數據,但在mongoDB 日誌中,
            無法找到原因。只是看到實例被關閉。





    4.因爲oplog 同步表最大設置值(oplogSizeMB)爲50G, 但50G 只能保存52h 的數量變化量。

    想添加新的從節點時,當同步完成數據後,已過了oplog 的窗口期.
        
    (oplogSizeMB的大小要大於數據同步完成+索引建立完成的時間段內生成的數據量,
    當同步完成後,從節點從主節點讀oplog表的數據,發現最小的同步時間,已大於從節點中
    同步開始時的時間了,這就是窗口期已過期)


        數據量大後,重新創建索引的時間特別驚人,一個索引需要10多個小時。
        500G 存儲量,總共需要3天左右的數據完成節點的數據同步及索引創建。

        後面計劃在添加節點前,做以下調整:
        1.把數據庫升級到3.4 版本,此版本在新節點數據同步,創建索引上,號稱已有很大的改善。
        2.刪除能夠優化的索引,如果索引無法優化,也可以考慮先把某個索引刪除,節點完成後,再重新建立




經驗總結:


    1.索引的優化,儘可能的發揮主鍵索引的功能,比如上面說到的,使用日期範圍自己生成_id 範圍,用_id字段進行查詢,
    能不建立索引,就不建立。在大增長的表中,極其重要。

    2.數據庫服務器的內存配置上,內存>索引大小,或者是配置到 內存>=索引大小+熱數據大小 還是有必要的。
    
    3.數據庫服務器的磁盤配置上,如果是雲服務器,儘量採用高效雲盤。使用EXT4,或者使用NFS 格式也是有必要的。

    4.如果一個庫有多個表的數據達到億級時,可能也是考慮使用分片集羣的時候,特別是如果此表是做爲主業務
    數據庫的情況。








---------- 表數據增長情況 ------------------
......
1/1/2017,4318897
1/2/2017,3619411
1/3/2017,2583555
1/5/2017,5523416
1/6/2017,3052537
1/7/2017,3482728
1/8/2017,3931742
1/9/2017,4732320
1/10/2017,4651948
1/11/2017,4438733
1/12/2017,4286169
1/13/2017,4405242
1/14/2017,5664654
1/15/2017,5623800
1/16/2017,3638656
1/17/2017,3617628
1/18/2017,3601569
1/19/2017,3738790
1/20/2017,3788641
1/21/2017,4603575
1/22/2017,4466660
1/23/2017,3913910
1/24/2017,3749316
1/25/2017,3969802
1/26/2017,4101293
1/27/2017,2581358
1/28/2017,3160561
1/29/2017,3051008
1/30/2017,3332417
1/31/2017,3476649
2/1/2017,    3152283
2/2/2017,    3394489
2/3/2017,    3524487
2/4/2017,    3511386
2/5/2017,    3870305
2/6/2017,    3056966
2/7/2017,    3022927
2/8/2017,    3484463
2/9/2017,    4033520

--------------------------
 2016/12:    191914076
 2017/01:    119106985
 2017/02:    31050826


發佈了221 篇原創文章 · 獲贊 53 · 訪問量 121萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章