MongoDB全面指南:从基础到分布式架构
本文系统全面地介绍了MongoDB数据库的核心概念、部署配置、管理操作以及高可用和分布式架构的构建。内容涵盖MongoDB的概述与特点、安装部署过程、基础管理操作、复制集功能原理与实践、以及分布式架构的搭建与应用。通过学习本文档,读者能够掌握MongoDB在生产环境中的实际应用,构建高性能、高可用的NoSQL数据库解决方案。
本文档系统全面地介绍了MongoDB数据库的核心概念、部署配置、管理操作以及高可用和分布式架构的构建。内容涵盖MongoDB的概述与特点、安装部署过程、基础管理操作、复制集功能原理与实践、以及分布式架构的搭建与应用。通过学习本文档,读者能够掌握MongoDB在生产环境中的实际应用,构建高性能、高可用的NoSQL数据库解决方案。
一、MongoDB概述
1.概述介绍
-
MongoDB名称由来于Humongous,表示巨大的意思,比较适合海量数据的存储和管理;
-
MongoDB支持的数据结构非常松散,是一种类似于JSON的格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。
-
MongoDB中的记录是一个文档(来自于JSON Document),它是一个由字段和值对(field:value)组成的数据结构。
-
MongoDB属于OLTP/OLAP数据库,类似于Oracle、MySQL数据库产品,可以用于海量数据处理,数据管理平台;
2.MongoDB数据库特点
-
MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。
-
MongoDB数据库自身有很多架构的设计,比如高可用架构、分布式架构,并不需要第三方软件支持;
3.MongoDB优势
MongoDB面向开发者具有易用性,并且属于高效数据库;
- 简单直观:以自然的方式来建模,以直观的方式来与数据库交互;
- 结构灵活:弹性模式从容响应需求的频繁变化;
- 快速开发:做更多的事,写更少的代码;
MongoDB原生的高可用和横向扩展能力:
高可用能力介绍:
- Replica set 可以实现2到50个成员节点;
- 具有自恢复能力;
- 具有多中心容灾能力;
- 属于滚动服务,可以实现最小化服务终端
横向扩展能力:
- 需要的时候可以实现无缝扩展
- 对于业务应用来说是全透明的
- 支持多种数据分布策略方式
- 可以轻松支持TB-PB数量级存储
二、MongoDB安装部署
1.安装环境准备
01 需要在redhat或centos 6.2以上系统进行部署;
02 系统开发工具包安装完整;
03 系统IP地址和hosts文件解析正常;
04 系统防火墙功能与SElinux安全功能均要关闭;
05 关闭系统大页内存机制
# 禁用大页内存功能
[root@db01 ~]# vim /etc/rc.local
#在文件末尾添加如下指令:
#先判断是否存在这个文件,再进行修改
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
#执行脚本文件,使配置信息生效
[root@db01 ~]# sh /etc/rc.local
#脚本执行完毕后检查确认
[root@db01 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
[root@db01 ~]# cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
2.安装MongoDB
1. 下载、解压安装包
[root@db01 ~]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.24.tgz
[root@db01 ~]# cd /usr/local/
[root@db01 ~]# tar xf mongodb-linux-x86_64-rhel70-4.2.24.tgz -C /usr/local/
[root@db01 local]# mv mongodb-linux-x86_64-rhel70-4.2.24 mongodb
2. 配置环境变量
[root@db01 local]# vim /etc/profile
export PATH=/usr/local/mongodb/bin:$PATH
[root@db01 local]# source /etc/profile
#确认mongo是否可以执行
[root@db01 local]# mongo
3. 创建用户
[root@db01 local]# useradd mongod
#密码设置为12366
[root@db01 local]# passwd mongod
4. 创建mongodb所需目录结构
[root@db01 local]# mkdir -p /mongodb/conf
[root@db01 local]# mkdir -p /mongodb/log
[root@db01 local]# mkdir -p /mongodb/data
[root@db01 local]# chown -R mongod:mongod /mongodb/
[root@db01 local]# su - mongod
#在指定管理用户下载设置环境变量
[mongod@db01 ~]$ vim ~/.bash_profile
export PATH=/usr/local/mongodb/bin:$PATH
[mongod@db01 ~]$ source ~/.bash_profile
5. 启动服务
#加载启动命令参数,实现程序启动
[mongod@db01 ~]$ mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork
about to fork child process, waiting until server is ready for connections.
forked process: 1872
child process started successfully, parent exiting
#mongodb服务默认端口号信息27017,看到此端口信息表示mongod服务已经运行启动
[mongod@db01 ~]$ ss -lntup |grep mongod
tcp LISTEN 0 128 127.0.0.1:27017 *:* users:(("mongod",pid=1872,fd=11))
6. 加载程序配置文件,实现程序启动
[mongod@db01 ~]$ vim /mongodb/conf/mongo.conf
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/mongodb/data"
processManagement:
fork: true
net:
port: 27017
bindIp: 10.0.0.51,127.0.0.1
[mongod@db01 ~]$ pkill mongod
[mongod@db01 ~]$ ss -lntup |grep mongod
[mongod@db01 ~]$ mongod -f /mongodb/conf/mongo.conf
about to fork child process, waiting until server is ready for connections.
forked process: 2087
child process started successfully, parent exiting
7. mongo登录操作
[mongod@db01 ~]$ mongo
> show databases;
admin 0.000GB
config 0.000GB
local 0.000GB
> show tables;
三、MongoDB基础管理
1.MongoDB默认数据说明
#mongodb默认存在的数据库信息
> show databases;
admin 0.000GB #系统预留库,mongodb系统管理库
config 0.000GB #mongodb配置信息库
local 0.000GB #本地预留库,存储关键日志信息
> show dbs;
> use admin
switched to db admin
> show tables;
system.version
> db
admin
#mongodb中不需要提前创建数据库信息,只要进行use操作后,就会自动创建一个模拟使用的数据库
# 在模拟数据库中创建表或数据信息后,数据库就会被真实创建出来
> use liux;
switched to db liux
> db;
liux
2.MongoDB命令应用种类
DB对象相关命令;
db.[TAB][TAB]
db.help()
db.oldboy.[TAB][TAB]
db.oldboy.help()
RS复制集相关命令(replication set);
rs.[TAB][TAB]
rs.help()
SH分片集群相关命令(sharding cluster);
sh.[TAB][TAB]
sh.help()
3.MongoDB对象操作实践
| mongodb | mysql |
|---|---|
| 库 | 库 |
| 集合 | 表 |
| 文档 | 数据行 |
3.1 MongoDB数据库操作
#创建数据库
> use test;
switched to db test
#删除数据库
> db.dropDatabase();
{ "ok" : 1 }
3.2 MongoDB集合操作
#手工创建集合信息
> use liux
switched to db liux
#创建数据表过程,并且在创建表过程中是不需要有数据类型、属性和约束的信息设置的
> db.createCollection("a");
{ "ok" : 1 }
> show tables;
a
#删除数据表过程
> db.a.drop();
true
> show tables;
>
# 插入一个文档的时候,一个集合就会自动创建
> use liux;
switched to db liux
> db.test.insert({name:"zhangsan"})
WriteResult({ "nInserted" : 1 })
> db.stu.insert({id:101,name:"zhangsan",age:20,gender:"m"})
WriteResult({ "nInserted" : 1 })
> show tables;
stu
test
> db.stu.insert({id:102,name:"lisi"})
3.3 MongoDB文档操作
# 数据录入
> for(i=0;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()})};
WriteResult({ "nInserted" : 1 })
# 查询数据行数
> db.log.count();
10000
#全表信息查询
> db.log.find();
# 每页显示50条记录信息
> DBQuery.shellBatchSize=50;
50
> db.log.find()
# 按照条件查询数据
> db.log.find({uid:999})
{ "_id" : ObjectId("65308bf9945d0d972f09658f"), "uid" : 999, "name" : "mongodb", "age" : 6, "date" : ISODate("2023-10-19T01:52:57.017Z") }
# 以标准的json格式输出内容
> db.log.find({uid:999}).pretty()
{
"_id" : ObjectId("65308bf9945d0d972f09658f"),
"uid" : 999,
"name" : "mongodb",
"age" : 6,
"date" : ISODate("2023-10-19T01:52:57.017Z")
}
>
# 删除集合中所有记录
> db.log.remove({})
WriteResult({ "nRemoved" : 10000 })
> db.log.find()
# 查看集合存储信息
#集合中索引+数据库压缩存储之后的大小
> for(i=0;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()})}
WriteResult({ "nInserted" : 1 })
> db.log.totalSize()
286720
> db.log.stats()
3.4 MongoDB用户权限管理
验证库(authenticationDatabase):建立用户时use到的库,就是验证库,在使用用户时,要加上验证库才能登录,主要限制远程
对于管理员用户,必须在admin下创建:
- 建立用户时,use到的库,就是此用户的验证库
- 登录时,必须明确指定验证库才能登录
- 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
- 如果直接登录到数据库,不进行use,默认的验证库是test,不是企业生产建议的
- 从3.6版本开始,不添加bindIp参数,默认不让远程登录,只能本地管理员登录
01 创建超级管理员
管理所有数据库(必须use admin再去创建)
#创建管理员用户
> use admin
switched to db admin
> db.createUser(
{
user: "root",
pwd: "root123",
roles: [ { role: "root", db: "admin" } ]
}
)
#验证用户是否创建成功
> db.auth('root','root123')
1
#配置文件中,加入验证功能配置
[root@db01 ~]# vim /mongodb/conf/mongo.conf
security:
authorization: enabled
#重启数据库服务程序,加载用户验证配置功能
[root@db01 ~]# mongod -f /mongodb/conf/mongo.conf --shutdown
killing process with pid: 1466
[root@db01 ~]# mongod -f /mongodb/conf/mongo.conf
about to fork child process, waiting until server is ready for connections.
forked process: 3919
child process started successfully, parent exiting
#用户登录验证
#本地登录
[root@db01 ~]# mongo -uroot -proot123 admin
> use admin
switched to db admin
> show tables
system.users
system.version
#远程登录
[root@db01 ~]# mongo -uroot -proot123 10.0.0.51:27017/admin
02 创建应用用户
#创建用户
> use liux
switched to db liux
> db.createUser(
{
user: "app01",
pwd: "app01",
roles: [ { role: "readWrite", db: "liux" } ]
}
)
#验证用户是否创建成功
> db.auth('app01','app01')
1
#登录用户
[root@db01 ~]# mongo -uapp01 -papp01 liux
03 用户信息管理
#查看用户信息
[root@db01 ~]# mongo -uroot -proot123
> use admin
switched to db admin
> show tables;
system.users
system.version
> db.system.users.find().pretty()
#删除用户
> use liux
switched to db liux
> db.dropUser("app01")
true
说明:对于mongodb单节点数据库服务使用用户信息登录即可,但是对于mongodb复制集环境,尽量使用秘钥方式进行登录
四、MongoDB复制集功能
1.复制集功能概述
MongoDB复制集(replication Set)的主要意义在于实现服务高可用,它的实现依赖于两个方面的功能
- 数据写入时将数据迅速复制到另一个独立节点上
- 在接受写入的节点发生故障时自动选举出一个新的替代节点
在实现高可用的同时,复制集实现了其他几个附加功能:
- 数据分发:将数据从一个区域复制到另一个区域,减少另一个区域的读延迟
- 读写分离:不同类型的压力分别在不同的节点上执行
- 异地容灾:在数据中心故障时候快速切换到异地
一个典型的复制集由3个以上具有投票权的节点组成:(PSS PSA)
- 一个主节点(primary):接收写入操作和选举时投票;
- 两个或多个从节点(secondary):复制主节点上的新数据和选举时投票
- Arbiter(投票节点)
复制集节点之间的数据复制:
-
当一个修改操作发生,无论是插入、更新或删除,到达主节点时,它对数据的操作将被记录下来(经过一些必要的转换);
这些记录称为oplog
-
从节点通过在主节点上打开一个tailable游标不断获取新进入主节点的oplog,并在自己的数据库上回放,以此保证更主节点数据一致
2.复制集功能原理
基本构成是1主2从的结构,自带互相监控投票机制(Raft-MongoDB,Paxos-MGR 变种方式 )
如果发生主库宕机,复制集内部会进行投票选举,选择一个新的主库替代原有主库对外提供服务,同时复制集会自动通知客户端程序;
主库已经发生切换了,应用就会连接到新的主库;
通过选举完成故障恢复,具有投票权的节点之间两两互相发送心跳:
- 当5次心跳未收到时,判定为节点失联;
- 如果失联的是主节点,从节点会发起选举,选出新的主节点
- 如果失联的是从节点,则不会产生新的选举;
- 选举是基于Raft一致性算法实现,选举成功的必要条件是大多数投票节点存活;
3.复制集功能配置
3.1 复制集功能环境规划准备
需要三个以上的mongodb节点或者多实例环境:
| 实例信息 | 地址 | 端口 |
|---|---|---|
| 实例01 | 10.0.0.51 | 28017 |
| 实例02 | 10.0.0.51 | 28018 |
| 实例03 | 10.0.0.51 | 28019 |
| 实例04 | 10.0.0.51 | 28020 |
1. 创建多实例目录
[root@db01 ~]# su mongod
[mongod@db01 ~]# mkdir -p /mongodb/28017/conf /mongodb/28017/data /mongodb/28017/log
[mongod@db01 ~]# mkdir -p /mongodb/28018/conf /mongodb/28018/data /mongodb/28018/log
[mongod@db01 ~]# mkdir -p /mongodb/28019/conf /mongodb/28019/data /mongodb/28019/log
[mongod@db01 ~]# mkdir -p /mongodb/28020/conf /mongodb/28020/data /mongodb/28020/log
2. 创建多实例配置文件
[mongod@db01 ~]$
cat > /mongodb/28017/conf/mongod.conf << EOF
systemLog:
destination: file
path: "/mongodb/28017/log/mongodb.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/mongodb/28017/data"
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
port: 28017
bindIp: 10.0.0.51,127.0.0.1
replication:
oplogSizeMB: 2048
replSetName: my_repl
EOF
#定义oplog日志存储量,实质是数据库服务的表的大小
oplogSizeMB: 2048
#表示复制集的名称,要和后面创建的集群名称一致
replSetName: my_repl
[mongod@db01 ~]$ cp /mongodb/28017/conf/mongod.conf /mongodb/28018/conf/
[mongod@db01 ~]$ cp /mongodb/28017/conf/mongod.conf /mongodb/28019/conf/
[mongod@db01 ~]$ cp /mongodb/28017/conf/mongod.conf /mongodb/28020/conf/
[mongod@db01 ~]$ sed -i 's#28017#28018#g' /mongodb/28018/conf/mongod.conf
[mongod@db01 ~]$ sed -i 's#28017#28019#g' /mongodb/28019/conf/mongod.conf
[mongod@db01 ~]$ sed -i 's#28017#28020#g' /mongodb/28020/conf/mongod.conf
3. 启动运行复制集多实例
[mongod@db01 ~]$ mongod -f /mongodb/28017/conf/mongod.conf
[mongod@db01 ~]$ mongod -f /mongodb/28018/conf/mongod.conf
[mongod@db01 ~]$ mongod -f /mongodb/28019/conf/mongod.conf
[mongod@db01 ~]$ mongod -f /mongodb/28020/conf/mongod.conf
[mongod@db01 ~]$ netstat -lntup|grep 280
3.2 复制集功能配置操作
- 实现1主2从,从库为普通从库
[mongod@db01 ~]$ mongo --port 28017 admin
>config = {_id: 'my_repl', members: [
{_id: 0, host: '10.0.0.51:28017'},
{_id: 1, host: '10.0.0.51:28018'},
{_id: 2, host: '10.0.0.51:28019'}]
}
> rs.initiate(config)
{ "ok" : 1 }
> rs.initiate(config)
{ "ok" : 1 }
my_repl:SECONDARY>
my_repl:PRIMARY>
-- 主从关系建立完毕后,会实现底层自动克隆过程,不用考虑备份恢复数据问题
-- 对于secondary节点是默认不支持任何读和写操作的,后期可以打开节点的读功能
- 实现1主1从,加1个arbiter
[mongod@master ~]$ mongo --port 28017 admin
>config = {_id: 'my_repl', members: [
{_id: 0, host: '10.0.0.51:28017'},
{_id: 1, host: '10.0.0.51:28018'},
{_id: 2, host: '10.0.0.51:28019',"arbiterOnly": true}]
}
> rs.initiate(config)
-- 不建议进行应用,当只有三个节点时,会有一定的风险性
3.3 复制集功能管理应用
1. 查看复制集状态信息
#-- 查看整体复制集状态信息
rs.status()
#-- 查看主节点状态信息
rs.isMaster()
2. 添加删除复制集节点(从节点)
#添加复制集节点
my_repl:PRIMARY> rs.add("10.0.0.51:28020")
my_repl:PRIMARY> rs.status();
#删除复制集节点
my_repl:PRIMARY> rs.remove("10.0.0.51:28020")
3. 添加删除节点(仲裁节点)
my_repl:PRIMARY> rs.addArb("10.0.0.51:28020")
my_repl:PRIMARY> rs.isMaster()
{
"hosts" : [
"10.0.0.51:28017",
"10.0.0.51:28018",
"10.0.0.51:28019"
],
"arbiters" : [
"10.0.0.51:28020"
]
...
my_repl:PRIMARY> rs.remove("10.0.0.51:28020")
3.4 复制集特殊节点应用
| 特殊节点 | 解释说明 |
|---|---|
| arbiter | 主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务 |
| hidden | 隐藏节点,不参与选主,也不对外提供服务 |
| delay | 延时节点,数据落后于主库一段时间 因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏) |
配置延时节点方法(一般延时节点也配置为hidden)
cfg=rs.conf()
cfg.members[0].priority=0
cfg.members[0].hidden=true
cfg.members[0].slaveDelay=120
rs.reconfig(cfg)
# 查看复制集节点信息
my_repl:PRIMARY> rs.status();
{
"_id" : 0,
"name" : "10.0.0.51:28017",
},
{
"_id" : 1,
"name" : "10.0.0.51:28018",
},
{
"_id" : 2,
"name" : "10.0.0.51:28019",
},
{
"_id" : 3,
"name" : "10.0.0.51:28020",
}
# 进行特殊节点设置
my_repl:PRIMARY> cfg=rs.conf()
my_repl:PRIMARY> cfg.members[3].priority=0
my_repl:PRIMARY> cfg.members[3].hidden=true
my_repl:PRIMARY> cfg.members[3].slaveDelay=120
my_repl:PRIMARY> rs.reconfig(cfg)
# 查看配置信息情况
my_repl:PRIMARY> rs.conf();
{
"_id" : 3,
"host" : "10.0.0.51:28020",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : true,
"priority" : 0,
"tags" : {
},
"slaveDelay" : NumberLong(120),
"votes" : 1
}
# 取消特殊节点设置
cfg=rs.conf()
cfg.members[3].priority=1
cfg.members[3].hidden=false
cfg.members[3].slaveDelay=0
rs.reconfig(cfg)
3.5 复制集操作梳理补充
admin> rs.config()
或者
admin> rs.conf()
--查看副本集的配置信息
admin> rs.status()
--查看副本集各成员的状态
admin> rs.stepDown()
--副本集角色切换(将主库降级)
admin> rs.freeze(300)
-- 锁定从,使其不会转变成主库;freeze()和stepDown单位都是秒。
admin> rs.slaveOk()
--设置副本节点可读:在副本节点执行
3.6 复制集安全加固操作
实现复制集之间利用秘钥文件进行通讯;
1. 复制集节点生成keyfile文件
[mongod@db01 ~]$ openssl rand -base64 756 >/mongodb/28017/conf/keyfile
[mongod@db01 ~]$ chmod 600 /mongodb/28017/conf/keyfile
[mongod@db01 ~]$ \cp -a /mongodb/28017/conf/keyfile /mongodb/28018/conf/keyfile
[mongod@db01 ~]$ \cp -a /mongodb/28017/conf/keyfile /mongodb/28019/conf/keyfile
[mongod@db01 ~]$ \cp -a /mongodb/28017/conf/keyfile /mongodb/28020/conf/keyfile
2. 复制集节点开启验证功能:
[mongod@db01 ~]$ cat >> /mongodb/28017/conf/mongod.conf <<EOF
security:
keyFile: /mongodb/28017/conf/keyfile
EOF
[mongod@db01 ~]$ cat >> /mongodb/28018/conf/mongod.conf <<EOF
security:
keyFile: /mongodb/28018/conf/keyfile
EOF
[mongod@db01 ~]$ cat >> /mongodb/28019/conf/mongod.conf <<EOF
security:
keyFile: /mongodb/28019/conf/keyfile
EOF
[mongod@db01 ~]$ cat >> /mongodb/28020/conf/mongod.conf <<EOF
security:
keyFile: /mongodb/28020/conf/keyfile
EOF
3. 关闭已有复制集节点服务,进行重启操作
# 关闭所有节点服务17,18,19,20
[mongod@db01 ~]$ mongo --port 28017 admin
use admin
db.shutdownServer()
# 启动所有节点服务
[mongod@db01 ~]$ mongod -f /mongodb/28017/conf/mongod.conf
[mongod@db01 ~]$ mongod -f /mongodb/28018/conf/mongod.conf
[mongod@db01 ~]$ mongod -f /mongodb/28019/conf/mongod.conf
[mongod@db01 ~]$ mongod -f /mongodb/28020/conf/mongod.conf
[mongod@db01 ~]$ netstat -lntup|grep 280
五、MongoDB分布式架构
MongoDB的sharding cluster 分片集群可以实现分布式架构构建;
1.MongoDB分布式架构搭建
1.1 环境准备
需要十个以上的mongodb节点或者多实例环境:
| 实例信息 | 地址 | 端口 |
|---|---|---|
configServer节点 |
38018-38020 |
|
| 实例01 | 10.0.0.51 | 38018 |
| 实例02 | 10.0.0.51 | 38019 |
| 实例03 | 10.0.0.51 | 38020 |
shard节点-sh1 |
38021-38023 |
|
| 实例01(主节点) | 10.0.0.51 | 38021 |
| 实例02(从节点) | 10.0.0.51 | 38022 |
| 实例03(从节点-arbiter) | 10.0.0.51 | 38023 |
shard节点-sh2 |
38024-38026 |
|
| 实例01(主节点) | 10.0.0.51 | 38024 |
| 实例02(主节点) | 10.0.0.51 | 38025 |
| 实例03(主节点) | 10.0.0.51 | 38026 |
mongos节点 |
||
| 实例01(主节点) | 10.0.0.51 | 38017 |

1.2 shard节点配置过程
1. 创建多实例与配置文件
# 目录信息创建
[mongod@db01 ~]$ mkdir -p /mongodb/38021/conf /mongodb/38021/log /mongodb/38021/data
[mongod@db01 ~]$ mkdir -p /mongodb/38022/conf /mongodb/38022/log /mongodb/38022/data
[mongod@db01 ~]$ mkdir -p /mongodb/38023/conf /mongodb/38023/log /mongodb/38023/data
[mongod@db01 ~]$ mkdir -p /mongodb/38024/conf /mongodb/38024/log /mongodb/38024/data
[mongod@db01 ~]$ mkdir -p /mongodb/38025/conf /mongodb/38025/log /mongodb/38025/data
[mongod@db01 ~]$ mkdir -p /mongodb/38026/conf /mongodb/38026/log /mongodb/38026/data
# 编写配置文件(第01组复制集配置:21-23 1主 1从 1arb)
[mongod@db01 ~]$ cat > /mongodb/38021/conf/mongodb.conf <<EOF
systemLog:
destination: file
path: /mongodb/38021/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/38021/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 10.0.0.51,127.0.0.1
port: 38021
replication:
oplogSizeMB: 2048
replSetName: sh1
sharding:
clusterRole: shardsvr
processManagement:
fork: true
EOF
[mongod@db01 ~]$ \cp /mongodb/38021/conf/mongodb.conf /mongodb/38022/conf/
[mongod@db01 ~]$ \cp /mongodb/38021/conf/mongodb.conf /mongodb/38023/conf/
[mongod@db01 ~]$ sed -i 's#38021#38022#g' /mongodb/38022/conf/mongodb.conf
[mongod@db01 ~]$ sed -i 's#38021#38023#g' /mongodb/38023/conf/mongodb.con
# 编写配置文件(第02组复制集配置:24-26 1主 1从 1arb)
[mongod@db01 ~]$ cat > /mongodb/38024/conf/mongodb.conf <<EOF
systemLog:
destination: file
path: /mongodb/38024/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/38024/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 10.0.0.51,127.0.0.1
port: 38024
replication:
oplogSizeMB: 2048
replSetName: sh2
sharding:
clusterRole: shardsvr
processManagement:
fork: true
EOF
[mongod@db01 ~]$ \cp /mongodb/38024/conf/mongodb.conf /mongodb/38025/conf/
[mongod@db01 ~]$ \cp /mongodb/38024/conf/mongodb.conf /mongodb/38026/conf/
[mongod@db01 ~]$ sed -i 's#38024#38025#g' /mongodb/38025/conf/mongodb.conf
[mongod@db01 ~]$ sed -i 's#38024#38026#g' /mongodb/38026/conf/mongodb.conf
2. 启动运行多个实例程序
[mongod@db01 ~]$ mongod -f /mongodb/38021/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38022/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38023/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38024/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38025/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38026/conf/mongodb.conf
[mongod@db01 ~]$ netstat -lntup|grep 380
3. 配置复制集信息
# 第01组复制集配置:21-23 1主 1从 1arb
[mongod@master ~]$ mongo --port 38021
>use admin
>config = {_id: 'sh1', members: [
{_id: 0, host: '10.0.0.51:38021'},
{_id: 1, host: '10.0.0.51:38022'},
{_id: 2, host: '10.0.0.51:38023',"arbiterOnly": true}]
}
> rs.initiate(config)
{ "ok" : 1 }
# 第02组复制集配置:24-26 1主 1从 1arb
[mongod@master ~]$ mongo --port 38024
> use admin
> config = {_id: 'sh2', members: [
{_id: 0, host: '10.0.0.51:38024'},
{_id: 1, host: '10.0.0.51:38025'},
{_id: 2, host: '10.0.0.51:38026',"arbiterOnly": true}]
}
> rs.initiate(config)
{ "ok" : 1 }
1.3 config节点配置过程
1. 创建多个实例目录与配置文件
# 目录信息创建
[mongod@db01~]$ mkdir -p /mongodb/38018/conf /mongodb/38018/log /mongodb/38018/data
[mongod@db01~]$ mkdir -p /mongodb/38019/conf /mongodb/38019/log /mongodb/38019/data
[mongod@db01~]$ mkdir -p /mongodb/38020/conf /mongodb/38020/log /mongodb/38020/data
# 编写配置文件
[mongod@master ~]$ cat > /mongodb/38018/conf/mongodb.conf <<EOF
systemLog:
destination: file
path: /mongodb/38018/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/38018/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 10.0.0.51,127.0.0.1
port: 38018
replication:
oplogSizeMB: 2048
replSetName: configRepSet
sharding:
clusterRole: configsvr
processManagement:
fork: true
EOF
[mongod@db01 ~]$ \cp /mongodb/38018/conf/mongodb.conf /mongodb/38019/conf/
[mongod@db01 ~]$ \cp /mongodb/38018/conf/mongodb.conf /mongodb/38020/conf/
[mongod@db01 ~]$ sed -i 's#38018#38019#g' /mongodb/38019/conf/mongodb.conf
[mongod@db01 ~]$ sed -i 's#38018#38020#g' /mongodb/38020/conf/mongodb.conf
2. 启动运行多个实例
[mongod@db01 ~]$ mongod -f /mongodb/38018/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38019/conf/mongodb.conf
[mongod@db01 ~]$ mongod -f /mongodb/38020/conf/mongodb.conf
[mongod@db01 ~]$ netstat -lntup|grep 380
3. 配置复制集信息
# 复制集配置:
[mongod@db01 ~]$ mongo --port 38018
> use admin
> config = {_id: 'configRepSet', members: [
{_id: 0, host: '10.0.0.51:38018'},
{_id: 1, host: '10.0.0.51:38019'},
{_id: 2, host: '10.0.0.51:38020'}]
}
> rs.initiate(config)
{
"ok" : 1,
"$gleStats" : {
"lastOpTime" : Timestamp(1677951388, 1),
"electionId" : ObjectId("000000000000000000000000")
},
"lastCommittedOpTime" : Timestamp(0, 0)
}
说明:
configserver可以是一个节点,官方建议复制集,并且configserver不能有arbiter,最新版本中,要求必须是复制集;
mongodb 3.4之后,虽然要求config server为replica set,但是不支持arbiter
1.4 mongos节点配置过程
1. 创建多个实例目录与配置文件
# 目录信息创建
[mongod@db01 ~]$ mkdir -p /mongodb/38017/conf /mongodb/38017/log
# 编写配置文件
[mongod@db01 ~]$ cat > /mongodb/38017/conf/mongos.conf <<EOF
systemLog:
destination: file
path: /mongodb/38017/log/mongos.log
logAppend: true
net:
bindIp: 10.0.0.51,127.0.0.1
port: 38017
sharding:
configDB: configRepSet/10.0.0.51:38018,10.0.0.51:38019,10.0.0.51:38020
processManagement:
fork: true
EOF
2. 启动运行多个实例
[mongod@db01 ~]$ mongos -f /mongodb/38017/conf/mongos.conf
1.5 分片集群添加节点
连接到其中一个mongos(10.0.0.51),做以下配置:
1. 连接到mongos的admin数据库
[root@db01 conf]# su - mongod
[mongod@db01 ~]$ mongo 10.0.0.51:38017/admin
2. 添加分片
mongos> db.runCommand({addshard: "sh1/10.0.0.51:38021,10.0.0.51:38022,10.0.0.51:38023",name:"shard1"})
mongos> db.runCommand({addshard: "sh2/10.0.0.51:38024,10.0.0.51:38025,10.0.0.51:38026",name:"shard2"})
3. 查看分片
# 列出分片
mongos> db.runCommand({listshards:1})
# 整体状态查看
mongos> sh.status();
2.MongoDB分布式架构应用
在进行分片时,主要关注两个方面:
- 分片键的选择:经常作为查询条件的列
- 分片策略选择:range-范围查找 hash-等值查找 zone-类似枚举
2.1 配置应用基于分片策略-Range
1. 激活数据库分片功能
#-- 对test数据库启动分片功能
[mongod@master ~]$ mongo --port 38017 admin
mongos> use admin
mongos> db.runCommand( { enablesharding : "test" } )
{
"ok" : 1,
"operationTime" : Timestamp(1677958221, 5),
"$clusterTime" : {
"clusterTime" : Timestamp(1677958221, 5),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
2. 指定分盘键对集合分片
# 创建索引(建议在后端节点进行建立)
[root@db01 ~]# mongo --port 38021
mongos> use test
mongos> db.vast.ensureIndex({id:1})
[root@master ~]# mongo --port 38024
mongos> use test
mongos> db.vast.ensureIndex({id:1})
# 开启分片
mongos> use admin
mongos> db.runCommand( { shardcollection : "test.vast",key : {id: 1} } )
3. 集合分片模拟测试
mongos> use test
mongos> for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
mongos> db.vast.stats()
4. 分片结果测试验证
# shard1数据信息查看
[mongod@db01 ~]$ mongo --port 38021
sh1:PRIMARY> db.vast.count();
0
# shard2数据信息查看
[mongod@db01 ~]$ mongo --port 38024
sh2:PRIMARY> db.vast.count();
999999
2.2 配置应用基于分片策略-Hash
1. 激活数据库分片功能
[mongod@db01 ~]$ mongo --port 38017 admin
mongos> use admin
mongos> db.runCommand( { enablesharding : "liux" } )
2. 指定分盘键对集合分片
# 创建索引
mongo --port 38017 admin
mongos> use liux
mongos> db.vast.ensureIndex({id:"hashed"})
# 开启分片
mongos> use admin
mongos> sh.shardCollection( "liux.vast", { id: "hashed" } )
3. 集合分片模拟测试
mongos> use liux
mongos> for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
4. 分片结果测试验证
# shard1数据信息查看
[mongod@db01 ~]$ mongo --port 38021
sh1:PRIMARY> use liux
sh1:PRIMARY> db.vast.count();
50393
# shard2数据信息查看
[mongod@db01 ~]$ mongo --port 38024
sh2:PRIMARY> use liux
sh2:PRIMARY> db.vast.count();
49606
3.MongoDB分布式架构管理
3.1 分片集群的查询
[mongod@db01 ~]$ mongo --port 38017
mongos> use admin
# 判断是否Shard集群(是否是分片集群)
mongos> db.runCommand({ isdbgrid : 1})
{
"isdbgrid" : 1,
"hostname" : "master",
"ok" : 1,
}
# 列出所有分片信息
mongos> db.runCommand({ listshards : 1})
# 列出开启分片的数据库
mongos> use config
#-- 列出所有数据库分片情况
mongos> db.databases.find( { "partitioned": true } )
{ "_id" : "test", "primary" : "shard2", "partitioned" : true, "version" : { "uuid" : UUID("afdfe8f1-1c56-440d-806f-f97ae4129f7e"), "lastMod" : 1 } }
mongos> db.databases.find()
{ "_id" : "test", "primary" : "shard2", "partitioned" : true, "version" : { "uuid" : UUID("afdfe8f1-1c56-440d-806f-f97ae4129f7e"), "lastMod" : 1 } }
# 查看分片的片键
mongos> db.collections.find().pretty()
# 查看分片的详细信息
mongos> db.printShardingStatus()
mongos> sh.status()
3.2 分片集群的查询管理
# 确认blance是否在工作
mongos> sh.getBalancerState()
# 删除shard2节点(谨慎)
mongos> db.runCommand( { removeShard: "shard2" } )
六、总结
1.核心价值与优势总结:
- 灵活的数据模型:
- 文档型数据库,支持BSON格式,数据结构灵活
- 无需预定义表结构,适应快速变化的业务需求
- 高性能与高可用:
- 内存映射存储引擎,读写性能优异
- 原生复制集实现自动故障转移和数据冗余
- 支持多种特殊节点(Arbiter、Hidden、Delay)满足不同场景需求
- 强大的扩展能力:
- 分片集群实现水平扩展,支持海量数据存储
- 多种分片策略(Range、Hash)满足不同查询模式
- 配置服务器、路由节点、分片节点分离的架构设计
- 完善的安全机制:
- 基于角色的访问控制(RBAC)
- 密钥文件认证、TLS/SSL加密
- 网络绑定和IP白名单
2.架构选择建议:
- 单节点部署:开发和测试环境,数据量小
- 复制集架构:生产环境,需要高可用和读写分离
- 分片集群架构:超大规模数据,需要水平扩展
3.最佳实践要点:
- 部署规划:
- 硬件配置合理,禁用大页内存
- 目录结构清晰,权限设置正确
- 配置文件标准化,便于维护
- 高可用设计:
- 复制集至少3个节点(1主2从)
- 跨机房部署考虑网络延迟
- 定期测试故障切换流程
- 分片策略选择:
- Range分片:适合范围查询,数据分布可能不均匀
- Hash分片:数据均匀分布,适合等值查询
- 分片键选择:常用查询字段,基数高,值分布均匀
- 监控与维护:
- 监控复制集状态和延迟
- 定期检查分片平衡状态
- 备份策略和恢复测试
4.总结:
本文档系统地介绍了MongoDB从基础概念到高级架构的完整知识体系,通过实际操作示例和详细配置说明,使读者能够:
- 理解MongoDB的核心特性和适用场景
- 掌握MongoDB的安装部署和基础管理操作
- 搭建和维护高可用的复制集架构
- 设计和实施分布式分片集群
- 根据业务需求选择合适的数据模型和架构方案
MongoDB作为现代应用开发中重要的NoSQL数据库,掌握其原理和应用对于构建高性能、可扩展的数据存储系统具有重要意义。本文档为读者提供了全面的学习和实践指南,帮助在实际工作中更好地应用MongoDB解决数据存储和管理问题。
更多推荐


所有评论(0)