MongoDB(十) - MongoDB分片集操作

文章目录

  • 一、修改Chunk数据块大小
    • [1. 步骤1:连接mongos路由服务](#1. 步骤1:连接mongos路由服务)
    • [2. 步骤2:切换至config配置库](#2. 步骤2:切换至config配置库)
    • [3. 步骤3:修改chunkSize为64MB](#3. 步骤3:修改chunkSize为64MB)
    • [4. 步骤4:查询当前数据块配置](#4. 步骤4:查询当前数据块配置)
  • 二、集合分片操作
    • [1. 预配置Chunk大小为1MB](#1. 预配置Chunk大小为1MB)
    • [2. 范围分片](#2. 范围分片)
      • [2.1 切换数据库](#2.1 切换数据库)
      • [2.2 创建集合](#2.2 创建集合)
      • [2.3 批量插入数据](#2.3 批量插入数据)
      • [2.4 统计文档总数](#2.4 统计文档总数)
      • [2.5 创建索引](#2.5 创建索引)
      • [2.6 执行分片操作](#2.6 执行分片操作)
      • [2.7 查看分片信息](#2.7 查看分片信息)
    • [3. 哈希分片](#3. 哈希分片)
      • [3.1 切换数据库](#3.1 切换数据库)
      • [3.2 创建集合](#3.2 创建集合)
      • [3.3 批量插入数据](#3.3 批量插入数据)
      • [3.4 创建哈希索引](#3.4 创建哈希索引)
      • [3.5 执行分片操作](#3.5 执行分片操作)
      • [3.6 查看分片信息](#3.6 查看分片信息)
    • [4. 删除分片](#4. 删除分片)
      • [4.1 删除分片](#4.1 删除分片)
      • [4.2 迁移数据库主分片](#4.2 迁移数据库主分片)

一、修改Chunk数据块大小

MongoDB 7.0默认Chunk数据块大小为128MB,范围约束:1MB~1024MB

  • 数据增速快:调大chunkSize,减少拆分迁移、提升写入性能
  • 分片数据倾斜:调小chunkSize,加快块拆分,便于数据均衡

1. 步骤1:连接mongos路由服务

在任意节点执行客户端连接,路由部署在hadoop2:21020

shell 复制代码
mongosh --host hadoop2 --port 27020

2. 步骤2:切换至config配置库

分片全局配置存储在config库,切换数据库:

js 复制代码
use config

3. 步骤3:修改chunkSize为64MB

更新settings集合,设置数据块大小:

js 复制代码
db.settings.updateOne(
  {_id: "chunksize"},
  {$set: {_id: "chunksize", value: 64}},
  {upsert: true}
)

upsert:true:无文档则新增、已有文档则更新。

4. 步骤4:查询当前数据块配置

校验修改结果:

js 复制代码
db.settings.find({_id: "chunksize"})

二、集合分片操作

默认未分片的集合完整存储在数据库主分片(mongos自动挑选数据量最少分片);MongoDB6.0+首次集合分片时自动开启数据库分片,无需单独对数据库执行分片操作。

1. 预配置Chunk大小为1MB

调整Chunk大小为1MB,便于自动分片的演示,连接hadoop2:27020的mongos后执行:

js 复制代码
use config
db.settings.updateOne(
{_id: "chunksize"},
{$set: {_id: "chunksize", value: 1}},
{upsert: true}
)

2. 范围分片

范围分片依据分片键字段数值区间划分 Chunk 数据块,同区间数据落至同一个分片,分片键范围查询可精准路由至单个分片,查询性能优异;本实验选用 age 为分片键,实现按年龄区间拆分数据至 shard1、shard2 两个分片。

2.1 切换数据库

mongosh 环境下切换至目标业务库 mydb,后续所有集合操作均在当前库执行。

js 复制代码
use mydb

2.2 创建集合

新建空集合 users,提前定义分片承载对象,分片操作依赖已存在的目标集合。

js 复制代码
db.createCollection('users')

2.3 批量插入数据

使用无序批量写入对象高效批量插入 50000 条测试文档,充足数据量可触发 MongoDB 自动拆分 Chunk,验证分片数据切割效果;age 字段随机 18~77,满足按年龄范围分片的数据条件MongoDB。

js 复制代码
const bulk = db.users.initializeUnorderedBulkOp();
for (let i = 1; i <= 50000; i++) {
bulk.insert({
username: `user${i}`,
age: Math.floor(Math.random() * 60) + 18,
gender: Math.random() > 0.5 ? 'Male' : 'Female',
height: Math.floor(Math.random() * 60) + 150,
weight: Math.floor(Math.random() * 50) + 50
});
}
bulk.execute();

2.4 统计文档总数

校验批量插入结果,确认 5 万条数据完整入库,保证分片前数据基数达标。

js 复制代码
db.users.find().count()

2.5 创建索引

非空集合执行分片前,必须提前建立分片键索引,索引字段需与分片键完全一致;创建 age 升序索引并自定义索引名 ageIndex,为后续范围分片提供索引支撑MongoDB。

js 复制代码
db.users.createIndex({age: 1},{name: 'ageIndex'})

2.6 执行分片操作

sh.shardCollection()为集合分片核心命令,mydb.users为集合全限定名,{age:1}代表以 age 字段做升序范围分片;索引就绪后执行该命令,config 服务生成分片元数据,均衡器自动拆分 Chunk 并分配至各分片。

js 复制代码
sh.shardCollection("mydb.users", {age: 1})

2.7 查看分片信息

sh.status()查看分片集群全局元数据,可查看数据库分片开关、集合分片键、Chunk 区间分布、各分片承载数据块数量,用于校验范围分片是否生效、数据拆分边界是否符合规则。

js 复制代码
sh.status()

3. 哈希分片

哈希分片对分片键值进行哈希运算后划分 Chunk,数据随机均匀打散至所有分片,有效规避范围分片的数据倾斜、写入热点问题;缺点是分片键范围查询会全分片广播,查询效率偏低MongoDB,本实验基于 age 哈希分片对比范围分片差异。

3.1 切换数据库

复用 mydb 数据库,新建独立集合 users1 用于哈希分片实验,和上方范围分片 users 做对照。

js 复制代码
use mydb

3.2 创建集合

创建全新集合 users1,隔离实验数据,避免与 users 集合数据互相干扰。

js 复制代码
db.createCollection('users1')

3.3 批量插入数据

同 users 插入逻辑,批量写入 50000 条异构测试数据,保证数据体量满足 Chunk 自动分裂条件,直观体现哈希分片均匀打散数据的特性。

js 复制代码
const bulk = db.users1.initializeUnorderedBulkOp();
for (let i = 1; i <= 50000; i++) {
bulk.insert({
username: `user${i}`,
age: Math.floor(Math.random() * 60) + 18,
gender: Math.random() > 0.5 ? 'Male' : 'Female',
height: Math.floor(Math.random() * 60) + 150,
weight: Math.floor(Math.random() * 50) + 50
});
}
bulk.execute();

3.4 创建哈希索引

哈希分片要求分片键字段建立hashed类型专用索引,区别于范围分片普通升序索引;非空集合必须预先创建哈希索引,才可执行分片命令。

js 复制代码
db.users1.createIndex({age: "hashed"})

3.5 执行分片操作

{age:"hashed"}标识采用哈希分片策略,MongoDB 内部自动计算 age 字段哈希值、分配 Chunk 至各分片,无需人工划定数值区间。

js 复制代码
sh.shardCollection("mydb.users1", {age: "hashed"})

3.6 查看分片信息

查看哈希分片 users1 的分片元数据;通过 sh.status 查看哈希分片的 Chunk 分布,对比 users 范围分片的数据分布规律差异。

js 复制代码
sh.status()

4. 删除分片

删除分片是集群缩容操作,removeShard为异步指令,均衡器后台自动迁移分片内所有 Chunk 至其余分片;若待删分片是某数据库主分片(Primary Shard),需先行迁移主分片再执行删除,否则命令报错无法执行MongoDB。

4.1 删除分片

removeShard:"shard"中 shard 替换为实际分片副本集名称;命令提交后后台自动数据搬迁,重复执行该命令查看搬迁进度,直至状态为 completed 才算分片移除成功。

js 复制代码
db.adminCommand({removeShard: "shard"})

4.2 迁移数据库主分片

每个数据库默认绑定一个主分片,主分片存储库内所有未分片集合;待删分片绑定主分片时,通过movePrimary变更库的主分片指向,仅修改 config 元数据、不迁移存量数据;database 替换库名、to 填写目标可用分片名称,主分片迁移完成后才可正常删除分片。

js 复制代码
db.adminCommand({movePrimary: "database", to: "shard"})
相关推荐
ClouGence9 小时前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将11 小时前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils1 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
葫芦和十三2 天前
图解 MongoDB 08|ESR 原则:复合索引的字段顺序怎么定
后端·mongodb·agent
葫芦和十三2 天前
图解 MongoDB 07|索引类型:七种索引,七种访问形状
后端·mongodb·agent
倔强的石头_3 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
葫芦和十三3 天前
图解 MongoDB 06|模式演进:无 schema 是优势还是债
后端·mongodb·agent
葫芦和十三3 天前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
葫芦和十三4 天前
图解 MongoDB 03|CRUD 全链路:一条 find 怎么穿过 WiredTiger
后端·mongodb·agent