原理
数据分片(Sharding)将数据水平拆分到多个数据库或节点,提升性能和扩展性。分片策略包括:
- 范围分片:按字段范围(如用户 ID 区间)分配数据。
- 哈希分片:对分片键哈希后取模,均匀分布数据。
- 一致性哈希:动态增减节点时减少数据迁移。
Node.js 实现(基于 MongoDB 分片集群)
MongoDB 分片集群架构:
- Config Servers:存储元数据和分片配置。
- Shard Servers:实际存储分片数据。
- Mongos:路由服务,将查询分发到对应分片。
步骤
- 配置分片集群:
# 启动 Config Server
mongod --configsvr --replSet configReplSet --port 27019
# 启动 Shard Servers
mongod --shardsvr --replSet shardReplSet1 --port 27018
mongod --shardsvr --replSet shardReplSet2 --port 27028
# 启动 Mongos
mongos --configdb configReplSet/localhost:27019
- 在 Node.js 中使用 Mongoose 连接:
const mongoose = require("mongoose");
// 连接到 Mongos 路由
mongoose.connect("mongodb://localhost:27017/shardedDB", {
useNewUrlParser: true,
useUnifiedTopology: true
});
// 定义分片模型(需在 MongoDB 启用分片)
const userSchema = new mongoose.Schema({
userId: { type: Number, required: true },
name: String, email: String
});
// 创建分片键索引
userSchema.index({ userId: 1 });
const User = mongoose.model("User", userSchema);
// 插入数据时自动路由到对应分片
async function createUser(userId, name, email) {
const user = new User({ userId, name, email });
await user.save();
console.log("User created:", user.userId);
}
createUser(1001, "Alice", "alice@example.com");
分片策略配置
在 MongoDB Shell 中启用分片:
sh.enableSharding("shardedDB");
sh.shardCollection("shardedDB.users", { userId: 1 });
自定义分片逻辑(哈希分片示例)
function getShardIndex(userId, totalShards) {
const hash = crypto.createHash("md5").update(String(userId)).digest("hex");
const shardIndex = parseInt(hash, 16) % totalShards;
return shardIndex;
}
const shardDBs = [
mongoose.createConnection("mongodb://shard1:27017/db"),
mongoose.createConnection("mongodb://shard2:27017/db")
];
async function saveUser(userId, data) {
const shardIndex = getShardIndex(userId, shardDBs.length);
const User = shardDBs[shardIndex].model("User", userSchema);
await User.create(data);
}
关键点
- 分片键选择:需高频查询且分布均匀的字段(如用户 ID)。
- 查询路由:非分片键查询可能触发广播到所有分片(Scatter-Gather)。
- 数据均衡:MongoDB 自动平衡分片间的数据分布。
总结
- 分布式锁:通过 Redis 的原子操作实现互斥访问,需处理超时和容错。
- 分布式事务:Saga 模式结合消息队列实现最终一致性,需补偿机制和幂等性。
- 数据分片:利用 MongoDB 分片集群或自定义逻辑,提升扩展性和性能。