Mongodb

来源:互联网 发布:php在windows和linux 编辑:程序博客网 时间:2024/06/01 07:40


(一) Mongodb 安装 (有两个大版本,一个是2.X,一个是3.X)介绍

参考官方文档:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/
如果第一手质料还是看不懂,请在Google上搜索第二手资料

  • RPM包安装(记住 2.6 和 3.4 分别演示,对于大家来说,重点学习3.4版本,因为3.2以后版本提供了多个易用的API接口,让我们管理MongoDB更为方便)
1:创建yum仓库配置文件,编辑 /etc/yum.repos.d/mongodb.repo文件,添加
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1
2:安装mongodb-org,且mongodb-org-server、mongodb-org-mongos、mongodb-org-shell、mongodb-org-tools将一并被安装
yum install -y mongodb-org
  • 修改主配置文件/etc/mongod.conf
bind_ip = 0.0.0.0 让所有的用户都可以连接服务端, 生成环境里请自行按需修改
dbpath = /data/mongo 重新指定数据存储的路径
httpinterface = true 打开基于web接口来监控mongodb的工作特性,且监听于28017
rest = true 支持restful编程接口
port = 27017 指定mongodb-server监听的端口
  • 创建数据目录,且修改权限
mkdir -pv /data/mongo
chown -R mongod.mongod /data/mongo
  • 启动mongodb,且查看数据目录是否存在数据
systemctl start mongod.service
ll /data/mongo/
  • 客户端连接到服务端
(一):使用http接口连接服务端,查看mongodb的信息, http接口是28017
http://192.168.23.9:28017
(二):查看客户端连接到服务端的帮助
[root@mongodb1 data]# mongo --help
MongoDB shell version: 2.6.12
usage: mongo [options] [db address] [file names (ending in .js)]
(三):通过客户端连接到服务端
mongo --host 192.168.23.9 连接到服务端,默认是连接192.168.23.9:27017/testtest为数据库名
show dbs; 查看数据库
  • mongodb的命令介绍
db.help() 查看库级别的命令
db.stats() 查看数据库状态
db.version() 查看数据库版本
db.serverStatus() 查看数据库服务器状态
db.mycoll.help() 查看表级别的命令
db.getCollectionNames 显示当前库中所有的表的列表
sh.help() 关于sharding的操作
rs.help() 集合赋值命令
help admin 管理命令
help connect 连接操作语法
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs 显示数据库名称
show collections 显示表名称
show users 查看已有用户
show profile 显示profile信息,显示性能评估工具
show logs 显示日志名信息
show log [name] 显示指定的日志名的信息
use <db_name> 进入某库,设定某库为当前库
db.foo.find()
db.foo.find( { a : 1 } )
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
  • DDL, DML, DCL (在mongodb中叫做CRUD操作)
db.students.insert({name:"dage",age:20}) 插入一条数据,默认会创建students
show collections 显示当前的表
db.students.stats() 显示students表的数据信息
db.students.find() 查询插入的各个字段
db.students.count() 查看students表中有多少个document
  • Collection的简单查询过滤操作
find()的高级用法:比较操作:
(一) db.students.find({age: {$gt: 30}}) age大于30
{ "_id" : ObjectId("597b49b4072d632a342867cc"), "name" : "data", "age" : 34 }
(二)db.students.find({age: {$gte: 30}}) age大于等于30
(三)db.students.find({age: {$lt: 30}}) age小于30
(四)db.students.find({age: {$lte: 30}}) age小于等于30
(五)db.students.find({age: {$in: [20, 30]}}) age在[20, 30]的document
(六)db.students.find({age: {$nin: [20, 30]}}) age不在[20, 30]的document
  • Collection的复杂查询过滤操作
find()的高级用法:组合条件:逻辑运算
(一)db.students.find({$or: [{name: {$eq: "yhy"}}, {age: {$nin: [40,50]}}]}) 或运算
(二)$and:与运算
(三)$not:非运算
(四)$nor:取反运算
find()的高级用法:元素查询: 根据document中是否存在指定的字段进行的查询
(一)db.students.find({gender: {$exists: true}}) 查询存在gender字段的document
(二)$mod:取摸
(三)$type:返回指定字段的值类型为指定类型的document
MongoDB支持的数据类型有:Double, String, Object, Array, Binary data, Undefined, Boolean, Date, Null
  • Collection的跟新操作(update( )方法详解:插入和修改字段的值)
update()的高级用法:$set 更新,或插入字段的值, $unset 删除指定字段 ,$rename 修改字段名
(一)db.students.update({name: "yhy"}, {$set: {age: 44}})
将name为yhy的这个document的age字段的值改为44
db.students.update({name: "yhy"}, {$set: {age: 50}})
将name为yhy的这个document的age字段的值改为50
(二)db.students.update({name: "yhy"}, {$unset: {age: 50}})
删除name字段为yhy的document的age为50的字段
(三)db.students.update({name: "yhy"}, {$rename: {age: "Age"}})
修改name字段为yhy的document的age字段名为Age字段名
(四)db.students.update({name: "yhy"}, {$inc: {course: "Python"}})
给name字段为yhy的document增加一个字段course且值为Python
  • Collection的删除操作(remove( ),drop( ), dropDatabase( )方法详解)
# 删除字段
db.students.remove({"name": "yhy"})
# 删除表
db.students.drop()
# 删除当前数据库
db.dropDatabase()

(二) Mongodb index 介绍

1:MongoDB中的索引与MySQL中的索引有类似的功能,将表中的字段添加索引,索引会将字段做排序,依次索引能够大大提高MongoDB的查询能力,但是会削弱一部分的i/o能力
2:在MySQL的学习过程中,我们知道,当用户去查询一行数据的时候,都需要指定条件过滤,那么在条件过滤时,最好能够使用字段上建立的索引,能够帮助我们快速匹配到行,拿到需要的数据。如果使用到了索引,那么MySQL先会去查找索引,然后通过索引定位到数据表中的数据,最后返回给调用者, MySQL的索引类型有如下几类:B Tree索引、hash索引、空间索引、全文索引
3:mongoDB索引类型有:单键索引、组合索引、多键索引、空间索引、文本索引、hash索引

  • 索引操作介绍
db.student.ensureIndex({name: 1})
给name字段创建索引, 1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
实例
db.student.getIndexes()
查看索引
db.student.find({"name": "yhy"}).explain()
查看是否使用到了索引(由于MongoDB调优)
db.student.dropIndex("name_1")
删除索引
db.students.ensureIndex({name: 1}, {unique: true})
给name字段创建一个唯一键索引,那么再给students表增加一条行document,且name与之前存在的document的name值相同,那么就会报错, 如:增加一条document
db.students.insert({name: "yhy"})
报错的信息如下:
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.students.$name_1 dup key: { : \"yhy\" }"
}
})

(四) Mongodb 授权认证 介绍

mongodb存储所有的用户信息在admin 数据库的集合system.users中,保存用户名、密码和数据库信息。mongodb默认不启用授权认证,只要能连接到该服务器,就可连接到mongod。若要启用安全认证,需要更改配置文件参数auth
官方文档:https://docs.mongodb.com/manual/tutorial/enable-authentication/

  • db.createUser( )函数介绍
1:创建一个root用户,角色为userAdminAnyDatabase,因此root用户对数据库具有管理权限,但是不具备操作权限
db.createUser({user:"root",pwd:"123456", roles: [{ role: "userAdminAnyDatabase", db: "admin" }]});
2:createUser()方法说明
user:定义用户名
pwd:设置密码
roles:指定用户的角色,可以用一个空数组给新用户设定空角色; 在roles字段,可以指定内置角色和用户定义的角色。
db:指定用户对哪个数据库具有管理员权限
3:角色种类说明
Built-In Roles(内置角色):
①. 数据库用户角色:read、readWrite;
②. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
③. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
④. 备份恢复角色:backup、restore
⑤. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
⑥. 超级用户角色:root
// 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
⑦. 内部角色:__system
4:角色对应的意义说明
Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限
5:查看授权表
db.system.users.find();
6:此时退出MongoDB,且编辑配置文件/etc/mongod.conf, 添加
auth=true(针对于2.6版本)
security:(针对于3.4版本)
authorization: enabled
7:可以在连接数据库的时候认证,也可以在登入时候认证,这里使用登入之后认证的方式
show dbs; (会报错,因为没有管理授权)
db.auth("root", "123456") 授权之后再查看数据库就没有问题了
8:此时登入使用的是root用户,角色是管理角色,但是不具备对数据库的操作权限
use test;
show collections; (会报错,因为没有操作权限)
9:再次创建一个用户: test,让其对test具有读写操作, 且切换用户为test
db.createUser({user:"test",pwd:"test", roles: [{ role: "readWrite", db: "test" }]});
db.auth("test", "test")
10:再次查看test库的表,发现可以查看了
show collections;
11:其实,如果需要创建一个用户具有管理权限且同时具有操作权限,那么这个用户的角色必须是root
db.createUser({user:"yhy",pwd:"123456", roles: [{ role: "root", db: "admn" }]});

(五) mongod 的常用选项 介绍

mongod是服务器程序,mongo是客户端程序,不要搞混乱了,我们不仅可以使用systemctl来启动mongoDB, 还可以直接使用mongod来启动
在启动mongod的时候,可以指定一系列的选项,那么mongodb中,提供了一个配置文件:/etc/mongod.conf ,那么可以将这些选项都写在这个配置文件里,使得启动mongod时,mongodb会先读取这个配置文件中的选项,之后在读取命令行的选项来启动mongodb
详细配置请参考博文:http://blog.csdn.net/sun491922556/article/details/74973191

①:在配置mongodb2.6的时候,常用的一些选项有
fork = {true=false}:指定mongod是否运行在后台
bind_ip = IP地址:指定监听的地址,如果不指定,默认是监听本地的所有IP地址
port = 监听的端口:指定监听的端口
maxConns = 并发连接数:指定支持的最大并发连接数
logappend = {true=false}:指定是否支持日志滚动
auth = :指定是否启用认证功能
②:在配置mongodb3.4的时候,常用的选项有(如果想使用mongodb的web管理页面,在/usr/lib/systemd/system/mongod.service文件中,修改:Environment="OPTIONS=-f /etc/mongod.conf --rest")(/usr/lib/systemd/system/mongod.service这个unit file可以指定很多环境配置选项)
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
# Where and how to store data.
storage:
dbPath: /data/mongodb
journal:
enabled: true
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
net:
port: 27017
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
# 启用认证
security:
authorization: enabled

(六) Mongodb compass 介绍

参考官方文档:https://docs.mongodb.com/compass/current/install/#install-on-red-hat-enterprise-linux-rhel
Mongodb compass 提供图形化管理界面管理MongoDB

  • 安装 Mongodb compass
1:下载安装包:
wget https://downloads.mongodb.com/compass/mongodb-compass-1.6.0.x86_64.rpm;
2:安装
yum install mongodb-compass-1.6.0.x86_64.rpm;
3:启动
DEBUG=* mongodb-compass;
  • 效果如下(这个相当于MySQL的GUI工具一样,自己去点一点就知道了)

Alt text

  • 另外还有个叫做 RockMongo 是一个PHP写的MongoDB管理工具,类似于phpMyAdmin一样,可以通过浏览器连接MongoDB

(七) Mongodb 复制架构 介绍

以上所有的内容都是 MongoDB standalone方式 运行,下面我们将重点讲解MongoDB的复制,也就是副本集的概念(MongoDB的集群架构)
MongoDB复制是将数据同步在多个服务器的过程,复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性, 复制还允许您从硬件故障和服务中断中恢复数据

Alt text

以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性

  • 复制概念说明、副本集概念说明(如果实在是不理解什么是副本集,就认为一个副本集是一个集群)
1:在mongodb的集群中,一般会部署多个节点,且有多个节点有相同的数据。
2:主节点可以进行读写操作,而从节点一般只能够进行读操作
3:副本集就是服务所有的mongodb实例的同一个数据集(也就是说副本集定义了一个集群,一个已经运行的集群中如果添加了一个新的节点,那么必须指定这个新的节点加入到哪个副本集中。一个副本集就定义了一个集群,一个副本集可以最多支持12个成员,但是只有7个成员可以参与投票)
4:对应MySQL而言:从节点在主节点复制数据的方式为主节点将数据操作保存在二进制日志中,而从节点就是复制主节点的二进制日志,在本地再执行一次,那么这就实现了与主节点的数据一致。而mongodb是主节点将数据操作保存在操作日志(oplog)中,从节点复制操作日志(oplog),在本地再执行一次实现数据集一致
5:从节点每隔一段时间会探测一次主节点的心跳信息,如果在一段时间中无法获得主节点的心跳信息,那么其余的从节点会重新进行一次投票选举操作,谁的优先级高就会成为下一个主节点。
6:mongodb节点集群至少需要三个节点,一个主节点,两个从节点
7:复制中的四种特殊的从节点分类
a:0优先级的节点:冷备节点,不会被选举成为主节点,但是可以参与选举过程
b:被隐藏的从节点:不想让客户端访问数据的节点,必须为0优先级的节点,不会显示在mongodb集群的信息中
c:延迟复制的从节点:必须为0优先级的节点,且复制时间落后于主节点一个固定时间,可以参与选举过程
d:arbiter:没有数据
8:oplog:记录数据改变的操作日志,用于数据同步复制,大小固定的文件,存储在local数据库中,集群中每一个节点都有oplog。但是只有当其成为主节点的时候,才会将其数据改变的操作记录到oplog之中
同步的步骤分为:
初始同步
同步之后追赶主节点
切分块迁移(切片)
local库中存放了副本集的所有的元数据和oplog,用于存储oplog的一个叫oplog.rs的collection表,oplog.rs的大小默认与文件系统有关,但是可以自定义
  • 基于MongoDB2.6版本配置MongoDB主从复制集群架构实战(请大家自行完成3.4版本的MongoDB主从复制集群架构)
1:集群环境说明:mongodb1:192.168.43.10、mongodb2:192.168.43.11、mongodb3:192.168.43.12。且基于主机名相互通信/etc/hosts文件(为了集群信息同步不出现问题,先关闭认证功能anth)
2:编辑mongodb1的/etc/mongod.conf文件,注释auth指令,添加如下内容
# 指定副本集的名称
replSet=uplooking
# 指定预拷贝的索引,这里只拷贝id那个系统自动生成的索引
replIndexPrefetch=_id_only
noauth=true
3:将mongodb1的配置文件拷贝到mongodb2、mongodb3
scp /etc/mongod.conf 192.168.43.11:/etc/
scp /etc/mongod.conf 192.168.43.12:/etc/
3:启动mongodb1、mongodb2、mongodb3
4:登入mongodb1的shell接口
> rs.status(); (查看集群中的节点状态)
> rs.initiate();(初始化副本集)
> rs.status();(再次查看集群中的节点状态)
uplooking:PRIMARY> (此时的提示符已经变了)
5:当初始化了主节点以后,需要添加其他的从节点到mongodb集群中来
uplooking:PRIMARY> rs.add("192.168.43.11")
uplooking:PRIMARY> rs.add("192.168.43.12")
6:添加了其他节点以后,就可以查看配置信息和副本集的状态信息
uplooking:PRIMARY> rs.conf()
{
"_id" : "uplooking",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "mongodb1:27017"
},
{
"_id" : 1,
"host" : "192.168.43.11:27017"
},
{
"_id" : 2,
"host" : "192.168.43.12:27017"
}
]
}
7:再次查看状态副本集的状态信息
uplooking:PRIMARY> rs.status()
{
"set" : "uplooking",
"date" : ISODate("2017-10-29T16:05:55Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "mongodb1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 914,
"optime" : Timestamp(1509292923, 1),
"optimeDate" : ISODate("2017-10-29T16:02:03Z"),
"electionTime" : Timestamp(1509292619, 1),
"electionDate" : ISODate("2017-10-29T15:56:59Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.43.11:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 237,
"optime" : Timestamp(1509292923, 1),
"optimeDate" : ISODate("2017-10-29T16:02:03Z"),
"lastHeartbeat" : ISODate("2017-10-29T16:05:54Z"),
"lastHeartbeatRecv" : ISODate("2017-10-29T16:05:54Z"),
"pingMs" : 0,
"syncingTo" : "mongodb1:27017"
},
{
"_id" : 2,
"name" : "192.168.43.12:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 232,
"optime" : Timestamp(1509292923, 1),
"optimeDate" : ISODate("2017-10-29T16:02:03Z"),
"lastHeartbeat" : ISODate("2017-10-29T16:05:55Z"),
"lastHeartbeatRecv" : ISODate("2017-10-29T16:05:55Z"),
"pingMs" : 0,
"syncingTo" : "mongodb1:27017"
}
],
"ok" : 1
}
8:此时从节点可以在shell接口查看到在主节点复制过来的数据库和表,但是不能查询表的内容,因此需要通过命令让从节点变为可用节点,在查询就可以了
uplooking:SECONDARY> rs.slaveOk()
9:主节点也可以通过命令变为从节点, 此时其他的节点通过投票将会变为主节点
uplooking:SECONDARY> rs.stepDown()
10:在新的主节点(mongodb2)中可以设置从节点的优先级让从节点变为主节点,让第一个从节点优先级为10,那么第一个从节点就会变为主节点
uplooking:PRIMARY> config=rs.conf() # 先使用一个config临时变量保存rs.conf()的值,也就是当前的副本集配置
uplooking:PRIMARY> config.members[0].priority=10 # 让第一个节点,也即是mongodb1的优先级为10
uplooking:PRIMARY> rs.reconfig(config) # 让副本集获得新的配置,此时,mongodb1将会成为主节点
11:在主节点中,从副本集中移除一个节点,
rs.conf() # 先查看需要删除的host
rs.remove("192.168.43.12:27017")
12:也可以将一个从节点变为arbiter仲裁节点,这里将mongodb3变为arbiter节点,必须先让mongodb3下线,然后删除数据目录,在重启,再设置为arbiter仲裁节点
rs.addArb("192.168.43.12")

(八) Mongodb 分片操作 介绍

为什么需要分片操作?由于数据量太大,使得CPU,内存,磁盘I/O等压力过大。当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。

  • 当单个MongoDB节点的数据量过大的时候,我们通常考虑将数据切分为多个shard,也就是切分为多片。

Alt text

Alt text

  • (一)数据分片之后,整个集群中的MongoDB节点就分为了三类,一类是Router节点,实现前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。一类是Config节点,存储了整个 元数据ClusterMetadata,其中包括 chunk信息,明确知道客户端请求的数据在哪个shard节点上。第三类,shard节点,存储真实的数据,将原有的数据集分片之后平均存储在每一个shard节点之上。

  • (二)MongoDB的分片机制上建立在副本集概念之上的概念,因为这里每一个shard节点都将组成一个副本集,使每一个shard节点的数据具有高可用性。这里需要补充一个chunk的概念,大数据集首先是切分为多个chunk,之后再将chunk发布到各个shard节点中,就是每一个shard节点的数据都是一个一个的chunk组成的。那么chunk又是基于什么标准切分出来的呢?是这样的,一般在切分chunk的时候,会指定索引,比如age,如果在一个collection中给age这个字段创建了一个索引,那么切分chunk的时候,就以age这个索引来切分,使得1~60岁这个年龄阶段的数据能够根据不同的区间范围,切割为多个chunk,例如1~15岁为一个chunk,15~20岁一个chunk,21~30岁一个chunk,31~60岁一个chunk,每一个chunk的数量大小均等,因此整个collection就被切割成为了3个chunk,chunk信息将会保存至config节点中,而chunk数据将会保存在每一个shard节点中。

  • (三)shard分片的衡量的标准,也就是根据哪个索引(切片键)进行切片(让经常写的数据尽量离散分散到各个shard中,让经常读的数据尽量集中到一个shard中)
1:基于范围range做分片
例如:以年龄、时间等切片
2:基于离散列表切片
例如:以区域、地名等数据切片
3:基于hash值进行随机切片
例如:以热点人物(例如:鹿晗和关晓彤)做hash之后切片
  • 生产环境中MongoDB集群架构如下

Alt text

(九) Mongodb 分片操作实战

由于生产环境中一般使用zoomkeeper做config节点的仲裁节点,zoomkeeper会在三个config节点中挑选出一台作为主config节点。且mongos节点一般是两个节点,必须做高可用,可以用keepalived实现(任何具有负载均衡能力的服务器节点都可以使用keepalived做高可用)

  • 试验环境介绍

Alt text

  • 实际操作过程
1:准备四个节点mongodb1(mongos)、mongodb2(config)、mongodb3(shard1)、mongodb4(shard2)且保证可以通过主机名访问,且时间同步
2:配置mongodb2(config)节点,使得mongodb2为config节点,编辑配置文件/etc/mongod.conf
添加:configsvr = true
同时注释:#replSet=uplooking #replIndexPrefetch=_id_only #port=27017 这3个指令
(因为副本集与config节点不能同时工作)
4:启动config server,此时默认config server监听在27019端口
systemctl start mongod.service
5: 在mongodb1上操纵:mongodb1作为路由,使用mongos连接config server,先清空配置文件,再添加如下信息
logpath=/var/log/mongodb/mongod.log # 指明日志路径
pidfilepath=/var/run/mongodb/mongod.pid # 指明pid路径
logappend=true # 指明日志累加
fork=true # 指明运行于守护进程
port=27017 # 指明端口
configdb=192.168.43.11:27019 # 指明config server 的地址在哪里
6:指定配置文件,启动mongos,也可以使用systemctl启动,但是需要修改下启动脚本/etc/rc.d/init.d/mongod
mongos -f /etc/mongod.conf
7:将mongodb3和mongodb4配置文件中关于副本集的指令注释,然后直接启动
systemctl start mongod
8:mongodb3、mongodb4启动之后,在mongodb1上,通过mongo登入到mongos,将mongodb3、mongodb4作为shard添加到mongos的路由策略中
9:创建支持shard机制的数据库
sh.enableSharding("uplookingdb")
mongos> sh.status();
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 4,
"minCompatibleVersion" : 4,
"currentVersion" : 5,
"clusterId" : ObjectId("59f6caf5c93e5ff2a637a0cd")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.43.13:27017" }
{ "_id" : "shard0001", "host" : "192.168.43.12:27017" }
databases: # 这里会显示支持shard的数据库,分片collection放置在各个shard,而没有分片的collection放置在主shard中
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
{ "_id" : "uplookingdb", "partitioned" : true, "primary" : "shard0001" }
10:在对应支持shard机制的数据库上创建支持shard的collection,{"age": 1}指明索引为age,升序排序,这样shard集群的功能就已经启动了,之后就可以调用mongodb1这个接口写数据了,但是写入mongodb1的数据不会保存在mongodb1,因为mongodb1是一个router节点,所有的数据都会保存至shard节点上。
sh.shardCollection("uplookingdb.students", {"age": 1})
11:此时mongodb1节点上会有uplookingdb库 和 students表了
mongos> show dbs;
admin (empty)
config 0.016GB
uplookingdb 0.078GB
mongos> use uplookingdb
switched to db uplookingdb
mongos> show collections;
students
system.indexes
12:给students表创建添加数据(可以使用js的循环语法插入数据)
mongos> for (i=1; i<1000000; i++){
db.students.insert({"name": "yhy"+i, "age": i%100, "student_id": i, "skill": "ok"+i, "salary": "$"+i%10000})
}
13:复制mongodb1窗口,先查看一下students表有多少行数据了,在看看此时的shard分片的状态
mongos>db.students.find().count(); # 查看students表中有多少行数据了
237751
mongos> sh.status() # 再查看一下shard的状态信息
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 4,
"minCompatibleVersion" : 4,
"currentVersion" : 5,
"clusterId" : ObjectId("59f6caf5c93e5ff2a637a0cd")
}
shards: # 只是shard节点列表
{ "_id" : "shard0000", "host" : "192.168.43.13:27017" }
{ "_id" : "shard0001", "host" : "192.168.43.12:27017" }
databases: # 这是支持shard机制的库
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
{ "_id" : "uplookingdb", "partitioned" : true, "primary" : "shard0001" }
uplookingdb.students 这是支持shard机制的表
shard key: { "age" : 1 } # 用表上的哪个索引作为shard的键
chunks: # 这里是显示chunk的发布情况
shard0000 2 # 发布两个chunk
shard0001 3 # 发布三个chunk
{ "age" : { "$minKey" : 1 } } -->> { "age" : 1 } on : shard0000 Timestamp(2, 0)
{ "age" : 1 } -->> { "age" : 47 } on : shard0000 Timestamp(3, 0)
{ "age" : 47 } -->> { "age" : 72 } on : shard0001 Timestamp(3, 2)
{ "age" : 72 } -->> { "age" : 99 } on : shard0001 Timestamp(3, 3)
{ "age" : 99 } -->> { "age" : { "$maxKey" : 1 } } on : shard0001 Timestamp(2, 3)
14:过一段时间之后,等数据在mongodb1节点插入完毕,在mongodb3,mongodb4上就会发现一部分年龄的人在mongodb3,而另外一部分在mongodb4上
db.students.find();
15:再添加一个新的节点进来,在mongodb1上设置它为shard节点,此时你会发现chunk就会自动迁移,无需我们手动管理,但是chunk在shard节点中自动迁移会消耗大量的带宽以及带来I/O压力,因此,一般是现在mongodb1节点将
16:如果创建一个库,且添加一张表,且并没有将库和表添加到shard机制中来,那么
  • 对于每一个shard节点实现副本集赋值功能,以及多个config节点,同学们一定要完成(我出去调研的时候发现,MongoDB的应用场景再某种程度上不比MySQL弱)