8

我们有一个相对简单的 MongoDB 分片设置:4 个分片,每个分片是一个至少有 3 个成员的副本集。每个集合都包含从大量文件中加载的数据;每个文件都有一个单调递增的 ID,并且分片是基于 ID 的哈希完成的。

我们的大多数系列都按预期工作。但是,我有一个似乎没有在分片之间正确分布块的集合。在创建索引并对其进行分片之前,该集合已加载约 30GB 的数据,但据我所知,这无关紧要。以下是该系列的统计数据:

mongos> db.mycollection.stats()
{
        "sharded" : true,
        "ns" : "prod.mycollection",
        "count" : 53304954,
        "numExtents" : 37,
        "size" : 35871987376,
        "storageSize" : 38563958544,
        "totalIndexSize" : 8955712416,
        "indexSizes" : {
                "_id_" : 1581720784,
                "customer_code_1" : 1293148864,
                "job_id_1_customer_code_1" : 1800853936,
                "job_id_hashed" : 3365576816,
                "network_code_1" : 914412016
        },
        "avgObjSize" : 672.9578525853339,
        "nindexes" : 5,
        "nchunks" : 105,
        "shards" : {
                "rs0" : {
                        "ns" : "prod.mycollection",
                        "count" : 53304954,
                        "size" : 35871987376,
                        "avgObjSize" : 672.9578525853339,
                        "storageSize" : 38563958544,
                        "numExtents" : 37,
                        "nindexes" : 5,
                        "lastExtentSize" : 2146426864,
                        "paddingFactor" : 1.0000000000050822,
                        "systemFlags" : 0,
                        "userFlags" : 0,
                        "totalIndexSize" : 8955712416,
                        "indexSizes" : {
                                "_id_" : 1581720784,
                                "job_id_1_customer_code_1" : 1800853936,
                                "customer_code_1" : 1293148864,
                                "network_code_1" : 914412016,
                                "job_id_hashed" : 3365576816
                        },
                        "ok" : 1
                }
        },
        "ok" : 1
}

这个集合的 sh.status() :

            prod.mycollection
                    shard key: { "job_id" : "hashed" }
                    chunks:
                            rs0     105
                    too many chunks to print, use verbose if you want to force print

关于为什么这个集合只会分发到 rs0,我有什么遗漏吗?有没有办法强制重新平衡?我执行了相同的步骤来分片其他集合,并且它们正确地分布自己。以下是成功分片的集合的统计信息:

mongos> db.myshardedcollection.stats()
{
        "sharded" : true,
        "ns" : "prod.myshardedcollection",
        "count" : 5112395,
        "numExtents" : 71,
        "size" : 4004895600,
        "storageSize" : 8009994240,
        "totalIndexSize" : 881577200,
        "indexSizes" : {
                "_id_" : 250700688,
                "customer_code_1" : 126278320,
                "job_id_1_customer_code_1" : 257445888,
                "job_id_hashed" : 247152304
        },
        "avgObjSize" : 783.3697513591966,
        "nindexes" : 4,
        "nchunks" : 102,
        "shards" : {
                "rs0" : {
                        "ns" : "prod.myshardedcollection",
                        "count" : 1284540,
                        "size" : 969459424,
                        "avgObjSize" : 754.7133012595949,
                        "storageSize" : 4707762176,
                        "numExtents" : 21,
                        "nindexes" : 4,
                        "lastExtentSize" : 1229475840,
                        "paddingFactor" : 1.0000000000000746,
                        "systemFlags" : 0,
                        "userFlags" : 0,
                        "totalIndexSize" : 190549856,
                        "indexSizes" : {
                                "_id_" : 37928464,
                                "job_id_1_customer_code_1" : 39825296,
                                "customer_code_1" : 33734176,
                                "job_id_hashed" : 79061920
                        },
                        "ok" : 1
                },
                "rs1" : {
                        "ns" : "prod.myshardedcollection",
                        "count" : 1287243,
                        "size" : 1035438960,
                        "avgObjSize" : 804.384999568846,
                        "storageSize" : 1178923008,
                        "numExtents" : 17,
                        "nindexes" : 4,
                        "lastExtentSize" : 313208832,
                        "paddingFactor" : 1,
                        "systemFlags" : 0,
                        "userFlags" : 0,
                        "totalIndexSize" : 222681536,
                        "indexSizes" : {
                                "_id_" : 67787216,
                                "job_id_1_customer_code_1" : 67345712,
                                "customer_code_1" : 30169440,
                                "job_id_hashed" : 57379168
                        },
                        "ok" : 1
                },
                "rs2" : {
                        "ns" : "prod.myshardedcollection",
                        "count" : 1131411,
                        "size" : 912549232,
                        "avgObjSize" : 806.5585644827565,
                        "storageSize" : 944386048,
                        "numExtents" : 16,
                        "nindexes" : 4,
                        "lastExtentSize" : 253087744,
                        "paddingFactor" : 1,
                        "systemFlags" : 0,
                        "userFlags" : 0,
                        "totalIndexSize" : 213009328,
                        "indexSizes" : {
                                "_id_" : 64999200,
                                "job_id_1_customer_code_1" : 67836272,
                                "customer_code_1" : 26522944,
                                "job_id_hashed" : 53650912
                        },
                        "ok" : 1
                },
                "rs3" : {
                        "ns" : "prod.myshardedcollection",
                        "count" : 1409201,
                        "size" : 1087447984,
                        "avgObjSize" : 771.6769885914075,
                        "storageSize" : 1178923008,
                        "numExtents" : 17,
                        "nindexes" : 4,
                        "lastExtentSize" : 313208832,
                        "paddingFactor" : 1,
                        "systemFlags" : 0,
                        "userFlags" : 0,
                        "totalIndexSize" : 255336480,
                        "indexSizes" : {
                                "_id_" : 79985808,
                                "job_id_1_customer_code_1" : 82438608,
                                "customer_code_1" : 35851760,
                                "job_id_hashed" : 57060304
                        },
                        "ok" : 1
                }
        },
        "ok" : 1
}

sh.status() 用于正确分片的集合:

            prod.myshardedcollection
                    shard key: { "job_id" : "hashed" }
                    chunks:
                            rs2     25
                            rs1     26
                            rs3     25
                            rs0     26
                    too many chunks to print, use verbose if you want to force print
4

1 回答 1

13

在 MongoDB 中,当您使用分片系统并且看不到任何平衡时,它可能是几件事之一。

  1. 您可能没有足够的数据来触发平衡。这绝对不是你的情况,但有些人可能没有意识到默认块大小为 64MB 可能需要一段时间才能插入数据,然后才能将其中的一些数据拆分和平衡到其他块。

  2. 平衡器可能没有运行 - 因为您的其他集合正在平衡,这在您的情况下不太可能,除非在平衡器由于某种原因停止后最后分片此集合。

  3. 您收藏中的区块无法移动。当分片键的粒度不足以将数据拆分成足够小的块时,就会发生这种情况。事实证明这是您的情况,因为您的分片键对于这个大型集合来说不够精细 - 您有 105 个块(可能对应于唯一 job_id 值的数量)和超过 30GB 的数据。当块太大并且平衡器无法移动它们时,它会将它们标记为“巨型”(因此它不会旋转它的轮子来尝试迁移它们)。

如何从一个糟糕的分片键选择中恢复?通常,更改分片键是非常痛苦的——因为分片键是不可变的,您必须执行相当于完整数据迁移的操作才能将其放入具有另一个分片键的集合中。但是,在您的情况下,集合仍然在一个分片上,因此“取消分片”集合并使用新的分片键重新分片应该相对容易。因为 job_id 的数量相对较少,我建议使用常规索引对 job_id,customer_code 进行分片,因为您可能会对此进行查询,我猜它总是在文档创建时设置。

于 2013-06-04T14:34:41.030 回答