本文档系统全面地介绍了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解决数据存储和管理问题。

Logo

更多推荐