前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Mongodb7.0.14集群分片部署

Mongodb7.0.14集群分片部署

作者头像
DBA实战
发布2024-10-10 19:26:09
发布2024-10-10 19:26:09
20500
代码可运行
举报
文章被收录于专栏:DBA实战DBA实战
运行总次数:0
代码可运行

概述

MongoDB 集群分片是一种水平扩展数据库的方法,通过将数据分布在多个物理服务器上,提高系统的性能和可扩展性。分片的核心思想是将数据分成多个部分(称为“分片”),每个分片存储在不同的服务器上,从而分散负载,提高查询和写入性能。

使用场景

  1. 大规模数据存储:当单个 MongoDB 实例无法处理大量数据时,可以使用分片来分布数据,提高存储容量。
  2. 高并发访问:在高并发读写场景下,分片可以分散负载,提高系统的响应速度和吞吐量。
  3. 地理分布:当数据需要在全球范围内访问时,分片可以将数据分布到不同的地理位置,减少网络延迟。
  4. 实时分析:在需要实时处理大量数据的场景下,分片可以提高查询性能,支持实时分析和报表生成。

优缺点

优点

  1. 高可扩展性:通过增加更多的分片服务器,可以轻松扩展存储和计算能力。
  2. 高可用性:每个分片可以配置为副本集,提供数据冗余和故障恢复能力。
  3. 负载均衡:数据和查询负载可以均匀分布在多个分片上,提高整体性能。
  4. 灵活的数据分布:可以根据业务需求选择合适的分片键,优化数据分布和查询性能。

缺点

  1. 复杂性:分片架构比单实例架构更复杂,需要更多的管理和维护工作。
  2. 配置和管理成本:需要配置路由服务器、配置服务器和分片服务器,增加了初始设置和运维成本。
  3. 数据迁移:在分片键选择不当或数据增长过快时,可能需要重新平衡数据,导致额外的开销。
  4. 查询性能:跨分片的聚合查询和联合查询可能会影响性能,需要优化查询策略。

节点作用

  1. mongos(路由服务器)
  • 作用:作为客户端应用程序和分片集群之间的接口,负责路由查询和写入操作到正确的分片。
  • 特点:无状态,可以横向扩展,提高系统的并发处理能力。
  1. shard(分片服务器)
  • 作用:存储实际的数据,每个分片可以是一个独立的 MongoDB 实例或副本集。
  • 特点:数据分布在多个分片上,每个分片负责一部分数据,提高存储和查询性能。
  1. config server(配置服务器)
  • 作用:存储集群的元数据信息,如分片键、分片分布、路由信息等。
  • 特点:通常使用副本集形式部署,确保高可用性和数据冗余。

下载地址

MongoDB Community Downloads | MongoDB

配置hosts解下

代码语言:javascript
代码运行次数:0
运行
复制
vim /etc/hosts
10.10.10.21 mon1
10.10.10.22 mon2
10.10.10.23 mon3

集群规划

代码语言:javascript
代码运行次数:0
运行
复制
10.10.10.21 mon1:mongos(30000)\config(27017-主)\shard1(40001-主)\shard2(40002-从)\shard3(40003-从)
10.10.10.22 mon2:mongos(30000)\config(27017-从)\shard1(40001-从)\shard2(40002-主)\shard3(40003-从)
10.10.10.23 mon3:mongos(30000)\config(27017-从)\shard1(40001-从)\shard2(40002-从)\shard3(40003-主)

3台机,每台机5个组件,分别mongos 1 个,config server 1 个,shard server 3 个

部署

解压(三台机器)

代码语言:javascript
代码运行次数:0
运行
复制
mongosh:
wget https://downloads.mongodb.com/compass/mongosh-2.3.1-linux-x64.tgz
tar xvf mongosh-2.3.1-linux-x64.tgz
mongodb:
tar xvf mongodb-linux-x86_64-rhel70-7.0.14.tgz
mv  mongodb-linux-x86_64-rhel70-7.0.14 mongodb

创建相关目录(三台机器)

代码语言:javascript
代码运行次数:0
运行
复制
[root@easyliao012 monogocluster]# mkdir -p /monogocluster/shard{1,2,3}/{config,log,data}
[root@easyliao012 monogocluster]#mkdir -p /monogocluster/mongos/{config,log,data}
[root@easyliao012 monogocluster]# mkdir -p /monogocluster/config/{config,log,data}

内存配置

shard 和 config 服务器的 WiredTiger 缓存大小的分配建议:

1. Shard 服务器的缓存大小分配:

对于每个 Shard 服务器,可以根据数据量和预计的工作负载来调整缓存大小。一般来说,将缓存大小设置为机器内存的 50%-75% 是比较常见的做法。

例如,如果你的Shard服务器有16GB的内存,可以将缓存大小设置为8GB-12GB,即 wiredTiger.engineConfig.cacheSizeGB:8

或者wiredTiger.engineConfig.cacheSizeGB:12。

这样可以让MongoDB利用一部分内存来缓存数据和索引,提高读取操作的性能

2. Config 服务器的缓存大小分配:

Config 服务器主要用于存储集群的元数据信息,相对来说对内存的需求较小。通常可以将缓存大小设置为机器内存的 25%-50%。

例如,如果你的 Config 服务器有 8GB 的内存,可以将缓存大小设置为 2GB - 4GB,即 wiredTiger.engineConfig.cacheSizeGB: 2

或者 wiredTiger.engineConfig.cacheSizeGB: 4。

需要注意的是,缓存大小的分配应该综合考虑系统内存大小、数据量、查询模式等因素,以达到最佳性能和资源利用的平衡点。

配置集群分片配置文件

配置文件config(三台机器)

vim /monogocluster/config/config/mongo-conf

代码语言:javascript
代码运行次数:0
运行
复制
# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/config/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen

# 网络设置
net:
  port: 27017                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制

# 数据目录
storage:
  dbPath: /monogocluster/config/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 3               # 根据情况配置内存  

# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/config/data/mongod.pid # PID 文件路径 

#复制集名称  
replication:
  replSetName: "mgconfig"

#作为配置服务  
sharding:
  clusterRole: configsvr

配置文件mongos(三台机器)

vim /monogocluster/mongos/config/mongo-conf

代码语言:javascript
代码运行次数:0
运行
复制
# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/mongos/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen

# 网络设置
net:
  port: 30000                    # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制

# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/mongos/data/mongod.pid # PID 文件路径 

#网络延迟阈值  
replication:
  localPingThresholdMs: 15

#关联配置服务
sharding:
  configDB: mgconfig/mon1:27017,mon2:27017,mon3:27017

配置文件mongoshard1(三台机器)

vim /monogocluster/shard1/config/mongo-conf

代码语言:javascript
代码运行次数:0
运行
复制
# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/shard1/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen

# 网络设置
net:
  port: 40001                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制

# 数据目录
storage:
  dbPath: /monogocluster/shard1/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 7               # 根据情况配置内存 

# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/shard1/data/mongod.pid # PID 文件路径 

#复制集名称
replication:
  replSetName: "shard1"

#慢查询
operationProfiling:
  slowOpThresholdMs : 100
  mode: "slowOp"

#作为分片服务
sharding:
  clusterRole: shardsvr

配置文件mongoshard2(三台机器)

vim /monogocluster/shard2/config/mongo-conf

代码语言:javascript
代码运行次数:0
运行
复制
# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/shard2/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen

# 网络设置
net:
  port: 40002                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制

# 数据目录
storage:
  dbPath: /monogocluster/shard2/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 7               # 根据情况配置内存 

# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/shard2/data/mongod.pid # PID 文件路径 

#复制集名称
replication:
  replSetName: "shard2"

#慢查询
operationProfiling:
  slowOpThresholdMs : 100
  mode: "slowOp"

#作为分片服务
sharding:
  clusterRole: shardsvr

配置文件mongoshard3(三台机器)

vim /monogocluster/shard3/config/mongo-conf

代码语言:javascript
代码运行次数:0
运行
复制
# 日志设置
systemLog:
  destination: file                # 日志写入文件
  path: /monogocluster/shard3/log/mongodb.log # 日志文件路径     
  logAppend: true                  # 追加日志
  logRotate: rename                # 日志轮转方式,支持 rename 或 reopen

# 网络设置
net:
  port: 40003                     # MongoDB 默认端口
  bindIp: 0.0.0.0                 # 允许从所有 IP 访问,生产环境建议限制

# 数据目录
storage:
  dbPath: /monogocluster/shard3/data          # 数据文件存放路径
  wiredTiger:
    engineConfig:
      cacheSizeGB: 7               # 根据情况配置内存 

# 进程设置
processManagement:
  fork: true                       # 以后台进程方式运行
  pidFilePath: /monogocluster/shard3/data/mongod.pid # PID 文件路径 

#复制集名称
replication:
  replSetName: "shard3"

#慢查询
operationProfiling:
  slowOpThresholdMs : 100
  mode: "slowOp"

#作为分片服务
sharding:
  clusterRole: shardsvr

启动config服务并配置复制集(3台机器执行相同操作)

代码语言:javascript
代码运行次数:0
运行
复制
/opt/mongodb/bin/mongod --config /monogocluster/config/config/mongo-conf

连接一个config实例
mongosh mongodb://easyliao012:27017
初始化复制集
这个 mgconfig 名字一定要和config 配置文件中 replSet 的名字一致

config={_id:"mgconfig",members:[ 
{_id:0,host:"mon1:27017"}, 
{_id:1,host:"mon2:27017"}, 
{_id:2,host:"mon3:27017"}, 
]};

rs.initiate(config)
rs.status()

启动shard分片并配置副本集

代码语言:javascript
代码运行次数:0
运行
复制
---shard1
##启动
/opt/mongodb/bin/mongod --config /monogocluster/shard1/config/mongo-conf
##配置副本集
权重越高priority:3会被指定为主节点
连接任意一个shard1实例
[root@mysql1 bin]# mongosh mongodb://mon1:40001
创建复制集
use admin 

config={_id:"shard1",members:[ 
{_id:0,host:"mon1:40001",priority:3}, 
{_id:1,host:"mon2:40001",priority:1}, 
{_id:2,host:"mon3:40001",priority:1}, 
]}

rs.initiate(config)
rs.status()

--shard2
##启动
/opt/mongodb/bin/mongod --config /monogocluster/shard2/config/mongo-conf
##配置副本集
连接任意一个shard2实例
[root@mysql1 bin]# mongosh mongodb://mon2:40002
创建复制集
use admin 

config={_id:"shard2",members:[ 
{_id:0,host:"mon1:40002",priority:1}, 
{_id:1,host:"mon2:40002",priority:3}, 
{_id:2,host:"mon3:40002",priority:1}, 
]}

rs.initiate(config)
rs.status()

---shard3
##启动
/opt/mongodb/bin/mongod --config /monogocluster/shard3/config/mongo-conf
##配置副本集
连接任意一个shard3实例
[root@mysql1 bin]# mongosh mongodb://mon3:40003
创建复制集
use admin 

config={_id:"shard3",members:[ 
{_id:0,host:"mon1:40003",priority:1}, 
{_id:1,host:"mon2:40003",priority:1}, 
{_id:2,host:"mon3:40003",priority:3}, 
]};

rs.initiate(config)
rs.status()

启动mongos并添加分片

代码语言:javascript
代码运行次数:0
运行
复制
##启动
 /opt/mongodb/bin/mongos --config /monogocluster/mongos/config/mongo-conf 

##登陆路由节点
mongosh mongodb://mon1:30000
use admin
##添加分片
sh.addShard("shard1/mon1:40001,mon2:40001,mon3:40001") 
sh.addShard("shard2/mon1:40002,mon2:40002,mon3:40002")
sh.addShard("shard3/mon1:40003,mon2:40003,mon3:40003")
##查看状态
[direct: mongos] admin> sh.status();
shardingVersion
{ _id: 1, clusterId: ObjectId("66f50c31e8f91dc6de9b9770") }
---
shards
[
  {
    _id: 'shard1',
    host: 'shard1/mon1:40001,mon2:40001,mon3:40001',
    state: 1,
    topologyTime: Timestamp({ t: 1727338491, i: 3 })
  },
  {
    _id: 'shard2',
    host: 'shard2/mon1:40002,mon2:40002,mon3:40002',
    state: 1,
    topologyTime: Timestamp({ t: 1727338512, i: 1 })
  },
  {
    _id: 'shard3',
    host: 'shard3/mon1:40003,mon2:40003,mon3:40003',
    state: 1,
    topologyTime: Timestamp({ t: 1727338518, i: 3 })
  }
]
---
active mongoses
[ { '7.0.14': 3 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{ 'Currently enabled': 'yes', 'Currently running': 'no' }
---
databases
[
  {
    database: { _id: 'config', primary: 'config', partitioned: true },
    collections: {}
  }
]

创建账户

代码语言:javascript
代码运行次数:0
运行
复制
##在mongos创建一个管理员账户用于数据库操作,
mongosh mongodb://mon1:30000
mongos>use admin
mongos>db.createUser({user:"root",pwd:"sdhjfREWFWEF23e",roles:["root"]})
mongos>db.auth("root","sdhjfREWFWEF23e") 

##在shard1、shard2、shard3分别创建副本集管理员账户,每个分片都要创建主节点上
mongosh mongodb://mon1:40001
mongosh mongodb://mon2:40002
mongosh mongodb://mon3:40003
mongos>use admin
mongos>db.createUser({user:"root",pwd:"sdhjfREWFWEF23e",roles:["root"]})
mongos>db.auth("root","sdhjfREWFWEF23e")

安全认证

代码语言:javascript
代码运行次数:0
运行
复制
##创建秘钥文件
openssl rand -base64 753 >/monogocluster/config/mongo-keyfile
#将主节点生成的mongo-keyfile文件拷贝到其他服务器目录,注意权限
chmod 600 /monogocluster/config/mongo-keyfile
##拷贝秘钥
root@mysql1 bin]# scp keyFile.key mongodb@mon2:/monogocluster/config/
root@mysql1 bin]# scp keyFile.key mongodb@mon3:/monogocluster/config/
代码语言:javascript
代码运行次数:0
运行
复制
修改config server,shard1,shard2,shard3配置文件,增加如下参数:
security:
  authorization: "enabled"
  keyFile: /monogocluster/config/mongo-keyfile

修改mongos 配置文件,增加如下参数:
security:
  keyFile: /monogocluster/config/mongo-keyfile

关闭服务

代码语言:javascript
代码运行次数:0
运行
复制
关闭集群
第一步:关闭所有mongos路由实例
第二步:关闭所有分片
第三步:关闭所有的配置服务器

##关闭mongos
mongosh mongodb://127.0.0.1:30000
use admin
db.auth('root','sdhjfREWFWEF23e')
db.shutdownServer()

##关闭分片
/opt/mongodb/bin/mongod --config /monogocluster/shard3/config/mongo-conf --shutdown
/opt/mongodb/bin/mongod --config /monogocluster/shard2/config/mongo-conf  --shutdown
/opt/mongodb/bin/mongod --config /monogocluster/shard1/config/mongo-conf  --shutdown

##关闭configservers
/opt/mongodb/bin/mongod --config /monogocluster/config/config/mongo-conf --shutdown

启动服务

代码语言:javascript
代码运行次数:0
运行
复制
启动集群
 第一步:启动配置服务器
 第二步:启动所有分片
 第三步:启动mongos路由实例

##启动配置服务
/opt/mongodb/bin/mongod --config /monogocluster/config/config/mongo-conf

##启动所有分片
/opt/mongodb/bin/mongod --config /monogocluster/shard1/config/mongo-conf 
/opt/mongodb/bin/mongod --config /monogocluster/shard2/config/mongo-conf 
/opt/mongodb/bin/mongod --config /monogocluster/shard3/config/mongo-conf

## 启动mongos路由实例
/opt/mongodb/bin/mongos --config /monogocluster/mongos/config/mongo-conf

验证数据库

代码语言:javascript
代码运行次数:0
运行
复制
--- 测试服务器分片功能
mongosh mongodb://127.0.0.1:30000
[direct: mongos] test> use admin
[direct: mongos] admin> db.auth('root','sdhjfREWFWEF23e')
--- 启用数据库分片
sh.enableSharding("db2")
--- 启用表分片
sh.shardCollection("db2.user",{"id":1})
sh.shardCollection("db2.user1",{"id":"hashed"})
--- 模拟写入数据
在db2库的user表中循环写入数据
use db2
for(i=1;i<=600;i++){db.tyuser3.insert({"id":i,"name":"ty"+i})}

---查看集群情况
[direct: mongos] db2> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId("66f50c31e8f91dc6de9b9770") }
shards
[{
    _id: 'shard1',
    host: 'shard1/mon1:40001,mon2:40001,mon3:40001',
    state: 1,
    topologyTime: Timestamp({ t: 1727338491, i: 3 })
  },{
    _id: 'shard2',
    host: 'shard2/mon1:40002,mon2:40002,mon3:40002',
    state: 1,
    topologyTime: Timestamp({ t: 1727338512, i: 1 })
  },{
    _id: 'shard3',
    host: 'shard3/mon1:40003,mon2:40003,mon3:40003',
    state: 1,
    topologyTime: Timestamp({ t: 1727338518, i: 3 })
  }]
active mongoses
[ { '7.0.14': 3 } ]


---查看集合分片情况
var dbName = "db2"; 
db.getSiblingDB(dbName).getCollectionNames().forEach(function(collName) {
    print("————————————————————————"); 
    print("Collection: " + collName); 
    db.getSiblingDB(dbName).getCollection(collName).getShardDistribution();
});

输出结果
————————————————————————
Collection: user1
Shard shard1 at shard1/mon1:40001,mon2:40001,mon3:40001
 data : 9KiB docs : 214 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity

Shard shard3 at shard3/mon1:40003,mon2:40003,mon3:40003
 data : 7KiB docs : 175 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity

Shard shard2 at shard2/mon1:40002,mon2:40002,mon3:40002
 data : 9KiB docs : 211 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity

Totals
 data : 26KiB docs : 600 chunks : 0
 Shard shard1 contains 35.64% data, 35.66% docs in cluster, avg obj size on shard : 45B
 Shard shard3 contains 29.19% data, 29.16% docs in cluster, avg obj size on shard : 45B
 Shard shard2 contains 35.16% data, 35.16% docs in cluster, avg obj size on shard : 45B
————————————————————————
Collection: user
Shard shard3 at shard3/mon1:40003,mon2:40003,mon3:40003
 data : 26KiB docs : 600 chunks : 0
 estimated data per chunk : InfinityGiB
 estimated docs per chunk : Infinity

Totals
 data : 26KiB docs : 600 chunks : 0
 Shard shard3 contains 100% data, 100% docs in cluster, avg obj size on shard : 45B

总结

MongoDB 集群分片是一种强大的水平扩展解决方案,适用于大规模数据存储和高并发访问场景。通过将数据分布在多个物理服务器上,分片可以显著提高系统的性能和可扩展性。然而,分片架构的复杂性和管理成本也需要仔细考虑。在选择分片键和配置集群时,应根据业务需求和数据特性进行优化,以充分发挥分片的优势。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA实战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档