1.MongoDB简介
MongoDB是分布式文件存储的数据库,为WEB应用提供可扩展高性能数据存储解决方案,是介于关系数据库和非关系数据库之间,是非关系数据库中功能最丰富,很像关系数据库。MongoDB在高负载的情况下,可以添加更多节点,可以保证服务器性能。MongoDB将数据存储为一个文档,数据结构由键值对组成。文档的数据结构有些类似JSON对象,字段值可以包含其他文档,数组及文档数组。
2.MongoDB特点
(1)MongoDB 是面向文档存储的数据库
(2)可以设置任何属性的索引,实现更快排序
(3) 如果负载增加,可以分布在计算机网络中的其它节点上,这就是所谓的分片。
(4) 使用JSON形式标记,可查询文档内嵌的对象和数组
(5)使用update()命令实现文档和数据替换
(6)Map/reduce用来对数据进行批量和聚合操作,Map 函数调用 emit(key,value)遍历集合中所有的记录,将 key 与 value 传给Reduce 函数进行处理。Map 函数和 Reduce 函数是使用 Javascript 编写的,并可以通过 db.runCommand 或 mapreduce命令来执行 MapReduce 操作。
(7)允许在服务端执行脚本,用Javascript 编写某个函数,直接在服务端执行,可以把函数定义存储在服务端,下次直接调用。
(8) 支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
3.安装MongoDB
(1) wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-4.2.8.tgz
先要去官网找到这个连接地址:
MongoDB官网地址:https://www.mongodb.com/try/download/community
如下图,先进行版本选型,然后点击Copy Link
(2) tar -zxvf mongodb-linux-x86_64-ubuntu1804-4.2.8.tgz
解压
(3) cd ./bin
进入到bin目录,然后就可以使用了。
如果报错了,使用如下方法:
报错./mongod: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory
解决办法:apt-get install curl
(4) 启动服务和检查服务是否运行
(5) ./mongod --version
查看版本
(6) 配置文件
vim mongodb.conf
(7) 启动配置文件对应的mongon服务,并用对应的命令查看服务
(8) 再启动./mongo服务,即可连接MongoDB
退出就使用exit
(9) 1. 再使用客户端工具Robo 3T去连接
输入服务器IP:172.16.204.129,使用默认端口去连接。就可以愉快的使用这个mongodb。
3.MongoDB解析
以下是一些关于MongoDB的专业术语解释
MongoDB可以建立多个数据库,默认数据库为"DB"(默认存储在data),每一个数据库都有自己的集合和权限,并存放在不同的文件夹中。
"show dbs"可以显示所有数据列表
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
>
执行 "db" 命令可以显示当前数据库对象或集合。
$ ./mongo
> db
test
>
use命令,可以连接到一个指定数据库
> use local
switched to db local
> db
local
>
数据库命名是要满足以下条件的UTF-8 字符串。
不能是空字符串
不能含有' '空格、.、$、/、\和\0 (空字符)。
应全部小写
最多64字节
有些特殊数据库名是要保留,可以直接访问这些特殊作用的数据库。
admin:这是"root"数据库,如果将一个用户添加到数据库,这个用户会自动继承所有数据库权限。有些特定的命令,只能从这个数据库运行,如列出所有数据库或关闭服务。
local:仅用来存储本地单台服务器集合,数据不会被复制
config:当 Mongo 用于分片设置时,config 数据库在内部使用,用于保存分片的相关信息。
文档(Document)
文档是一组键值(key-value)对(即 BSON)。MongoDB相同字段不需要相同数据类型,这与关系型数据库有很大区别,如:
{"site":"www.baidu.com", "name":"你好"}
列出了 RDBMS 与 MongoDB 对应的术语:
特定是:
(1)键值对是有序。
(2)值不仅可以是字符串,还可以是其他数据类型,甚至整个文档都可以。
(3)区分类型和大小写
(4)不能有重复键
(5)文档键是字符串,除少数情况,键可以是任意UTF-8字符。
集合
集合就是 MongoDB 文档,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。由于集合没有固定结构,则意味着可以使用不同格式和类型的数据。如可以使用不同数据结构的文档插入到集合。当第一个文档插入时,集合就会被创建。
{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
集合命名规则:
集合名不能是空字符串""。
集合名不能含有\0 字符(空字符),这个字符表示集合名的结尾。
集合名不能以"system."开头,这是为系统集合保留的前缀
用户创建的集合名字不能含有保留字符。不要出现$。
capped collections
Capped collections 就是固定大小的 collection。有很高的性能以及队列过期的特性(过期按照插入的顺序)。高性能自动维护对象的插入顺序。必须要显示创建capped collection,指定一个 collection 的大小,单位是字节,存储空间需要提前分配。Capped collections 可以按照文档的插入顺序保存到集合中,文档在磁盘上存放位置也是按照插入顺序来保存的,所以当我们更新 Capped collections 中文档的时候,更新后的文档不可以超过之前文档的大小,确保所有文档在磁盘的位置一直保持不变。Capped collection应该按照文档插入顺序确定插入位置,而不是索引,保证效率的提高。MongoDB 的操作日志文件 oplog.rs就是用Capped Collection 来实现的。需要注意指定存储大小包含了数据库的头信息。
db.createCollection("mycoll", {capped:true, size:100000})
使用 Capped Collection 不能删除一个文档,可以使用 drop() 方法删除 collection 所有的行。删除之后,你必须显式的重新创建这个 collection。
在 32bit 机器中,capped collection 最大存储为 1e9( 1X10的9次方)个字节。
元数据
数据库的信息是存储在集合中。它们使用了系统的命名空间:
dbname.system.*
在 MongoDB 数据库中名字空间 .system.* 是包含多种系统信息的特殊集合(Collection),如下:
在{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的 drop index 命令将自动更新相关信息)。{{system.users}}是可修改的。{{system.profile}}是可删除的。
下表为 MongoDB 中常用的几种数据类型。
下面说明几种重要数据类型:
ObjectId
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
0-3:时间戳
4-6:机器识别码
7-8:PID
9-11:随机数
MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个ObjectId 对象,由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:
> var newObject = ObjectId()> newObject.getTimestamp()ISODate("2020-07-10T04:42:12Z")newObject.str5d80642415db2f66a53467a4
时间戳
BSON 有一个特殊的时间戳类型用于 MongoDB 内部使用,与普通的 日期 类型不相关。时间戳值是一个 64 位的值。BSON时间戳主要用于MongoDB内部,在大多数情况,可以使用BSON日期类型。
前 32 位是一个 time_t 值。
后 32 位是在某秒中操作的一个递增的序数。
日期
日期类型是有符号的, 负数表示1970 年之前的日期。
> var date1 = new Date() //格林尼治时间> date1ISODate("2020-07-13T04:47:39.919Z")> typeof mydate1object> var mydate2 = ISODate() //格林尼治时间> mydate2ISODate("2019-07-13T04:48:21.854Z")> typeof mydate2object
如果想要返回日期类型,则使用js中的Date类型方法,则返回一个时间类型的字符串。
> var date1str = date1.toString()> date1strTue Sep 17 2020 12:47:39 GMT+0800 (CST)> typeof date1strstring//或Tue Sep 17 2020 12:47:39 GMT+0800 (CST)> typeof date1strstring
MongoDB连接
使用 MongoDB shell 来连接 MongoDB 服务器。标准 URI 连接语法:
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[d
atabase][?options]]
上面命令行的解释:
mongodb:// 这是固定的格式,必须要指定。
username:password@,可选项,登陆指定数据库。
host1:指定至少一个host,host1 是这个 URI 唯一要填写,要连接服务器地址。如果要连接复制集,需要指定多个主机地址。
portX,默认端口为27017。也可以选择指定端口。
/database,默认打开test数据库,也可以连接上面指定的数据库。
?options 是连接选项。若不使用/database,则前面需要加上/。所有连接项都是键值对name=value,键值对之间通过&或分号隔开。
//使用默认端口连接服务mongodb://localhost//通过shell连接MongoDB服务$ ./mongoMongoDB shell version: 4.0.9connecting to: test...
使用username:password@hostname/dbname' 格式,'username'为用户名,'password' 为密码。使用用户 admin 使用密码 123456 连接到本地的 MongoDB 服务上。输出结果如下所示:
>mongodb://admin:123456@localhost/
//连接本地数据库,端口是默认mongodb://localhost//使用用户名fred,密码foobar登陆localhost的admin数据库mongodb://fred:foobar@localhost//用户名fred,密码foobar登陆localhost的baz数据库mongodb://fred:foobar@localhost/baz//连接replica pair,服务器 1 为 example1.com 服务器 2 为 example2。mongodb://example1.com:27017,example2.com:27017//连接 replica set 三台服务器 (端口 27017, 27018, 和 27019):mongodb://localhost,localhost:27018,localhost:27019//连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器mongodb://host1,host2,host3/?slaveOK=true//直接连接第一个服务器,不管是主服务器或从服务器mongodb://host1,host2,host3/?connect=direct;slaveOK=true//安全模式连接到 localhost:mongodb://localhost/?safe=true//安全模式连接到 replica set,并等待至少两个复制服务器成功写入,超时时间设置2秒。mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000
MongoDB创建数据库
基本语法格式
use DATABASE_NAME
若数据库不存在,则创建数据库,否则切换到指定数据库。
>use qaaswitched to db qaa>dbqaa
若要查看所有数据库,则使用show dbs命令:
>show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GBtest 0.000GB>
刚创建的数据库并不在数据库列表中,若要显示,就需要向数据库插入一些数据。MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
>db.qaa.insert({"name":"qaa"})WriteResult({ "nInserted" : 1 })>show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GB
MongoDB 删除数据库
//语法格式如下db.dropDatabase()//再次查看刚添加数据的数据库> show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GBtest 0.000GBqaa 0.000GB//切换数据库qaa>use qaaswitched to db qaa> //执行删除命令 >use qaa switched to db qaa >db.dropDatabase(){ "dropped" : qaa", "ok" : 1 }
再通过show dbs命令数据库是否删除成功:
> show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GB
MongoDB 创建集合
MongoDB 中 使用 createCollection() 方法来创建集合。
name:创建的集合名称
options:可选参数,有关内存大小及索引的选项
db.createCollection(name, options)
插入文档时,首先检查固定集合的size字段,再检查max字段。
//在test数据库中,创建qaa集合>use testswitched to db test>db.createCollection("qaa"){ "ok" : 1 }>
查看已有集合,可以使用 show collections 或 show tables 命令:
> show collectionsqaasystem.indexes
创建固定集合 mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个。
> db.createCollection("col", {capped: true, autoIndexId: true, size: 6142800, max: 10000}){"note" : "the autoIndexId option is deprecated and will be removed in a future release","ok" : 1}> show tables> db.createCollection("col", {capped: true, size: 6142800, max: 10000}){ "ok" : 1 }>
在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
>db.col2.insert({"name":"antonio"})WriteResult({ "nInserted" : 1 })>>show tablescolcol2antonio...
MongoDB 删除集合
db.collection.drop()。如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
先通过 show collections 命令查看已存在的集合:
>use qaaswitched to db qaa>show tablescolcol2qaa>
接着删除集合 col2 :
>db.col2.drop()true//再次查看集合,发现被删除>show tablescolqaa
从结果中可以看出col2集合被删除
Mongo 文档操作
插入文档
db.COLLECTION_NAME.insert(document)
可以把文档存储在MongoDB的qaa数据库的col集合中:
>db.col.insert({title:'MongoDB 详解',title:'MongoDB 教程',by:"qaa",url:'www.toutiao.com ',tags:['mongodb', 'database', 'NoSQL'],likes:100})WriteResult({ "nInserted" : 1 })
col 是我们的集合名,如果该集合不在该数据库中,,MongoDB 会自动创建该集合并插入文档。查看已插入文档
col 是我们的集合名,如果该集合不在该数据库中,
插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
更新文档
使用 update() 和 save() 方法来更新集合中的文档。
update() 方法用于更新已存在的文档。
db.collection.update(
<query>,
<update>,
{
upsert: ,
multi: ,
writeConcern:
}
)
query : update 的查询条件,类似 sql update 查询内 where 后面的。
update : update 的对象和一些更新的操作符(如$,$inc...)等,也可以理解为 sql update查询内 set 后面的
upsert : 可选,这个参数的意思是,如果不存在 update 的记录,是否插入 objNew,true为插入,默认是 false,不插入。
multi : 可选,mongodb 默认是 false,只更新找到的第一条记录,如果这个参数为 true, 就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
> db.col2.insert({
title:'MongoDB 教程',
description: 'MongoDB 是 DB',
by: 'qaa',
url: 'www.toutiao.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100})
WriteResult({ "nInserted" : 1 })
通过 update() 方法来更新标题(title):
> > db.col2.update({title:'MongoDB 教程'}, {$set:{title:'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.col2.find().pretty()
{
"_id" : ObjectId("5d807497019abe974dac5167"),
"title" : "MongoDB",
"description" : "MongoDB 是 DB",
"by" : "qaa",
"url" : "www.toutiao.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。
multi表示要修改多条文档。
> db.col2.update({title:'MongoDB 教程'}, {$set:{title:'MongoDB'}}, {multi:true})
save() 方法通过传入的文档来替换已有文档。语法格式如下:
document : 文档数据。
writeConcern :可选,抛出异常的级别
db.collection.save(
<document>,
{
writeConcern:
}
)
删除文档
db.collection.remove(
<query>,
<justOne>
)
若MongoDB 是 2.6 版本以后。
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默
认值 false,则删除所有匹配条件的文档。
writeConcern :(可选)抛出异常的级别。
db.collection.remove(
<query>,
{
justOne: ,
writeConcern:
}
)
移除 title 为 'MongoDB 教程' 的文档
> db.col.remove({'title':'MongoDB 教程'})
WriteResult({ "nRemoved" : 2 }) # 删除了两条数据
> db.col.find()
…… # 没有数据
删除第一条找到的记录可以设置 justOne 为 1,如下所示:
>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):
>db.col.remove({})
>db.col.find()
>
查询文档
MongoDB 查询文档使用 find() 方法。
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需
省略该参数即可(默认省略)。
db.collection.find(query, projection)
易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
pretty() 方法以格式化的方式来显示所有文档。
//查询集合col中的数据
> db.col2.find().pretty()
{
"_id" : ObjectId("5d807497019abe974dac5167"),
"title" : "MongoDB",
"description" : "MongoDB 是 DB",
"by" : "qaa",
"url" : "www.0voice.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。
AND条件
db.col.find({key1:value1, key2:value2}).pretty()。类似于 WHERE 语句:WHERE by='xxx' AND 。
> db.col.find({"by":"qaa", "title":"MongoDB 教程"}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "qaa",
"url" : "http://www.toutiao.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
OR 条件
OR 条件语句使用了关键字 $or,语法格式如下:
>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
查询键 by 值为qaa或键title值为MongoDB 教程的文档。
>db.col.find({$or:[{"by":"qaa"},{"title":"MongoDB教程"}]}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "qaa",
"url" : "http://www.toutiao.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
MongoDB (>) 大于操作符 - $gt
MongoDB(>=)大于等于操作符 - $gte
MongoDB (
MongoDB (<=) 小于等于操作符 - $lte
$type 操作符
$type 操作符是基于 BSON 类型来检索集合中匹配的数据类型,并返回结果。如下表所示:
- $type 实例
获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令:
>db.col.find({"title":{$type:2}})
或
>db.col.find(获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令:)
MongoDB Limit() 方法
要在 MongoDB 中读取指定数量的数据记录,可以使用 MongoDB 的 Limit 方法,limit()方法接受一个数字参数,从MongoDB中读取的记录条数。没有指定 limit()方法中的参数则显示集合中的所有数据。
limit()方法基本语法如下所示:
>db.COLLECTION_NAME.find().limit(NUMBER)
显示查询文档中的两条记录:
> db.col.find({},{"title":1}).limit(5)
{ "_id" : ObjectId("5d807c11019abe974dac516a"), "title" : "c++教程" }
{ "_id" : ObjectId("5d807c6e019abe974dac516b"), "title" : "c langage" }
{ "_id" : ObjectId("5d807c9b019abe974dac516c"), "title" : "java" }
{ "_id" : ObjectId("5d807cb0019abe974dac516d"), "title" : "php" }
Skip() 方法
使用 skip()方法来跳过指定数量的数据,skip 方法同样接受一个数字参数作为跳过的记录条数。skip()方法默认参数为 0 。
语法格式如下:
> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
以下实例只会显示第二条文档数据
> db.col.find({},{"title":1}).limit(5).skip(2)
{ "_id" : ObjectId("5d807c9b019abe974dac516c"), "title" : "java" }
{ "_id" : ObjectId("5d807cb0019abe974dac516d"), "title" : "php" }
sort() 方法
sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
sort()方法基本语法如下所示:
>db.COLLECTION_NAME.find().sort({KEY:1})
MongoDB 索引
索引能够提高查询的效率,若没有索引,MongoDb需要在读取数据时,扫描文件,这种方式效率很低。索引一般存在易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。
MongoDB 使用 createIndex() 方法来创建索引。
>db.collection.createIndex(keys, options)
key值为创建的索引字段,1为指定按升序创建索引,-1表示按照降序。
>db.col.createIndex({"title":1})
createIndex() 方法中设置使用多个字段创建索引
> db.col.createIndex({"title":1,"description":-1})
createIndex() 接收可选参数,可选参数列表如下:
在后台创建索引:
创建索引时加 background:true 的选项,让创建工作在后台执行。
>db.values.createIndex({open:1,close:1}, {background:true})
MongoDB 聚合
用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似 sql 语句中的 count(*)。
MongoDB 中聚合的方法使用 aggregate()。aggregate() 方法的基本语法格式如下所示:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
通过以上集合计算每个作者所写的文章数,使用 aggregate()计算结果如下:
> db.col.aggregate([{$group: {_id: "$likes", num: {$sum:1}}}])
{ "_id" : 90, "num" : 1 }
{ "_id" : 80, "num" : 1 }
{ "_id" : 100, "num" : 1 }
{ "_id" : 150, "num" : 1 }
>
以上实例类似 sql 语句:
select likes, count(*) from col group by likes
下面也有一些聚合的表达式:
MongoDB 复制
复制是将数据同步在多个服务器的过程,提供数据冗余备份,并存储数据副本,保证数据安全性。复制允许从硬件故障和服务中断中恢复数据。
复制的特点:
(1)保障数据的安全性
(2)数据高可用性 (24*7)
(3)灾难恢复
(4)无需停机维护(如备份,重建索引,压缩)
(5)分布式读取数据
复制原理
复制至少需要两个节点,一个是主节点,负责处理客户端请求,其它都是从节点,负责复制主节点上的数据。各个节点常见的搭配方式为,一主一从,一主多从。主节点记录所有操作oplog,从节点定期轮询主节点获取这些操作,然后对数据副本执行这些操作,保证从节点数据与主节点数据一致,实现备份。
如下图所示:
客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。
副本集特征:
(1) N个节点的集群
(2)任何节点可作为主节点
(3)所有写入操作都在主节点上
(4)自动故障转移
(5)自动恢复
副本集设置
使用同一个 MongoDB 来做 MongoDB 主从的实验, 操作步骤如下:
(1)关闭正在运行的 MongoDB 服务器。
指定 --replSet 选项来启动 mongoDB。--replSet 基本语法格式如下:
启动一个名为rs0的MongoDB 实例,其端口号为 27017。命令提示框并连接上 mongoDB 服务。
客户端可以使用命令令 rs.initiate()启动一个新的副本集。使用rs.conf()来查看副本集的配置。使用rs.status()命令来查看副本集状态。
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NA
ME"
mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
副本集添加成员,使用多台服务启动mongo服务。进入Mongo客户端,使用rs.add()方法来添加副本集的成员。
//添加副本集的成员
>rs.add(HOST_NAME:PORT)
如果已经启动了一个mongod1.net,端口号为 27017 的 Mongo 服务。在客户端命令窗口使用 rs.add() 命令将其添加到副本集中,命令如下所示:
> rs.add("mongod1.net:27017")
>
只能通过主节点将Mongo服务添加到副本集中,判断当前运行节点的Mongo服务是否为主节点,可以用命令db.isMaster()。当主机宕机后,副本会接管主节点,不会出现宕机的情况。
MongoDB 分片
分片技术,可以满足 MongoDB 数据量大量增长的需求。当数据量大增时,一台机器可能不足以存储数据,也不能提供可接受的读写吞吐量。分片就是在多台机器上分割数据,使得数据系统能存储和处理更多的数据。
使用分片的理由:
(1)复制所有写入操作到主节点
(2)延迟敏感数据在主节点查询
(3)单个副本集限制在 12 个节点
(4)当请求量巨大,会出现内存不足
(5)本地磁盘不足
Mongo中使用分片集群结构分布:
图中主要有如下所述三个主要组件:
Shard:
存储实际的数据,实际生产环境中一个 shard server 角色可由几台机器组个一个replica set 承担,防止主机单点故障。
Config Server:
mongod 实例,存储了整个 ClusterMetadata,其中包括 chunk 信息。
Query Routers:
前端路由,客户端由此接入,让整个集群看上去像单一数据库,前端应用可以透明使用。
举例
分片结构端口分布如下:
Shard Server 1:27020
Shard Server 2:27021
Shard Server 3:27022
Shard Server 4:27023
Config Server :27100
Route Process:40000
(1)启动 Shard Server
[root@100 /]# mkdir -p /www/mongoDB/shard/s0
[root@100 /]# mkdir -p /www/mongoDB/shard/s1
[root@100 /]# mkdir -p /www/mongoDB/shard/s2
[root@100 /]# mkdir -p /www/mongoDB/shard/s3
[root@100 /]# mkdir -p /www/mongoDB/shard/log
[root@100 /]# /usr/local/mongoDB/bin/mongod --port 27020 --dbpath=/www/mongoDB/shard
/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork
....
[root@100 /]# /usr/local/mongoDB/bin/mongod --port 27023 --dbpath=/www/mongoDB/shard
/s3 --logpath=/www/mongoDB/shard/log/s3.log --logappend --fork
(2)启动 Config Server
可以像启动普通 mongodb 服务一样启动,不需要添加—shardsvr 和 configsvr 参数。因为这两个参数的作用就是改变启动端口的,所以我们自行指定了端口就可以。
[root@100 /]# mkdir -p /www/mongoDB/shard/config
[root@100 /]# /usr/local/mongoDB/bin/mongod --port 27100 --dbpath=/www/mongoDB/shard
/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork
(3)启动Route Process
mongos 启动参数中,chunkSize 这一项是用来指定 chunk 的大小的,单位是 MB,默认大小为200MB
/usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork --logpa
th=/www/mongoDB/shard/log/route.log --chunkSize 500
(4)配置Sharding
使用 MongoDB Shell 登录到 mongos,添加 Shard 节点
[root@100 shard]# /usr/local/mongoDB/bin/mongo admin --port 40000
MongoDB shell version: 2.0.7
connecting to: 127.0.0.1:40000/admin
mongos> db.runCommand({ addshard:"localhost:27020" })
{ "shardAdded" : "shard0000", "ok" : 1 }
......
mongos> db.runCommand({ addshard:"localhost:27029" })
{ "shardAdded" : "shard0009", "ok" : 1 }
mongos> db.runCommand({ enablesharding:"test" }) #设置分片存储的数据库
{ "ok" : 1 }
mongos> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}})
{ "collectionsharded" : "test.log", "ok" : 1 }
MongoDB 数据备份
使用 mongodump 命令来备份 MongoDB 数据,用命令可以导出所有数据到指定目录,mongodump 命令可通过参数指定导出的数据量级转存的服务器。
>mongodump -h dbhost -d dbname -o dbdirectory
-h:
MongDB 所在服务器地址,如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:
备份的数据库实例,如test
-o
备份的数据库位置,如:c:\data\dump,该目录需要提前建立,备份完成后,系统自动在dump目录下建立一个test目录,test目录就是存放实际的数据。
打开命令窗口,在MongoDb安装目录的bin目录输入命令mongodump。
$ mongodump
连接上后,会把数据备份到bin/dump目录中,输出结果如下:
mongodump 命令可选参数列表如下所示:
MongoDB 数据恢复
mongorestore命令恢复备份的数据。
格式如下:
>mongorestore -h <hostname><:port> -d dbname <path>
--host <:port>, -h <:port>:
MongoDB 所在服务器地址,默认为:localhost:27017
--db , -d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如 test2
--drop:
恢复后,备份后添加修改的数据都会被删除。
:
设置备份数据位置,不能同时指定 和 --dir 选项,--dir 也可以设置备份目录。
--dir:
不能同时指定 和 --dir 选项。
> mongorestore
输出结果如下:
MongoDB 监控
mongostat是自带的状态监测工具,间隔固定时间获取当前的运行状态,如果发现数据库变慢或其他问题,就用mongostat查看mongo的状态。
到你安装的 MongoDB 目录下的 bin 目录,然后输入 mongostat命令,如下所示
$ mongostat
mongotop
mongotop主要是提供一个方法,用来跟踪MongoDb,哪些操作花费了大量时间和读取。
输入mongotop命令,如下:
带参数实例
$ mongotop 3
mongotop --locks
每个数据库的锁的使用中,使用 mongotop - 锁,这将产生以下输出:
ns:
包含数据库命名空间,后者结合了数据库名称和集合
db:
数据库名称,名为 . 的数据库针对全局锁定,而非特定数据库。
total:
mongod 花费的时间工作在这个命名空间提供总额。
read:
提供读操作
write:
命名空间进行写操作。可能需要花费大量的时间。
这篇文章就分享到这里,欢迎转发,评论,点赞。
欢迎关注头条号
欢迎关注微信公众号