全部產品
Search
文件中心

ApsaraDB for MongoDB:設定資料分區以充分利用Shard效能

更新時間:Aug 05, 2026

您可以對分區叢集執行個體中的集合設定資料分區,以充分利用Shard節點的儲存空間和計算效能。

背景資訊

如果沒有對集合設定資料分區,資料將被集中存放在一個Shard節點中,這將導致其他Shard節點的儲存空間和計算效能無法被充分利用。


mongos> db.stats()
{
        "raw" : {
                "mgset-xxx65/xxx" : {
                        "db" : "mongodbtest",
                        "collections" : 0,
                        "views" : 0,
                        "objects" : 0,
                        "avgObjSize" : 0,
                        "dataSize" : 0,
                        "storageSize" : 0,
                        "numExtents" : 0,
                        "indexes" : 0,
                        "indexSize" : 0,
                        "fileSize" : 0,
                        "ok" : 1,
                        "$gleStats" : {
                                "lastOpTime" : Timestamp(0, 0),
                                "electionId" : ObjectId("7fffffff0000000000000001")
                        }
                },
                "mgset-xxx67/xxx" : {
                        "db" : "mongodbtest",
                        "collections" : 2,
                        "views" : 0,
                        "objects" : 1000021,
                        "avgObjSize" : 352.4417477232978,
                        "dataSize" : 352449149,
                        "storageSize" : 209125376,
                        "numExtents" : 0,
                        "indexes" : 1,
                        "indexSize" : 10141696,
                        "ok" : 1,
                        "$gleStats" : {
                                "lastOpTime" : Timestamp(0, 0),
                                "electionId" : ObjectId("7fffffff0000000000000001")
                        }
                }
        }
}

前提條件

執行個體類型為分區叢集執行個體。

注意事項

  • MongoDB 對片鍵(Shard Key)的修改能力隨著版本迭代不斷增強:

    • 4.4 版本以前:片鍵一旦設定,則固定不變,無法修改或刪除。

    • 從 4.4 版本開始:可以使用 refineCollectionShardKey 命令,通過為片鍵添加尾碼欄位的方式來最佳化它。

    • 從 5.0 版本開始:引入了 reshardCollection 命令,支援完全更換一個集合的片鍵。

  • 執行了資料分區操作後,均衡器會對滿足條件的資料進行拆分,這將佔用執行個體的資源,請在業務低峰期操作。

    說明

    您可以在設定資料分區之前,調整均衡器的使用中視窗,指定它在業務低峰期執行均衡操作。詳情請參見設定Balancer的使用中視窗。

  • 片鍵的選取將影響分區叢集執行個體的效能,關於片鍵選取的案例介紹,請參見如何選擇Shard Key和Shard Keys。

分區策略介紹

分區策略

說明

適用情境

基於範圍的分區

MongoDB按照片鍵的值的範圍將資料拆分為不同的塊(chunk),每個塊包含了一段範圍內的資料。

  • 優點: mongos可以快速定位請求需要的資料,並將請求轉寄到相應的Shard節點中。

  • 缺點: 可能導致資料在Shard節點上分布不均衡,容易造成讀寫熱點,且不具備寫分散性。

片鍵的值不是單調遞增或單調遞減、片鍵的值基數大且重複的頻率低、需要範圍查詢等業務情境。

基於Hash值的分區

MongoDB計算單個欄位的雜湊值作為索引值,並以雜湊值的範圍將資料拆分為不同的塊。

  • 優點:可以將資料更加均衡地分布在各Shard節點中,具備寫分散性。

  • 缺點:不適合進行範圍查詢,進行範圍查詢時,需要將讀請求分發到所有的Shard節點。

片鍵的值存在單調遞增或遞減、片鍵的值基數大且重複的頻率低、需要寫入的資料隨機分發、資料讀取隨機性較大等業務情境。

除了上述兩種分區策略,您還可以配置複合片鍵,例如由一個低基數的鍵和一個單調遞增的鍵組成,詳情請參見如何選擇Shard Key。

操作步驟

本文以mongodbtest資料庫,customer集合為例介紹操作流程。

  1. 通過Mongo Shell登入分區叢集執行個體。

  2. 對集合所在的資料庫啟用分區功能。

    重要

    如果您的執行個體是MongoDB 6.0及以上版本,可跳過此步驟,更多資訊,請參見sh.enableSharding()。

    sh.enableSharding("<database>")

    參數說明:<database>為資料庫名。

    樣本:

    sh.enableSharding("mongodbtest")
    說明

    您可以通過sh.status()查看分區狀態。

  3. 對片鍵的欄位建立索引。

    db.<collection>.createIndex(<keyPatterns>,<options>)

    參數說明:

    • <collection>:集合名。

    • <keyPatterns>:包含用於建立索引的欄位和索引類型。

      常見的索引類型如下:

      • 1:建立升序索引

      • -1:建立降序索引

      • "hashed":建立雜湊索引

    • <options>:表示接收選擇性參數,詳情請參見db.collection.createIndex(),本操作樣本中暫未使用到該欄位。

    建立升序索引樣本:

    db.customer.createIndex({name:1})

    建立雜湊索引樣本:

    db.customer.createIndex({name:"hashed"})
  4. 對集合設定資料分區。

    sh.shardCollection("<database>.<collection>",{ "<key>":<value> } ) 

    參數說明:

    • <database>:資料庫名。

    • <collection>:集合名。

    • <key>:分區的鍵,MongoDB將根據片鍵的值進行資料分區。

    • <value>

      • 1:表示基於範圍分區,通常能很好地支援基於片鍵的範圍查詢。

      • “hashed”:表示基於雜湊分區,通常能將寫入均衡分布到各Shard節點中。

    基於範圍分區的配置樣本:

    sh.shardCollection("mongodbtest.customer",{"name":1})

    基於雜湊分區的配置樣本:

    sh.shardCollection("mongodbtest.customer",{"name":"hashed"})

後續操作

經過一段時間的運行或資料寫入後,您可以在Mongo Shell中執行sh.status(),查看資料在各Shard節點中的分布資訊。


mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5xxx")
}
  shards:
        { "_id" : "d-bpxxx3c4", "host" : "mgset-xxx29/xxx", "state" : 1 }
        { "_id" : "d-bpxxx834", "host" : "mgset-xxx27/xxx", "state" : 1 }
  active mongoses:
        "3.4.6" : 2
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
NaN
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours:
                51 : Success
  databases:
        { "_id" : "mongodbtest", "primary" : "d-bpxxx834", "partitioned" : true }
                mongodbtest.customer
                        shard key: { "name" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                d-bpxxx3c4      51
                                d-bpxxx834      52
                        too many chunks to print, use verbose if you want to force print
        { "_id" : "test", "primary" : "d-bpxxx834", "partitioned" : false }

您也可以通過執行db.stats()查看該資料庫在各Shard節點的資料存放區情況。


mongos> db.stats()
{
    "raw" : {
        "mgset-xxx" : {
            "db" : "mongodbtest",
            "collections" : 2,
            "views" : 0,
            "objects" : 496075,
            "avgObjSize" : 353.0421932167515,
            "dataSize" : 175135406,
            "storageSize" : 434943968,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 17107270,
            "ok" : 1,
            "$gleStats" : {
                "lastOpTime" : Timestamp(0, 0),
                "electionId" : ObjectId("7fffffff0000000000000001")
            }
        },
        "mgset-xxx" : {
            "db" : "mongodbtest",
            "collections" : 2,
            "views" : 0,
            "objects" : 505423,
            "avgObjSize" : 352.9883444164591,
            "dataSize" : 178408428,
            "storageSize" : 501801512,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 17493372,
            "ok" : 1,
            "$gleStats" : {
                "lastOpTime" : Timestamp(0, 0),
                "electionId" : ObjectId("7fffffff0000000000000001")
            }
        }
    }
}