mongodb学习_01_相关概念基础知识

47次阅读
没有评论

共计 7071 个字符,预计需要花费 18 分钟才能阅读完成。

MongoDB学习记录

1 概述

MongoDB是一个基于分布式文件存储的NoSQL数据库,由C++编写。MongoDB使用BSON (Binary JSON)对象来存储,旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富,最像关系数据库的。


2 安装与启动

本次实践安装在CentOS7虚拟机上,采用的是离线安装的方式

  1. 官网下载相应版本的mongodb的tgz包。
  2. 上传至虚拟机,采用命令:tar -zxvf tgz包 -C 解压路径,解压重命名即可。
  3. 创建数据、日志目录,并修改其读写权限。
    • mkdir -p /usr/local/mongodb/data/db //数据目录
    • mkdir -p /usr/local/mongodb/logs //日志目录
    • touch /usr/local/mongodb/logs/mongodb.log //日志文件
  4. 启动mongodb,分为前台启动和后台启动
    • 前台启动:bin/mongod –dbpath /usr/local/mongodb/data/db/ –logpath /usr/local/mongodb/logs/mongodb.log –logappend –port 27017 –bind_ip 0.0.0.0 //dbpath指定数据文件路径,logpath指定日志文件路径,logappend代表追加日志,port代表端口,默认27017,bind_ip默认只有本机可以访问。
    • 后台启动:在前台的命令后添加”–fork”(一般不推荐),当然也可以采用配置文件方式启动。
      • 新建配置文件 vim bin/mongodb.conf
      • 将如下内容放入配置文件中
        #数据文件存放目录
        dbpath = /usr/local/mongodb/data/db
        # 日志文件存放目录
        logpath = /usr/local/mongodb/logs/mongodb.log
        #以追加的方式记录日志
        logappend = true
        #端口默认为27017
        port = 27017
        #对访问IP地址不做限制,默认为本机地址
        bind_ip = 0.0.o.0
        #以守护进程的方式启用,即在后台运行
        fork = true
        
      • 启动命令变为:bin/mongod -f bin/mongodb.conf
      • 关闭命令变为:bin/mongod -f bin/mongodb.conf –shutdown
  5. 可以通过 bin/mongo 来测试是否启动,mongo是它提供的一个shell客户端
  6. 配置环境变量:
    • vim /etc/profile
    • 加入如下命令:
      export MONGODB_HOME=/usr/local/mongodb
      # Path后追加 ":$MONGO_HOME/bin"
      
    • source /etc/profile //使环境变量生效

3 基本使用

3.1 MongoDB用户与权限管理

3.1.1 常用权限

  • read/readAnyDatabase //允许用户读取指定数据库,加上AnyDatabase就需要在Admin数据库中定义,代表可以读取所有数据库,其他类似
  • readWrite/readWriteAnyDatabase //允许用户读写指定数据库
  • userAdmin/userAdminAnyDatabase //允许用户向system.users集合写入,可以在指定数据库里创建、删除和管理用户。
  • dbAdmin/dbAdminAnyDatabase //允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile。
  • clusterAdmin //必须在admin数据库中定义,赋予用户所有分片和复制集相关函数的管理权限。
  • root //必须在admin数据库中定义,超级权限。

3.1.2 创建管理用户

打开mongo shell客户端

  1. use admin //切换到admin数据库
  2. show users //查看admin数据库中的所有用户信息
  3. db.createUser({用户信息}) //根据用户信息创建用户

开启用户认证

  1. 编辑2中配置文件bin/mongodb.conf
  2. 加入一行 ” auth = true”

开始认证

  1. 重新启动mongod
  2. 打开mongo客户端,use admin切换到admin库
  3. db.auth(“用户名”,”密码”) //登录认证,返回1认证成功 0失败

3.1.3 创建普通用户

  1. 普通用户需要由管理员用户创建,先登录管理员用户。
  2. 创建数据库,Mongodb没有提供专门的创建数据库的函数,使用 use 数据库 的命令,如果数据库不存在,则创建并切换。

3.1.4 更新用户

如果需要对已存在的用户进行角色修改,可以使用 db.updateUser() 函数来更新用户角色。

  • db.updateUser(“用户名”,{“roles”:[ {“role”:”角色名称”,db:”数据库”},{“更新项2″:”更新内容”}]})

修改用户密码:

  • 使用db.updateUser(“用户名”,{“pwd”:”新密码”})函数
  • 使用db.changeUserPassword(“用户名”,”新密码”)函数

注意:更新用户信息以及密码需要当前用户具有userAdminuserAdminAnyDatabseroot 角色。

3.1.5 删除用户

通过db.dropUser()函数可以删除指定用户,删除成功以后会返回true。删除用户时需要切换到该用户所在的数据库。

注意:删除用户信息以及密码需要当前用户具有userAdminuserAdminAnyDatabseroot 角色。

3.2 GUI可视化管理工具

  • studio 3T这是官方合作伙伴 下载地址,付费版提供了SQL转mongodb命令的功能,可以提供给不会写mongodb命令的用户。
  • MongoDB Compass 官方的工具

使用可视化工具连接时,连接不上虚拟机,telnet也不能连接27017端口,需要关闭centOS防火墙 systemctl stop firewalld

3.3 数据库操作

  1. show dbs //查看数据库
  2. db //查看当前数据库
  3. use 数据库名 //创建数据库,懒创建的方式,没有数据就不会创建。
  4. db.dropDatabase() //删除数据库,需要写换到数据库才能删除

3.4 集合操作

集合相当于关系型数据库的表。

  1. db.createCollection(集合名,可选参数) //创建集合,插入文档时会自动创建集合
  2. show collections //查看集合
  3. db.集合名.drop() //删除集合

3.5 文档操作

  1. db.集合名.insert(文档) //插入文档,索引是”_id”,也可以批量插入
  2. db.集合名.save(文档) //如果不指定”_id”字段,相当于插入,如果指定了,相当于更新操作,也可以批量插入
  3. db.集合名.update(query,update,options) //query是查询条件,类似sql中的where,update类似sql中的set部分,可选参数options。
  4. db.集合名.remove(query,<justOne, boolean>) //query是查询条件,justOne为true删除查到的全部文档,为false删除第一条。还有deleteOne、deleteMany等函数
  5. db.集合名.find(查询条件) //查询文档

此外mongodb还提供了索引和聚合等功能。


4 和MySQL的区别

  1. MongoDB是非关系型数据库,MySQL是关系型数据库
  2. MongoDB存储方式采用虚拟内存和持久化,MySQL不同引擎有不同的存储方式。
  3. MongoDB有独特的查询方式,MYSQL采用SQL语言,使用广泛
  4. MongoDB数据是放在磁盘上的,热数据是放在内存,从而达到高速读写。

可以和MySQL搭配使用,可以像redis一样搭配MySQL做缓存db,可以替代MySQL做后端数据库,而redis不能。从性能上来说,redis>mongodb>mysql,不过这是在内存充足的情况下,如果内存不足redis显然不能完成任务,因此在处理海量数据时,mongoDB是一个不错的选择。

5 总结

  • mongodb是一种NoSQL数据库,它能保证海量数据存储的情况,保证性能。
  • mongodb的所有数据实际上是存放在硬盘的,所有要操作的数据通过mmap的方式映射到内存某个区域内。

高级部分

6 mongoDB复制集

primary(主)和secondary(从)

  1. 复制集目的为了实现服务的高可用,类似redis的主从复制,可以实现如下功能
    • 数据分发,减少数据响应时间
    • 读写分离
    • 容灾恢复
  2. 选举:类似redis的哨兵模式
    • 复制集最多有50个节点,但具有投票权的最多7个。
    • 具有投票权的节点会通过心跳保持联系
    • 如果主节点失联,则会通过投票选出主节点
  3. 复制过程:将操作日志oplog记录,从节点,将主节点的oplog重新执行。
  4. 复制集节点的常见配置项:
    • 是否具有投票权(v参数):有则参与投票;
    • 优先级(priority 参数):优先级越高的节点越优先成为主节点。优先级为0的节点无法成为主节点;
    • 隐藏(hidden参数):复制数据,但对应用不可见。隐藏节点可以具有投票权,但优先级必须为0;
    • 延迟(slaveDelay 参数):复制n秒之前的数据,保持与主节点的时间差。设置延迟节点,可以恢复误删主节点数据等操作。

增加从节点并不会增加系统写性能!

  1. 新增复制集:
    • rs.initiate() //初始化,连续两次回车就可以成为主节点
    • rs.status() //查看复制集状态
    • rs.secondaryOk() //设置从节点可读
    • rs.add() //新增复制集

7 JSON文档模型和关系模型

  1. 模型设计层次:关系模型包含概念模型、逻辑模型、物理模型,JSON文档模型只包含概念模型、逻辑模型。
  2. 从模型实体来看,JSON文档模型是集合,关系模型是表
  3. 从属性来看,JSON文档模型是字段,关系模型是列
  4. 从模型关系来看,JSON文档模型是用内嵌数组、引用字段来表示关系,关系模型是用关联关系、主外键来表示。

什么时候采用引用而不是内嵌文档:

  1. 内嵌文档太大,数MB或超过16MB
  2. 内嵌文档或数组频繁更改
  3. 内嵌数组元素持续增长并且没有封顶

mongodb引用的限制:

  1. MongodB对使用引用的集合之间并无主外键检查
  2. MongoDB使用聚合框架的$lookup 来模仿关联查询
  3. $lookup只支持left out join
  4. $lookup的关联目标(from)不能是分片表

8 MongoDB设计模式

一个好的设计模式可以显著提升数据读写效率、降低资源的需求。

  1. 问题:对于时序数据,大数据量存储。解决方案:分桶设计模式:对于时序数据,采用内嵌数组,讲一个时间段内的数据聚合到一个文档里,可以大量减少数据量、索引数量。
  2. 问题:解决大文档,很多字段、很多索引的问题。解决方案:列转行,通过将文档的字段转化为数组,一个索引解决查询问题。
  3. 问题:模型灵活,如何管理文档多个版本?解决方案:新增版本字段。可以快速过滤不需要升级的版本等。
  4. 问题:统计网页点击流量,没访问一个页面都要进行一次数据库计数更新操作,但是对精确度要求不高。解决方案:近似计算。例如每十次更新一次,减小10倍的写入数量。
  5. 问题:业绩排名,游戏排名等精确统计。消耗资源多,聚合计算时间长。解决方案:使用预聚合字段,每次更新数据,同时更新统计字段。

9 MongoDB事务

9.1 什么是writeConcern

writeConcern决定一个写操作落到多少个节点上才算成功。writeConcern 的取值包括:

  • 0:发起写操作,不关心是否成功;
  • 1~集群最大数据节点数:写操作需要被复制到指定节点数才算成功;
  • majority:写操作需要被复制到大多数节点上才算成功。这样可以防止丢数据的情况。

发起写操作的程序将阻塞到写操作到达指定的节点数为止 使用方式:db.test.insert ( {count:1}, {writeConcern: {w:”majority”}})

注意事项:

  • 虽然多于半数的 writeConcern 都是安全的,但通常只会设置majority,因为这是等待写入延迟时间最短的选择;
  • 不要设置 writeConcern等于总节点数,因为一旦有一个节点故障,所有写操作都将失败;
  • writeConcern虽然会增加写操作延迟时间,但并不会显著增加集群压力,因此无论是否等待,写操作最终都会复制到所有节点上。设置 writeConcern只是让写操作等待复制后再返回而已;
  • 应对重要数据应用{w: “majority”},普通数据可以应用{w:1}以确保最佳性能。

9.2 读事务

  • 从哪儿读?数据节点位置->readPreference解决
  • 什么样的数据可以读?隔离性->readConcern解决
  • readPreference:决定使用哪一个节点来满足正在发起的读请求。可选值包括:
    • primary:只选择主节点,默认;
    • primaryPreferred:优先选择主节点,如果不可用则选择从节点;
    • secondary:只选择从节点;
    • secondaryPreferred:优先选择从节点,如果从节点不可用则选择主节点;
    • nearest:选择最近的节点;
  • readConcern:在readPreference选择了指定的节点后,readConcern决定这个节点上的数据哪些是可读的,类似于关系数据库的隔离级别。可选值包括:
    • available:读取所有可用的数据;
    • local:读取所有可用且属于当前分片的数据;(常用)
    • majority:读取在大多数节点上提交完成的数据;(常用) //不会发生脏读
    • linearizable:可线性化读取文档,只读取大多数节点确认过的数据,因此可能读的会很慢。
    • snapshot: 读取最近快照中的数据;不会出现脏读、不可重复读、幻读,所有读使用同一快照,直到事务提交才释放。

10 Change Stream 变更流

是实现变更跟踪的解决方案,类似关系型数据库的触发器,但原理不同。 需要在配置文件中开启 enableMajorityreadConcern true

  • Change Stream依赖于oplog实现
  • 关系型数据库触发器是同步的,也就是在事务中事件发生了去做什么,属于同一个事务,触发器可以被认为是一个隐式的嵌套事务。嵌套在引发它的事务中。而Change Stream这个是异步的,也就是在事件发生后才去执行。
  • Change Stream当发生故障时,从上次断点重新触发,而关系型数据库会事务回滚。、

使用场景:

  • 跨集群的变更复制,在源集群订阅changeStream,一旦得到任何变更就写入目标集群
  • 微服务联动,例如微服务检测数据库变更,就做出操作

示例:db.collection.watch([],{maxAwaitTimeMS:30000}) //监听集合,最多阻塞等待30000毫秒


11 分片集群

分片集群横向扩展,提升性能。

  • 路由节点mongos:提供集群的单一入口,转发应用端请求,选择合适的数据节点进行读写,合并数据节点返回的数据,建议多个,实现高可用。
  • 配置节点config:提供集群元数据的存储,分片数据分布的映射。多个配置节点,采用复制集实现,实现高可用。
  • 数据节点shard:一个分片一个复制集,以复制集为单位,横向扩展,最多1024个分片,分片之间数据不重复,必须所有分片完整才能使用。

三种分片方式:

  1. 基于范围:正对某一个键值的范围进行分片,数据分布不均匀,容易有热点写,就是最新写入的数据,可能总是写入一个分片,但是范围查询效率高。
  2. 基于Hash:采用hash进行分片,这样的话数据分布均匀,写效率高,但是范围查询效率低。适用:日志、物联网等高并发场景。
  3. 基于zone/tag:自定义zone,可以按照地域来分片,适用:跨地域,多中心的部署。

分片集群可以有效解决系统性能瓶颈和系统扩容问题,但是消耗较大,管理复杂。 数据量大于2TB考虑分片。如果分片资源占用60%以上就需要考虑扩展了。

12 Mongodb备份与恢复

12.1 备份机制

MongoDB的备份机制分为:

  • 延迟节点备份:复制集slavedelay参数实现。
  • 全量备份 + oplog增量备份(任意时间点备份和恢复) 最常见的全量备份操作:
  • mongodump (比较常用)
  • 复制数据文件 (需要暂停从节点)
  • 文件系统快照

12.2 备份和恢复工具

备份和恢复工具参数:

  • mongodump:备份工具
    • –oplog:复制mongodump从开始到结束过程中的所有oplog到结果中,保存在dump/oplog.bson
  • mongorestore:恢复工具
    • –oplogRelay:恢复完数据再重放oplog,默认重放dump/oplog.bson。
    • –oplogFile:指定需要重放的oplog文件位置
    • –oplogLimit:重放optlog截止到指定时间点

12.3 分片集的备份

分片集的备份比复制集复杂,因为需要考虑

  1. 分片集各分片之间的数据迁移chunk,取决于config上的元数据,如果实际数据已经迁移到新分片,然而config依然以为数据在旧分片上,就会出现不一致的问题,
  2. 分片集的备份还需要考虑config配置节点的备份
  3. 由于多个分片集时间难以一致,很难完全恢复到同一个时间点上。

需要解决上面的问题,需要将均衡器停止,不让数据在分片间迁移,这样增量备份和恢复才能保证正确,

13 索引

  • 单值索引
  • 组合索引原则:ESR,
    • 精确(Equal)匹配的字段放最前面
    • 排序(Sort)条件放中间
    • 范围(Range)匹配的字段放最后面
正文完
 
landery
版权声明:本站原创文章,由 landery 2023-03-07发表,共计7071字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)