有谁碰到过 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
}
问题描述
有用户遇到了在 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
}
解决方案
-
确保集群已正确初始化:首先,需要确认
mongos
和config server
已经正确启动,并且所有分片服务器都已加入集群。 -
检查分片配置:
- 确认是否已经对集合进行了分片。可以通过以下命令检查:
mongos> sh.status()
- 如果还没有启用分片,可以使用以下命令进行分片:
mongos> sh.enableSharding("testdb") mongos> sh.shardCollection("testdb.user", {"_id": "hashed"})
- 确认是否已经对集合进行了分片。可以通过以下命令检查:
-
确保数据均衡:如果数据只集中在某一个分片上,可能是因为数据均衡器没有正常工作。可以手动触发数据均衡:
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
节点始终没有变化,这可能意味着数据并没有被正确地分散到其他分片上。
以下是一些可能的原因及解决步骤:
-
确保集群已正确配置:
- 确认
mongos
进程是否正在运行。 - 检查配置服务器的状态,确保它们都在正常工作。
- 确认
-
检查分片状态:
- 使用
sh.status()
命令来查看当前分片的状态和配置。 - 确保集合已经分片,可以使用
sh.enableSharding("testdb")
和sh.shardCollection("testdb.user", {"_id": "hashed"})
命令来启用和配置分片。
- 使用
-
验证路由器与分片节点通信:
- 确保所有分片节点都可以通过网络互相访问。
- 验证
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
路由器,然后启用分片并设置分片键,最后打印出分片状态以确认配置是否正确。如果发现任何异常,可以根据输出进一步调试。
希望这些信息能帮助你解决问题!