什么是MongoDB
MongoDB是一个开源的,基于分布式的,面向文档存储的非关系型数据库,虽然MongoDB是属于非关系型数据库,但他是非关系型数据库中功能最丰富的,最像关系型数据的。
MongoDB由C++编写,可以运行在Windows,unix,OSX,Solaris系统上,支持32位和64位应用,提供多种编程语言的驱动程序
高性能,易部署,易使用,村塾数据非常方便
为什么要选择MongoDB
- 面向文档
- 模式自由
- 高可用
- 水平拓展
- 支持丰富
如何实现MongoDB
一般的MongoDB是搭配集群实现高可用的前提下完成的部署
MongoDB搭建集群的方式主要有三种
- 副本集(Replica set)
副本集没有主从模式的限制,部署在同一个副本集的上面的每一个服务会自动票选出主节点和从节点,主节点可以进行正常的读写,从节点只能完成读的操作 - 分片(sharding)
分片可以把数据合理的分配到每一片上,把数据分散开,存储压力分不到各个服务器中 - 主从模式(master-slaver)
指定一个主服务器负责读写,从服务器负责读
实际生产环境中通常使用副本集加分片结合:每个分片上部署一个副本集
下载地址:https://www.mongodb.com/try/download/community
搭建MongoDB集群(副本集+分片)
服务器 | 虚拟机1 | 虚拟机2 | 虚拟机3 |
组件1 | mongos | mongos | mongos |
组件2 | config server | config server | config server |
组件3 | shard server1(主) | shard server1(从) | shard server1(仲裁) |
组件4 | shard server2(仲裁) | shard server2(主) | shard server2(从) |
组件5 | shard server3(从) | shard server3(仲裁) | shard server3(主) |
端口分配
(本次搭建使用一台虚拟机,开启9个MongoDB,15个端口搭建集群)
副本集1 | 副本集2 | 副本集3 |
mongos1———20001 | mongos———20002 | mongos——20003 |
config——21001 | config——21002 | config——21003 |
shard1(主)——27011 | shard2(主)——27021 | shard3(主)——27031 |
shard1(从)——27012 | shard2(从)——27022 | shard3(从)——27032 |
shard1(仲裁)——27013 | shard2(仲裁)——27023 | shard3(仲裁)——27033 |
安装MongoDB
下载安装包,并解压:下载地址https://www.mongodb.com/try/download/community
本次使用的版本是5.0.3
解压文件放到 /usr/local/mongodb/mongodb-5.0.3 目录下
#解压,更改文件名为mongodb-5.0.3
tar -zxvf mongodb-linux-x86_64-rhel70-5.0.3.tgz
配置环境变量
#进入编辑环境变量
vim /etc/profile
#配置MongoDB路径
export MONGODB_HOME=/usr/local/mongodb/mongodb-5.0.3
export PATH=$MONGODB_HOME/bin:$PATH
#使配置立即生效
source /etc/profile
#验证配置是否正确
mongod -v
创建数据存放文件夹
在解压的文件夹下,创建server1,server2,server3三个文件夹,分别对应模拟三台虚拟机
#进入文件夹
cd /usr/local/mongodb/mongodb-5.0.3
#创建文件夹
mkdir server1
mkdir server2
mkdir server3
在每一个server1文件夹下创建一个data文件夹存放数据,在data文件夹中创建conf、config、mongos、shard1、shard2、shard3六个文件夹,在除了conf文件中分别创建log和data文件夹(mongos只是负责路由,所以可以只创建log文件夹)
(server1,server2,server3都需要创建,这里展示server1的创建,server2和server3同理)
#进入文件夹
cd /usr/local/mongodb/mongodb-5.0.3/server1
#创建data文件夹
mkdir data
#进入data文件夹
cd data
#创建数据文件夹
mkdir conf
mkdir config
mkdir config/data
mkdir config/log
mkdir mongos
mkdir mongos/log
mkdir shard1
mkdir shard1/data
mkdir shard1/log
mkdir shard2
mkdir shard2/data
mkdir shard2/log
mkdir shard3
mkdir shard3/data
mkdir shard3/log
配置服务器
(3.4版本之后要求配置服务器也需要创建副本集)
在刚刚创建的conf文件夹中创建config.conf文件
(server1,server2,server3都需要创建,这里展示server1的创建,server2和server3同理)
注:配置服务器如果在一个集群上,副本集名称 replSet 的名称要一致
#进入conf文件夹
cd /usr/local/mongodb/mongodb-5.0.3/server1/data/conf
#创建config.conf并编辑
vim config.conf
#pid文件存放地址
pidfilepath = /usr/local/mongodb/mongodb-5.0.3/server1/data/config/log/configsrv.pid
#数据存放地址
dbpath = /usr/local/mongodb/mongodb-5.0.3/server1/data/config/data
#日志存放地址
logpath = /usr/local/mongodb/mongodb-5.0.3/server1/data/config/log/congigsrv.log
#已追加的形式添加日志
logappend = true
#绑定ip地址
bind_ip = 0.0.0.0
#绑定端口号
port = 21001
#启用守护线程的方式启动
fork = true
#declare this is a config db of a cluster;
configsvr = true
#副本集名称
replSet=configs
#设置最大连接数
maxConns=20000
之后分别启动三个config.conf文件
(这里以启动server1为例,server2,server3同理)
mongod -f /usr/local/mongodb/mongodb-5.0.3/server1/data/conf/config.conf
之后登录任意一台配置服务器,初始化副本集
注:_id : “configs” 对应的是配置文件中的replSet的值
members中的host分别是三个配置服务器的ip和端口
#登录
mongo --port 21001
#输入config变量
config = {
_id : "configs",
members : [
{_id : 0 , host : "你的服务IP地址:21001"},
{_id : 1 , host : "你的服务IP地址:21002"},
{_id : 2 , host : "你的服务IP地址:21003"}
]
}
#初始化副本集
rs.initiate(config)
初始化之后显示参数中包含 { ok :1 }为初始化成功
shard副本集
在conf文件夹中创建副本集的配置文件
(这里以server1为例,server2,server3同理)
#进入conf文件夹
cd /usr/local/mongodb/mongodb-5.0.3/server1/data/conf
#新建配置文件并编辑
vim shard1.conf
#pid文件存储目录
pidfilepath = /usr/local/mongodb/mongodb-5.0.3/server1/data/shard1/log/shard1.pid
#数据存储目录
dbpath = /usr/local/mongodb/mongodb-5.0.3/server1/data/shard1/data
#日志存储目录
logpath = /usr/local/mongodb/mongodb-5.0.3/server1/data/shard1/log/shard1.log
#日志以追加的形式添加
logappend = true
#绑定ip
bind_ip = 0.0.0.0
#绑定端口号
port = 27011
#使用守护线程的方式启动
fork = true
#启用集群部署
directoryperdb = true
#副本集名称
replSet=shard1
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
之后启动三个shard1.conf
(这里是server1 的 shard1 的启动,server2,server3同理)
mongod -f /usr/local/mongodb/mongodb-5.0.3/server1/data/conf/shard1.conf
登录任意一个shard1(非仲裁节点),初始化副本集
#登录
mongo --port 27011
#使用admin数据库
use admin
#定义副本集
#输入config变量
config = {
_id : "shard1",
members : [
{_id : 0 , host : "你的服务IP地址:27011"},
{_id : 1 , host : "你的服务IP地址:27012"},
{_id : 2 , host : "你的服务IP地址:27013", arbiterOnly : true}
]
}
#初始化副本集配置
rs.initiate(config)
输出参数中带有 ok:1 即为成功
根据上面的操作,对应 shard2 完成其他两个副本集的配置
mongos路由服务器
在conf文件夹中添加配置文件
(这里以server1为例,server2,server3同理)
#进入conf文件夹
cd /usr/local/mongodb/mongodb-5.0.3/server1/data/conf
#新建mongos.conf文件并编辑
vim mongos.conf
#pid文件存储位置
pidfilepath = /usr/local/mongodb/mongodb-5.0.3/server1/data/mongos/log/mongos.pid
#日志文件存储位置
logpath = /usr/local/mongodb/mongodb-5.0.3/server1/data/mongos/log/mongos.log
#日志以追加的形式添加
logappend = true
#绑定的ip
bind_ip = 0.0.0.0
#绑定的端口
port = 20001
#以守护线程的方式启动
fork = true
#监听的配置服务器,只能有1个或者3个 configs为配置服务器的副本集名字
configdb = configs/你的服务IP地址:21001,你的服务IP地址:21002,你的服务IP地址:21003
#设置最大连接数
maxConns=20000
启动三个路由服务器mongos.conf
(这里以server1为例,server2,server3同理)
mongos -f /usr/local/mongodb/mongodb-5.0.3/server1/data/conf/mongos.conf
配置启动分片
应用要连接到mongos路由服务器才能使用分片机制
登录任意一台路由服务器mongos
#登录mongos服务器
mongo --port 20001
#使用admin数据库
use amdin
#串联路由服务器与分配副本集
sh.addShard("shard1/你的服务IP地址:27011,你的服务IP地址:27012,你的服务IP地址:27013")
sh.addShard("shard2/你的服务IP地址:27021,你的服务IP地址:27022,你的服务IP地址:27023")
sh.addShard("shard3/你的服务IP地址:27031,你的服务IP地址:27032,你的服务IP地址:27033")
#查看集群状态(仲裁类型的mongodb不会显示到状态中)
sh.status()
测试
默认分片大小chunkSize为64M,方便分片测试,这里可以改为1M
#在路由服务器中进行即可
mongo --port 20001
use config
db.settings.save({_id:"chunksize",value:1})
#查看结果
db.settings.find()
指定testdb分片生效
#指定testdb分片生效
db.runCommand({enablesharding:"testdb"})
#指定数据库需要分片的集合和分片键
db.runCommand({shardcollection:"testdb.user",key:{uid:1}})
use testdb
数据库添加数据
打入200000条数据,查看mongodb集群分片状态
(这一步会比较慢)
for(i=1;i<=200000;i++)db.user.insert({uid:i,name:'lllllll',age:21})
登录进入mongos路由服务器
#查看状态
sh.status()
其中chunks是分片的状态
chunks:
shark1
shark2
shark3
也可以查看详细信息
db.user.stats()