有谁碰到过 Nodejs 中 MongoDB 无法自动 sharding 的问题?

有谁碰到过 Nodejs 中 MongoDB 无法自动 sharding 的问题?

按照攻略配置了数遍,一直停留在s1上。。。。

Sat Mar 15 08:30:06.113 [initandlisten] connection accepted from 192.168.137.107:54727 #95 (10 connections now open)
Sat Mar 15 08:30:28.730 [conn35] command admin.$cmd command: { writebacklisten: ObjectId('5340d8a803e9ace098bfbc5a') } ntoreturn:1 keyUpdates:0  reslen:44 300000ms
Sat Mar 15 08:30:29.164 [conn94] end connection 192.168.137.108:44537 (9 connections now open)
Sat Mar 15 08:30:29.165 [initandlisten] connection accepted from 192.168.137.108:44556 #96 (10 connections now open)
Sat Mar 15 08:30:36.143 [conn95] end connection 192.168.137.107:54727 (9 connections now open)
Sat Mar 15 08:30:36.145 [initandlisten] connection accepted from 192.168.137.107:54746 #97 (10 connections now open)
Sat Mar 15 08:30:59.193 [conn96] end connection 192.168.137.108:44556 (9 connections now open)
Sat Mar 15 08:30:59.194 [initandlisten] connection accepted from 192.168.137.108:44575 #98 (10 connections now open)
Sat Mar 15 08:31:06.176 [conn97] end connection 192.168.137.107:54746 (9 connections now open)
Sat Mar 15 08:31:06.177 [initandlisten] connection accepted from 192.168.137.107:54765 #99 (10 connections now open)
Sat Mar 15 08:31:29.225 [conn98] end connection 192.168.137.108:44575 (9 connections now open)

日志也看不出有什么问题?

mongos> db.user.stats();
{
        "sharded" : true,
        "ns" : "testdb.user",
        "count" : 100000,
        "numExtents" : 6,
        "size" : 5600000,
        "storageSize" : 11182080,
        "totalIndexSize" : 3262224,
        "indexSizes" : {
                "_id_" : 3262224
        },
        "avgObjSize" : 56,
        "nindexes" : 1,
        "nchunks" : 1,
        "shards" : {
                "s1" : {
                        "ns" : "testdb.user",
                        "count" : 100000,
                        "size" : 5600000,
                        "avgObjSize" : 56,
                        "storageSize" : 11182080,
                        "numExtents" : 6,
                        "nindexes" : 1,
                        "lastExtentSize" : 8388608,
                        "paddingFactor" : 1,
                        "systemFlags" : 1,
                        "userFlags" : 0,
                        "totalIndexSize" : 3262224,
                        "indexSizes" : {
                                "_id_" : 3262224
                        },
                        "ok" : 1
                }
        },
        "ok" : 1
}

2 回复

问题描述

有用户遇到了在 Node.js 中使用 MongoDB 时无法自动分片(sharding)的问题。尽管按照官方文档和教程多次配置,但分片始终未能成功,数据仍然集中在某个分片节点 s1 上。

日志分析

从日志中可以看到,连接和断开连接的信息并没有明显的错误,但当查询分片状态时,发现所有数据都集中在 s1 分片上,而不是预期的多个分片节点之间。

mongos> db.user.stats();
{
    "sharded": true,
    "ns": "testdb.user",
    "count": 100000,
    "numExtents": 6,
    "size": 5600000,
    "storageSize": 11182080,
    "totalIndexSize": 3262224,
    "indexSizes": {
        "_id_": 3262224
    },
    "avgObjSize": 56,
    "nindexes": 1,
    "nchunks": 1,
    "shards": {
        "s1": {
            "ns": "testdb.user",
            "count": 100000,
            "size": 5600000,
            "avgObjSize": 56,
            "storageSize": 11182080,
            "numExtents": 6,
            "nindexes": 1,
            "lastExtentSize": 8388608,
            "paddingFactor": 1,
            "systemFlags": 1,
            "userFlags": 0,
            "totalIndexSize": 3262224,
            "indexSizes": {
                "_id_": 3262224
            },
            "ok": 1
        }
    },
    "ok": 1
}

解决方案

  1. 确保集群已正确初始化:首先,需要确认 mongosconfig server 已经正确启动,并且所有分片服务器都已加入集群。

  2. 检查分片配置

    • 确认是否已经对集合进行了分片。可以通过以下命令检查:
      mongos> sh.status()
      
    • 如果还没有启用分片,可以使用以下命令进行分片:
      mongos> sh.enableSharding("testdb")
      mongos> sh.shardCollection("testdb.user", {"_id": "hashed"})
      
  3. 确保数据均衡:如果数据只集中在某一个分片上,可能是因为数据均衡器没有正常工作。可以手动触发数据均衡:

    mongos> db.adminCommand({moveChunk: "testdb.user", find: {_id: ObjectId("some_id")}, to: "s2"})
    

示例代码

假设我们有一个 Node.js 应用程序,并且想要对其进行分片配置:

const MongoClient = require('mongodb').MongoClient;

async function setupSharding() {
    const uri = 'mongodb://<username>:<password>@<host1>,<host2>,<host3>/<database>?replicaSet=<replica_set>&authSource=admin';
    const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

    try {
        await client.connect();
        const adminDb = client.db().admin();

        // 启用分片
        await adminDb.command({ enableSharding: "testdb" });
        console.log("Sharding enabled for testdb");

        // 对集合进行分片
        await adminDb.command({ shardCollection: "testdb.user", key: { _id: "hashed" } });
        console.log("User collection is sharded");
    } catch (err) {
        console.error(err);
    } finally {
        await client.close();
    }
}

setupSharding();

通过以上步骤和代码,可以解决在 Node.js 中 MongoDB 自动分片失败的问题。


在Node.js中遇到MongoDB无法自动分片的问题可能是由于多种原因引起的。从提供的日志和输出信息来看,s1节点始终没有变化,这可能意味着数据并没有被正确地分散到其他分片上。

以下是一些可能的原因及解决步骤:

  1. 确保集群已正确配置

    • 确认mongos进程是否正在运行。
    • 检查配置服务器的状态,确保它们都在正常工作。
  2. 检查分片状态

    • 使用sh.status()命令来查看当前分片的状态和配置。
    • 确保集合已经分片,可以使用sh.enableSharding("testdb")sh.shardCollection("testdb.user", {"_id": "hashed"})命令来启用和配置分片。
  3. 验证路由器与分片节点通信

    • 确保所有分片节点都可以通过网络互相访问。
    • 验证mongos路由器能够正确地将请求转发到相应的分片。

示例代码如下:

// 连接到mongos路由器
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb://mongos_router_ip:port";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

client.connect(err => {
  const collection = client.db("testdb").collection("user");

  // 启用分片
  client.db().admin().command({ enablesharding: "testdb" });

  // 分片键设置为_id字段的哈希值
  client.db().admin().command({ shardcollection: "testdb.user", key: { _id: "hashed" } });

  // 查看分片状态
  client.db().admin().command({ shstatus: 1 }, function(err, result) {
    console.log(result);
  });

  client.close();
});

上述代码首先连接到mongos路由器,然后启用分片并设置分片键,最后打印出分片状态以确认配置是否正确。如果发现任何异常,可以根据输出进一步调试。

希望这些信息能帮助你解决问题!

回到顶部