MongoDB学习(接上文)
Mongodb学习
- Mongodb是什么
- MySQL和MongoDB对比
- 相关术语对比
- 数据模型
- Mongodb的下载安装
- 安装
- 关闭服务
- 数据修复
- 基本常用命令
- 数据库操作
- 选择和创建数据库
- 查看数据库
- 删除数据库
- 集合操作
- 显式创建集合
- 隐式创建集合
- 查看集合
- 删除集合
- 文档操作
- 插入文档
- 单条插入
- 批量插入
- Try-catch处理批量操作
- 更新文档
- 覆盖修改
- 局部修改
- 批量修改
- 列值增长的修改
- 删除文档
- 查询文档
- 全部查询
- 条件查询
- 投影查询(Projection Query)
- 统计查询
- 分页查询
- 排序查询
- 正则查询
- 比较查询
- 包含查询
- 条件连接查询
- 索引
- 索引的类型
- 单字段索引
- 复合索引
- 其他索引
- 地理空间索引(Geospatial Index)
- 文本索引(Text Indexes)
- 哈希索引(Hashed Indexes)
- 索引管理
- 查询索引
- 创建索引
- 索引的移除
- 指定索引的移除
- 所有索引的移除
- 索引的使用
- 执行计划
- MongoDB的副本集
- 简介
- 副本集的三个角色
- 搭建副本集
- 创建主节点
- 创建从节点
- 创建仲裁节点
- 初始化配置副本集和主节点
- 查看副本集的配置内容
- 查看副本集状态
- 添加副本从节点
- 添加仲裁从节点
- 副本集合数据的读写操作
- 主节点的选举原则
- 故障测试
- MongoDB的分片集群-Sharded Cluster
- 分片概念
- 分片集群包含的组件
- 分片集群架构目标
- 路由命令
- (1)添加分片:
- (2)开启分片功能
- (3)集合分片
- MongoDB的安全认证
- 单实例环境演示
- 关闭已经开启的服务
- 添加用户权限
- 服务端开启认证和客户端连接登录
- 副本集环境演示
- 分片集群环境演示
- Docker安装
- Docker单点安装
- Docker安装mongodb副本集
- SpringBoot整合Mongodb
Mongodb是什么
MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。
它支持的数据结构非常松散,是一种类似于 JSON 的 格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。
MongoDB中的记录是一个文档,它是一个由字段和值对(fifield:value)组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认 为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组
MySQL和MongoDB对比
相关术语对比
数据模型
MongoDB的最小存储单位就是文档(document)对象。文档(document)对象对应于关系型数据库的行。数据在MongoDB中以 BSON(Binary-JSON)文档的格式存储在磁盘上。
BSON(Binary Serialized Document Format)是一种类json的一种二进制形式的存储格式,简称Binary JSON。BSON和JSON一样,支持 内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。
Mongodb的下载安装
安装
1.去mongodb官网下载指定的版本
2.上传压缩包到Linux中,解压
cd /usr/local/mongodb
tar -xvf mongodb-linux-x86_64-4.0.10.tgz
3.新建几个目录,分别用来存储数据和日志、配置
mkdir -p /usr/local/mongodb/data
mkdir -p /usr/local/mongodb/log
mkdir -p /usr/local/mongodb/conf
4.新建并修改配置文件
vim /usr/local/mongodb/conf/mongod.conf
内容如下:
systemLog:#MongoDB发送所有日志输出的目标指定为文件destination: filepath: "/usr/local/mongodb/log/mongod.log"logAppend: true
storage:#mongod实例存储其数据的目录dbPath: "/usr/local/mongodb/data"journal:#启用或禁用持久性日志以确保数据文件保持有效和可恢复。 enabled: true
processManagement: #启用在后台运行mongos或mongod进程的守护进程模式。 fork: true
net:#服务实例绑定的IP,默认是localhost bindIp: 0.0.0.0port: 27017
5.启动MongoDB服务
/usr/local/mongodb/mongodb-linux-x86_64-4.0.10/bin/mongod -f /usr/local/mongodb/conf/mongod.conf
如果启动后不是 successfully ,则是启动失败了。原因基本上就是配置文件有问题
关闭服务
//客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27017
//#切换到admin库
use admin
//关闭服务
db.shutdownServer()//也可以直接杀掉进程
数据修复
果一旦是因为数据损坏,则需要进行如下操作
删除lock文件
rm -f /usr/local/mongodb/data/*.lock
修复数据
/usr/local/mongdb/bin/mongod --repair --dbpath=/usr/local/mongodb/data
基本常用命令
需求:
存放文章评论的数据存放到MongoDB中,数据结构参考如下:
数据库:articledb
数据库操作
离不开的增删改查,MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中,有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库
admin:从权限角度来看,这是“root”数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器命令也只能在这个数据库运行,比如列出所有的数据库或者关闭服务器。
local:这个里面数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
config:当Mango用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
选择和创建数据库
//创建的时候会存在内存当中,当数据库中有集合的时候会被持久化到磁盘
use articledb //如果数据库不存在则自动创建
查看数据库
//查看所有数据库(没持久化到磁盘中不现实)
show dbs
//查看正在使用的数据库
db
删除数据库
db.dropDatabase() //提示:主要用来删除已经持久化的数据库
集合操作
集合的命名规范:
- 集合名不能是空字符串""。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以"system."开头,这是为系统集合保留的前缀。
- 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除 非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
显式创建集合
db.createCollection(name)
隐式创建集合
直接创建文档,会自动创建集合,通常我们使用隐式创建文档即可
查看集合
show collections
或
show tables
删除集合
db.collection.drop()
或
db.集合.drop()
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
文档操作
文档键命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线"_"开头的键是保留的(不是严格要求的)
插入文档
使用insert() 或 save() 方法向集合中插入文档,语法如下:
db.collection.insert( <document or array of documents>, { writeConcern: <document>, ordered: <boolean> }
)
参数:
单条插入
要向comment的集合(表)中插入一条测试数据:
db.comment.insert({"articleid": "100000","content": "今天天气真好,阳光明 媚","userid": "1001","nickname": "Rose","createdatetime": new Date(),"likenum": NumberInt(10),"state": null
})执行后,如下,说明插入一个数据成功了WriteResult({ "nInserted" : 1 })
提示:
- comment集合如果不存在,则会隐式创建
- mongo中的数字,默认double类型,如要存整型,必须使用函数NumberInt,否则取出来就有问题了。
- 插入当前日期使用 new Date()
- 插入的数据没有指定 _id ,会自动生成主键值
- 如果某字段没值,可以赋值为null,或不写该字段。
注意:
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
批量插入
语法:
db.collection.insertMany([ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> }
)
示例:
db.comment.insertMany([{"_id": "1","articleid": "100001","content": "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。","userid": "1002","nickname": "相忘于江湖","createdatetime": new Date("2019-08- 05T22:08:15.522Z"),"likenum": NumberInt(1000),"state": "1"
},
{"_id": "2","articleid": "100001","content": "我夏天空腹喝凉开水,冬天喝温开水","userid": "1005","nickname": "伊人憔 悴","createdatetime": new Date("2019-08-05T23:58:51.485Z"),"likenum": NumberInt(888),"state": "1"
}]);
提示:
插入时指定了 _id ,则主键就是该值。
Try-catch处理批量操作
如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。
try { //批量操作语句
} catch (e) { print (e);
}
更新文档
更新文档的语法:
db.collection.update(query, update, options)
或
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], hint: <document|string> // Available starting in MongoDB 4.2 }
)
覆盖修改
如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:
//执行后,我们会发现,这条文档除了likenum字段其它字段都不见了
db.comment.update({_id:"1"},{likenum:NumberInt(1001)})
局部修改
为了解决覆盖修改问题,我们需要使用修改器$set来实现,命令如下:
我们想修改_id为2的记录,浏览量为889,输入以下语句:
db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}})
批量修改
更新所有用户为 1003 的用户的昵称为 凯撒大帝 。
//默认只修改第一条数据
db.comment.update({userid:"1003"},{$set:{nickname:"凯撒2"}})
//修改所有符合条件的数据
db.comment.update({userid:"1003"},{$set:{nickname:"凯撒大帝"}},{multi:true})
//提示:如果不加后面的参数,则只更新符合条件的第一条记录
列值增长的修改
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。
需求:对3号数据的点赞数,每次递增1
db.comment.update({_id:"3"},{$inc:{likenum:NumberInt(1)}})
删除文档
删除文档的语法结构:
db.集合名称.remove(条件)
以下语句可以将数据全部删除,请慎用
db.comment.remove({})
如果删除_id=1的记录,输入以下语句
db.comment.remove({_id:"1"})
查询文档
查询数据的语法格式如下:
db.collection.find(<query>, [projection])
参数:
Parameter | Type | Description |
---|---|---|
query | document | 可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档 ({}) |
projection | document | 可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段, |
全部查询
如果我们要查询集合的所有文档,我们输入以下命令
db.comment.find()
或
db.comment.find({})
这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段, MongoDB会自动创建,其类型是ObjectID类型。 如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也可以是MongoDB支持的任意类型.
条件查询
如:查询用户编号是1003的记录,但只最多返回符合条件的第一条记录:
db.comment.findOne({userid:'1003'})
投影查询(Projection Query)
查询自己需要的字段(不显示所有字段,只显示指定的字段)。
如:查询结果只显示 _id、userid、nickname :
// _id不指定的话默认是显示的
db.comment.find({userid:"1003"},{userid:1,nickname:1})
如:查询结果只显示 、userid、nickname ,不显示 _id :
db.comment.find({userid:"1003"},{userid:1,nickname:1,_id:0})
如:查询所有数据,但只显示 _id、userid、nickname :
db.comment.find({},{userid:1,nickname:1})
统计查询
db.collection.count(query, options)
参数:
Parameter | Type | Description |
---|---|---|
query | document | 查询选择条件。 |
options | document | 可选。用于修改计数的额外选项。 |
示例:
统计comment集合的所有的记录数:
db.comment.count()
统计userid为1003的记录条数
db.comment.count({userid:"1003"})
分页查询
可以使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据
基本语法如下所示:
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
如果你想返回指定条数的记录,可以在fifind方法后调用limit来返回结果(TopN),默认值20,例如
//查询前三条数据
db.comment.find().limit(3)
skip方法同样接受一个数字参数作为跳过的记录条数。(前N个不要),默认值是0
//查询第三条后的所有数据
db.comment.find().skip(3)
分页查询:需求:每页2个,第二页开始:跳过前两条数据,接着值显示3和4条数据
//第一页
db.comment.find().skip(0).limit(2)
//第二页
db.comment.find().skip(2).limit(2)
//第三页
db.comment.find().skip(4).limit(2)
排序查询
sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用 于降序排列
db.COLLECTION_NAME.find().sort({KEY:1})
或
db.集合名称.find().sort(排序方式)
对userid降序排列,并对访问量进行升序排列
db.comment.find().sort({userid:-1,likenum:1})
提示:
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。
正则查询
MongoDB的模糊查询是通过正则表达式的方式实现的。格式为:
db.collection.find({field:/正则表达式/})
或
db.集合.find({字段:/正则表达式/})
提示:正则表达式是js的语法,直接量的写法。
例如,我要查询评论内容包含“开水”的所有文档,代码如下:
db.comment.find({content:/开水/})
如果要查询评论的内容中以“专家”开头的,代码如下:
db.comment.find({content:/^专家/})
比较查询
<, <=, >, >= 这个操作符也是很常用的,格式如下:
db.集合名称.find({ "field" : { $gt: value }}) // 大于: field > value
db.集合名称.find({ "field" : { $lt: value }}) // 小于: field < value
db.集合名称.find({ "field" : { $gte: value }}) // 大于等于: field >= value
db.集合名称.find({ "field" : { $lte: value }}) // 小于等于: field <= value
db.集合名称.find({ "field" : { $ne: value }}) // 不等于: field != value
示例:查询评论点赞数量大于700的记录
db.comment.find({likenum:{$gt:NumberInt(700)}})
包含查询
包含使用$in操作符。 示例:查询评论的集合中userid字段包含1003或1004的文档
db.comment.find({userid:{$in:["1003","1004"]}})
不包含使用$nin操作符。 示例:查询评论集合中userid字段不包含1003和1004的文档
db.comment.find({userid:{$nin:["1003","1004"]}})
条件连接查询
我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。 格式为:
$and:[ { },{ },{ } ]
示例:查询评论集合中likenum大于等于700 并且小于2000的文档:
db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]})
如果两个以上条件之间是或者的关系,我们使用 操作符进行关联,与前面 and的使用方式相同 格式为:
$or:[ { },{ },{ } ]
示例:查询评论集合中userid为1003,或者点赞数小于1000的文档记录
db.comment.find({$or:[ {userid:"1003"} ,{likenum:{$lt:1000} }]})
索引
索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。
索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。
MongoDB索引使用B树数据结构(确切的说是B-Tree,MySQL是B+Tree)
官网文档:https://docs.mongodb.com/manual/indexes/
索引的类型
单字段索引
MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。
对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引。
复合索引
MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。
复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后在每个userid的值内,再在按score倒序排序
其他索引
地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。
地理空间索引(Geospatial Index)
为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面 几何的二维球面索引。
文本索引(Text Indexes)
MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”),而将集合中的词作为词干,只存储根词。
哈希索引(Hashed Indexes)
为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支 持相等匹配,不支持基于范围的查询。
索引管理
查询索引
返回一个集合中的所有索引的数组
db.collection.getIndexes()
结果中显示的是默认 _id 索引。
默认_id索引:MongoDB在创建集合的过程中,在 _id 字段上创建一个唯一的索引,默认名字为 id ,该索引可防止客户端插入两个具有相同值的文 档,您不能在_id字段上删除此索引。
注意:该索引是唯一索引,因此值不能重复,即 _id 值不能重复的。在分片集群中,通常使用 _id 作为
创建索引
在集合上创建索引
db.collection.createIndex(keys, options)
参数:
options(更多选项)列表:
提示:
注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex() ,之后的版本使用了 db.collection.createIndex() 方法, ensureIndex() 还能用,但只是 createIndex() 的别名。
示例:
(1)单字段索引示例:对 userid 字段建立索引:
db.comment.createIndex({userid:1})
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1
}
索引的移除
可以移除指定的索引,或移除所有索引
指定索引的移除
db.collection.dropIndex(index)
示例:删除 comment 集合中 userid 字段上的升序索引:
db.comment.dropIndex({userid:1})
所有索引的移除
db.collection.dropIndexes()
索引的使用
执行计划
分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是否基于索引查询等。
那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看
db.collection.find(query,options).explain(options)
示例:
查看根据userid查询数据的情况:
db.comment.find({userid:"1003"}).explain()
关键点看: “stage” : “COLLSCAN”, 表示全集合扫描
下面对userid建立索引
> db.comment.createIndex({userid:1})
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1
}
再次查看执行计划,关键点看: “stage” : “IXSCAN” ,基于索引的扫描
MongoDB的副本集
简介
是一组维护相同数据集的Mongod服务,副本集可以提供冗余和高可用性,是所有生产部署的基础。
同时也是类似于有自动故障恢复功能的主从集群。用多台机器进行同一数据的异步和同步,从而使得多台机器拥有同一数据的多个副本。并且当主库宕机时不需要用户敢于的情况下自动切换其他备份服务器做主库。还可以利用副本服务器做只读服务器,实现读写分离,提高负载。
(1)冗余和数据可用性
复制提供冗余并提高数据可用性。通过在不同数据库服务器上提供多个数据副本,复制可提高一定级别的容错功能,以防止丢失单个数据库服务器。
某些情况下,复制可以提供增加的读取性能,因为客户端可以将读取操作发送到不同的服务上,在不同数据中心维护数据副本可以增加分布式应用程序的数据位置和可以性。还可以用于维护其他副本,灾难恢复,报告或者备份。
(2)复制
副本集时一组维护相同数据集的mongod实例。包含多个数据承载节点和可选的一个仲裁节点。在承载数据的节点中,一个且仅有一个成为被视为主节点,其他节点被视为次要节点。
主节点接收所有写操作,副本集只有一个主要能够确认具有{w:“most”}写入关注的写日;虽然某些情况下,另一个mongod实例可能暂时认为自己也是主要的。主要记录其操作日志中的数据集的所有更改,即oplog。
(3)主从复制和副本集区别
主从集群和副本集最大区别就是副本集没有固定的"主节点";整个集群会选出一个"主节点",当其挂掉后,又在剩下的从节点中选中其他节点为"主节点",副本集总有一个活跃点{主、primary}和一个或多个备份节点{从、secondary}.
副本集的三个角色
副本集有两种数据类型三个角色
两种类型:
- 主节点(primary)类型:数据操作的主要连接点,可读写。
- 次要(辅助、从)节点类型:数据冗余备份节点,可以读或选举。
三种角色:
主要成员(primary):主要接收所有写操作。就是主节点。
副本成员(Replicate):从主节点通过复制操作以维护相同的数据集,即数据备份,不可写操作,但可以读操作(但需要配置)。是默认的一种从节点类型。
仲裁者(Arbiter):不保留任何数据的副本,只具有投票选举作用。当然也可以将仲裁服务器维护为副本集的一部分,即副本成员同时也可以是仲裁者。也是一种从节点类型。
搭建副本集
一主一从一仲裁。
创建主节点
1.建立存放数据和日志的目录
#---------myrs
#主节点
mkdir -p /Users/didi/xzy/replica_sets/myrs_27017/log
mkdir -p /Users/didi/xzy/replica_sets/myrs_27017/data/db
2.新建或修改配置文件:
vim /Users/didi/xzy/replica_sets/myrs_27017/mongod.conf
主节点的配置文件myrs_27017:
systemLog:#MongoDB发送所有日志输出的目标指定为文件destination: file#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径path: "/Users/didi/xzy/replica_sets/myrs_27017/log/mongod.log"#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。logAppend: true
storage:#mongod实例存储其数据的目录,storage.dbPath设置仅适用于mongod。dbPath: "/Users/didi/xzy/replica_sets/myrs_27017/data/db"journal:#启用或禁用持久性日志以确保数据文件保持有效和可恢复。enabled: true
processManagement:#启用在后台运行mongos或mongod进程的守护进程模式fork: true#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PIDpidFilePath: "/Users/didi/xzy/replica_sets/myrs_27017/log/mongod.pid"
net:#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip#bindIpAll:true#服务实例绑定的IPbindIp: localhost#bindIp#绑定的端口port: 27017#三个副本集的名称都指定为myrs
replication:#副本集的名称replSetName: myrs
3.启动节点服务:
mongod -f /Users/didi/xzy/replica_sets/myrs_27017/mongod.confmongod --dbpath /Users/didi/xzy/replica_sets/myrs_27017/data/db --logpath /Users/didi/xzy/replica_sets/myrs_27017/log/mongod.log --fork
创建从节点
1.建立存放数据和日志的目录
#---------myrs
#从节点
mkdir -p /Users/didi/xzy/replica_sets/myrs_27018/log
mkdir -p /Users/didi/xzy/replica_sets/myrs_27018/data/db
2.新建或修改配置文件:
vim /Users/didi/xzy/replica_sets/myrs_27018/mongod.conf
myrs_27018:
systemLog:#MongoDB发送所有日志输出的目标指定为文件destination: file#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径path: "/Users/didi/xzy/replica_sets/myrs_27018/log/mongod.log"#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。logAppend: true
storage:#mongod实例存储其数据的目录,storage.dbPath设置仅适用于mongod。dbPath: "/Users/didi/xzy/replica_sets/myrs_27018/data/db"journal:#启用或禁用持久性日志以确保数据文件保持有效和可恢复。enabled: true
processManagement:#启用在后台运行mongos或mongod进程的守护进程模式fork: true#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PIDpidFilePath: "/Users/didi/xzy/replica_sets/myrs_27018/log/mongod.pid"
net:#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip#bindIpAll:true#服务实例绑定的IPbindIp: localhost#bindIp#绑定的端口port: 27018 #这里端口号与主节点不同
replication:#副本集的名称replSetName: myrs
3.启动服务
mongod -f /Users/didi/xzy/replica_sets/myrs_27018/mongod.confmongod --dbpath /Users/didi/xzy/replica_sets/myrs_27018/data/db --logpath /Users/didi/xzy/replica_sets/myrs_27018/log/mongod.log --fork
创建仲裁节点
1.建立存放数据和日志的目录
#---------myrs
#从节点
mkdir -p /Users/didi/xzy/replica_sets/myrs_27019/log
mkdir -p /Users/didi/xzy/replica_sets/myrs_27019/data/db
2.新建或修改配置文件:
vim /Users/didi/xzy/replica_sets/myrs_27019/mongod.conf
myrs_27019:
systemLog:#MongoDB发送所有日志输出的目标指定为文件destination: file#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径path: "/Users/didi/xzy/replica_sets/myrs_27019/log/mongod.log"#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。logAppend: true
storage:#mongod实例存储其数据的目录,storage.dbPath设置仅适用于mongod。dbPath: "/Users/didi/xzy/replica_sets/myrs_27019/data/db"journal:#启用或禁用持久性日志以确保数据文件保持有效和可恢复。enabled: true
processManagement:#启用在后台运行mongos或mongod进程的守护进程模式fork: true#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PIDpidFilePath: "/Users/didi/xzy/replica_sets/myrs_27019/log/mongod.pid"
net:#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip#bindIpAll:true#服务实例绑定的IPbindIp: localhost#bindIp#绑定的端口port: 27019 #这里端口号与主节点不同
replication:#副本集的名称replSetName: myrs
3.启动服务
mongod -f /Users/didi/xzy/replica_sets/myrs_27019/mongod.confmongod --dbpath /Users/didi/xzy/replica_sets/myrs_27019/data/db --logpath /Users/didi/xzy/replica_sets/myrs_27019/log/mongod.log --fork
初始化配置副本集和主节点
使用客户端命令连接任意一个节点,但这里尽量要连接主节点(27017节点)使之成为主节点:
mongo --host=localhost --port=27017
连入后必须初始化副本才行
rs.initiate() #可加参数configuration//"ok"的值为1,说明创建成功
//命令行提示符发生变化,变成一个从节点角色,此时默认不能读写。稍等片刻,回车,变成主节点myrs:SECONDARY>
myrs:PRIMARY>
初始化之后按一下回车从secondary变为primary
查看副本集的配置内容
rs.conf()来查看副本集的配置内容
查看副本集状态
rs.status()查看副本集状态
添加副本从节点
在主节点添加从节点,将其他成员加入到副本集中
语法:
rs.add(host,arbiterOnly)
Parameter | Type | Description |
---|---|---|
host | string or document | 要添加到副本集的新成员。指定为字符串或配置文档:1)如果是一个字符串,则需要指定新成员的主机名和可选的端口号;2)如果是一个文档,请指定在members数组中找到的副本集成员配置文档。您必须在成员配置文档中指定主机字段。有关文档配置字段的说明,详见下方文档:“主机成员的配置文档” |
arbiterOnly | boolean | 可选的。仅在值为字符串时适用。如果为true,则添加的主机是仲裁者。 |
主机成员的配置文档:
{_id:<int>,host:<string>,arbiterOnly:<boolean>,buildIndexes:<boolean>,hidden:<boolean>,priority:<number>,tags:<document>,slaveDelay:<int>,votes:<number>
}
示例:
将27018的副本节点加添加到副本集汇总:
rs.add("localhost:27018")
添加仲裁从节点
rs.add(host,arbiterOnly)
或
rs.addArb(host)例子:
rs.addArb("localhost:27019")
副本集合数据的读写操作
登陆主节点27017,写入和读取数据:
mongo --host localhost --port 27017
use articledb
db.comment.insert({"articleid":"100000","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Aoi","createdatetime":new Date()})
登陆从节点:
mongo --host localhost --port 27018
#此时进入时会发现无法读取任何数据,要先将当前节点变为从节点
rs.slaveOk()
或
rs.slaveOk(true)若要取消从节点
rs.slaveOk(false)
仲裁者节点
该节点不存放任何数据信息,只用于查看配置信息
主节点的选举原则
MongoDB在副本集中,会自动进行主节点的选举,主节点选举的触发条件:
- 主节点故障
- 主节点网络不可达(默认心跳信息为10秒)
- 人工干预(rs.stepDown(600))
一旦触发选举,就要根据一定的规则来选主节点
选举规则是根据票数来决定谁获胜:
- 票数最高,且获得了"大多数"成员的投票支持的节点获胜
"大多数"的定义为:假设复制集内投票成员数量为N,则大多数为N/2+1。例如:3个投票成员,则大多数的值是2.当复制集内存活的数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
- 若票数相同,且都获得了"大多数"成员的投票支持的,数据新的节点获胜。
数据的新旧是通过操作日志oplog来对比的。
在获得票数的时候,优先级(priority)参数影响重大。
可以通过优先级(priority)来设置额外票数。优先级即权重,取之为0-1000,相当于可以额外增加1-1000的票数,优先级的值越大,就越可能获得多数成员的投票(votes)数。指定较高的值可以使成员更有资格成为主要成员,更低的值可使成员更不符合条件。
默认情况下,优先级的设置是1。(因为仲裁节点不会存储数据,所以他的优先级默认为0)
通过命令查看优先级信息:
myrs:PRIMARY>rs.conf()
故障测试
1.模拟副本节点挂掉。
关闭副本节点,因为主节点还在,因此,没有触发投票选举。
如果给主节点写入数据后,启动副本节点,数据会自动同步给副本节点
2.主节点故障测试
关闭主节点后,从节点和仲裁节点对主节点的心跳失败,当失败超过十秒,没有主节点,会触发投票机制。
副本节点给自己投了一票,仲裁节点也给他投了一票。超过大多数。
副本节点成为主节点。具备读写功能。
3.仲裁节点和主节点挂掉
关闭后,发现从节点还是从节点,只具有独读操作,因为他的票数没有获得大多数。只有默认自己给自己的一票。
会出现:
- 加入仲裁节点,副节点变为主节点。
- 加入一个其他节点,会发起选举,谁的数据新,谁是主节点。
4.仲裁节点和副本节点挂掉
十秒后,主节点降级为副本节点,只具有读操作。
MongoDB的分片集群-Sharded Cluster
分片概念
分片是一种跨多台机器分布数据的方法,MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。
换句话说:分片就是将数据拆分,将其分散到不同的机器上的过程。
有两种解决系统增长的方法:垂直扩展和水平扩展
分片集群包含的组件
MongoDB分片集群包含以下组件:
分片(存储):每个分片包含分片数据的子集。每个分片都可以部署为副本集。
mongos(路由):mongos充当查询路由器,在客户端应用程序和分片集群之间提供接口。
config servers(“调度”的配置):配置服务器存储集群的元数据和配置设置。从MongoDB3.4开始必须将配置服务器部署为副本集(CSRS)。
分片集群架构目标
先搭建路由节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6WscgrY-1637635433013)(/Users/liuben/Library/Application Support/typora-user-images/截屏2021-11-22 上午10.40.05.png)]
https://blog.csdn.net/quanmaoluo5461/article/details/85164588
1.分片(存储)
2.config servers
3.mongos(路由)
路由命令
(1)添加分片:
语法:
sh.addShard("IP:Port")
将第一套副本集添加进来:
mongos>
sh.addShard("myshardrs01/localhost:27018,localhost:27118,localhost:27218")
#---------------查看分片状况情况
sh.status()
将第二套副本集添加进来:
mongos>
sh.addShard("myshardrs01/localhost:27318,localhost:27418,localhost:27518")
#---------------查看分片状况情况
sh.status()
(2)开启分片功能
sh.enableSharding(“库名”)、sh.shardCollection(“库名.集合名”,{“key”:1})
sh.enableSharding("")
(3)集合分片
对集合分片,必须使用sh.shardCollection()方法指定集合和分片键
语法:
sh.shardCollection(namespace,key,unique)
Parameter | Type | Description |
---|---|---|
namespace | string | 要(分片)共享对目标集合对命名空间,格式:. |
key | document | 用作分片键对所以规则文档。shard键决定MongoDB如何在shard之间分法文档。除非集合为空,否则索引必须在shard collection命令之前存在。如果集合为空,则MongoDB在对集合进行分片之前创建索引,前提是支持分片键的索引不存在。简单来说:由包含字段和该字段的索引遍历方向的文档组成。 |
unique | boolean | 当值为true,片键字段上会限制为确保是唯一索引,哈希策略片键不支持唯一索引,默认为false |
例如在articled库中的comment集合中,以nickname为键,以哈希策略来分片。
#-------------------------首先开启article库的分片功能
sh.enableSharding("articledb")sh.shardCollection("articledb.comment",{"nickname":"hashed"})
增加第二个路由节点:
和创建第一个节点的方式相同,开启服务后不需要再添加分配,会由配置服务自动同步。
MongoDB的安全认证
为了保障Mongodb的安全,可以采用以下方案:
1)使用心得端口,避免使用27017默认端口。
2)设置mongodb的网络环境。最好将mongodb部署到公司服务器内网,这样外网访问不到。公司内部使用vpn。
3)开启安全认证。认证要同时设置服务器之间的内部认证方式,同时设置客户端连接到集群的账号密码认证方式。
为了强制开启用户访问控制(用户验证),则需要在MongoDB实例启动的时候使用选项–auth或者在指定启动配置文件中添加auth=true。
角色与权限指的就是角色对资源的增删改查权限。
常用的内置角色:
- 数据库用户角色:read、readWrite
- 所有数据库用户角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
- 数据库管理角色:dbAdmin、dbOwner、userAdmin
- 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
- 备份恢复角色:backup、restore
- 超级用户角色:root
- 内部角色:system
角色说明:
角色 | 权限描述 |
---|---|
read | 可以读取数据库中任何数据。 |
readWrite | 可以读写所有数据库中任何数据,包括创建、重命名、删除集合 |
readAnyDatabase | 可以读取所有数据库中任何数据(除了数据库config和local之外) |
readWriteAnyDatabase | 可以读写所有数据库中任何数据(除了数据库config和local之外) |
userAdminAnyDatabase | 可以在指定数据库创建和修改用户(除了数据库config和local之外) |
dbAdminAnyDatabase | 可以读取任何数据库以及数据库进行清理、修改、压缩、获取统计信息、执行检查等操作(除了数据库config和local之外)。 |
dbAdmin | 可以读取指定数据库以及对数据库进行清理、修改、压缩、获取统计信息、执行检查等操作。 |
userAdmin | 可以指定数据库创建和修改用户 |
clusterAdmin | 可以对整个集群或数据库系统进行管理操作 |
backup | 备份MongoDB数据最小的权限 |
restore | 从备份文件中还原恢复MongoDB数据(处理system.profile集合)的权限 |
root | 超级账号,超级权限 |
单实例环境演示
关闭已经开启的服务
1.快速关闭
kill -2 54410 #通过进程编号关闭节点
如果一旦是因为数据损坏。需要进行以下操作:
1)删除lock文件。
rm -f /mongodb/single/data/db/*.lock
2)修复数据
/usr/local/mongodb/bin/mongod --repair --dbpath=/mongdb/single/data/db
2.标准关闭
通过mongo客户端中的shutdownServer命令来关闭。
mongo --port 27017 #客户端登录服务
use admin # 切换到admin库 ,内置的权限库
db.shutdownServer() #关闭服务
添加用户权限
>use admin
>db.createUser({user:"admin",pwd:"123456",roles:["root"]})>db.system.users.find() #查看已经创建了的用户的情况
>db.dropUser("admin") #删除用户
>db.changeUserPassword("root","123456") #修改密码>db.auth("admin","123456") #验证密码内容示例:
{user: "<name>",pwd: "<cleartext password>",customData: { <any information> },roles: [{ role: "<role>", db: "<database>" } | "<role>",...],authenticationRestrictions: [{clientSource: ["<IP>" | "<CIDR range>", ...]serverAddress: ["<IP>" | "<CIDR range>", ...]},...],mechanisms: [ "<SCRAM-SHA-1|SCRAM-SHA-256>", ... ],passwordDigestor: "<server|client>"
}
字段名称 | 字段类型 | 字段描述 |
---|---|---|
user | 字符串 | 用户名称 |
pwd | 字符串 | 用户密码 |
roles | 数据组 | 用户授予角色列表,可以是空 [] |
—role | 字符串 | 角色名称 |
—db | 字符串 | 授予权限的数据库 |
服务端开启认证和客户端连接登录
开启权限认证启动服务:
1.参数
mongod -f mongod.conf --auth
2.配置文件
securityauthorization: enable #开启授权认证
客户端登录:
>use admin #切换到指定的数据库在验证密码
>db.auth("admin","123456") #验证密码
副本集环境演示
1.关闭之前的副本集服务
2.通过主节点添加一个管理员账号
(前两步参照单实例环境演示)
3.创建副本集认证的key文件
3.1生成key文件
可以使用任意方法生成密钥文件
//演示openssl方式生成,并使用chmod来更改文件权限(仅为文件所有者读的权限)
[root@izwz94gb5cfw913042mfyxz ~]#openssl rand -base64 90 -out ./mongo.keyfile
[root@izwz94gb5cfw913042mfyxz ~]#chmod 400 ./mongo.keyfile
[root@izwz94gb5cfw913042mfyxz ~]#ll mongo.keyfile
所有的副本集必须要用同一份keyfile。一般是在一个机器生成拷贝到其他机器。切必须有读的权限。否则会出错。
一定要保证密钥文件一致,为了查找方便,建议每台机器都放在一个固定位置,放到和配置文件一起的目录。
[root@izwz94gb5cfw913042mfyxz ~]#cp keyfile文件位置 到其他副本集的位置
4.修改配置文件制定keyfile
分别编辑各自的mongod.conf文件
security:keyFile: 各自keyFile文件位置authorization: enable
5.重新启动副本集
6.在主节点上添加普通账号并登录
(注意:操作过程中记得使用rs.status()命令查看副本集是否健康)
分片集群环境演示
(还是使用keyFile)
开启安全认证的时候指定keyFile
Docker安装
Docker单点安装
1.下载mongo镜像
docker pull mongo
2.运行mongo容器
$ docker run -itd --name mongo -p 27017:27017 mongo --auth # --auth:需要密码才能访问容器服务。
3.docker ps 命令查看容器的运行信息
4.添加用户和设置密码,并且尝试连接。
$ docker exec -it mongo mongo admin
# 创建一个名为 admin,密码为 123456 的用户。
> db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
# 尝试使用上面创建的用户信息进行连接。
> db.auth('admin', '123456')
Docker安装mongodb副本集
1.下载mongo镜像
docker pull mongo
2.启动三个节点
docker run --name m0 -p 37017:27017 -d mongo --replSet "rs"docker run --name m1 -p 47017:27017 -d mongo --replSet "rs"docker run --name m2 -p 57017:27017 -d mongo --replSet "rs"
docker ps -a //查看启动的容器
3.连接任意一个节点,进行副本集配置
docker exec -it de242cc5fa5a /bin/bash #进入其中一个容器
mongo --host localhost --port 37017 #此处记得打开防火墙,localhost换成公网IP
4.进行副本集配置
var config={_id:"rs",members:[{_id:0,host:"localhost:37017"},{_id:1,host:"localhost:47017"},{_id:2,host:"localhost:57017"}
]};
rs.initiate(config)由原来的 > 变成了 rs:SECONDARY>
"ok" : 1,
5.查看副本集配置信息
rs:SECONDARY> rs.conf()
6.查看副本集状态
rs:SECONDARY> rs.status()
7.客户端工具连接
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eASk35E9-1637635433014)(/Users/liuben/Desktop/截屏2021-11-22 上午10.14.02.png)]
SpringBoot整合Mongodb
1.pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>
2.application.properties
#单机连接方式
#spring.data.mongodb.host=127.0.0.1
#spring.data.mongodb.database=articledb
#spring.data.mongodb.port=27017
#spring.data.mongodb.username=admin
#spring.data.mongodb.password=123456
#spring.data.mongodb.uri=mongodb://admin:123456@120.24.85.71:37017/articledb#集群连接方式
spring.data.mongodb.uri=mongodb://admin:123456@120.24.85.71:37017,120.24.85.71:47017,120.24.85.71:57017/articledb?connect=replicaSet&slaveOk=true&relicaSet=rs#分片连接方式
spring.data.mongodb.uri=mongodb://120.24.85.71:37017,120.24.85.71:47017/articledb
3.实体类注解
@Document(collation = "comment")
public class Comment implements Serializable {@Idprivate String id;private String content;private Date publishtime;// @Indexedprivate String userid;private String nickname;private LocalDateTime createdatetime;private Integer likenum;private Integer replynum;private String state;private String parentid;private String articleid;
4.dao层
//extends MongoRepository<Comment,String> Comment实体类类型,id的类型
public interface CommentRepository extends MongoRepository<Comment,String> {}
4.业务
//commentRepository和mongoTemplate都可以来进行业务操作
@Service
public class CommentServiceImpl implements CommentService {@Autowiredprivate CommentRepository commentRepository;//注入MongoTemplate@Autowiredprivate MongoTemplate mongoTemplate;}
MongoDB学习(接上文)相关推荐
- MongoDB学习笔记(入门)
MongoDB学习笔记(入门) 一.文档的注意事项: 1. 键值对是有序的,如:{ "name" : "stephen", "genda" ...
- MongoDB学习第一篇 --- Mac下使用HomeBrew安装MongoDB
2019独角兽企业重金招聘Python工程师标准>>> MongoDB学习第一篇 --- Mac下使用HomeBrew安装MongoDB 0.确保mac已经安装了HomeBrew ( ...
- MongoDB学习札记第六篇之主从复制
mongo系列文章请看http://www.codefrom.com/p/mongodb 环境准备: ubuntu12.0.4 mongodb3.0.3 主从复制是MongoDB中最常见的复制方式.这 ...
- Mongodb学习(安装篇): 在centos下的安装
安装篇 ###下载解压文件 [root@192 lamp]# wget http://fastdl.mongodb.org/linux/mongodb-linux-i686- 2.2.2.tgz ## ...
- MongoDB学习笔记【2】-- 试用
大部分内容根据MongoDB官方手册整理:http://docs.mongodb.org/manual/contents/ 查看数据库 [root@slayer ~]# mongo MongoDB s ...
- MongoDB学习笔记(四)使用Java进行实时监控与数据收集(空间使用量、连接数)
目录: MongoDB学习笔记(一)环境搭建与常用操作 MongoDB学习笔记(二)使用Java操作MongoDB MongoDB学习笔记(三)使用Spring Data操作MongoDB Mongo ...
- MongoDB学习路线
转载博客: 1.MongoDB学习笔记(一)MongoDB概述和安装 http://www.cnblogs.com/wupeiqi/archive/2013/05/12/3074478.html 2. ...
- MongoDB学习笔记(一) MongoDB介绍及安装
系列目录 MongoDB学习笔记(一) MongoDB介绍及安装 MongoDB学习笔记(二) 通过samus驱动实现基本数据操作 MongoDB学习笔记(三) 在MVC模式下通过Jq ...
- PHP操作MongoDB学习笔记
PHP操作MongoDB技術總結 <?php /** * PHP操作MongoDB学习笔记 */ //************************* //** 连接MongoDB数据库 ...
最新文章
- 网易10万+课程迅速刷屏又迅速被封:“违规”背后的思考
- 安装python性能检测工具line_profiler
- 18 FI配置-财务会计-向计算程序分配国家
- SQL2005 学记笔记(9)
- 一加9R国行版即将到来:搭载骁龙870 售价预计3K内
- 测视力距离5米还是3米_装B冷知识 | 小孔镜为什么可以提高视力?
- python3 tkinter 实现凯撒密码GUI界面
- 【codevs1576】最长严格上升子序列
- 超详细的Python安装和环境搭建教程
- 如何把视频和音频合并?手把手教你合并
- 学习日志day44(2021-09-08)(1、Ajax跨域操作 2、Ajax接收json数据 3、JQuery和Ajax 4、使用JavaScript模板简化操作)
- java 众数 中位数_什么是中位数、众数、平均数,今天终于弄明白
- Android 直播RTMP流
- SyntaxError :invalid syntax错误解决办法
- 计算机到金融大师,宽客人生:从物理学家到数量金融大师的传奇
- 海康威视监控,RSTP转m3u8展示在移动端网页
- 钱币的大小写转换,123 成一百二十三元整
- 学计算机专业有必要考一级,计算机一级有必要考吗?计算机一级难度怎么样?...
- 阿里云配置php mysql_阿里云Windows 2008一键安装包配置php web环境图文安装教程(IIS+Php+Mysql)...
- 使用js将HTML页面转成pdf