目录

MongoDB简介

  • ​ 体系结构

    • 关系型数据库
      • 库 表 行
    • MongoDB
      • 库 集合 文档
  • 数据模型

    • MongoDB的最小存储单位就是文档(document)对象。文档(document)对象对应关系型数据库的行。数据在MongoDB中以BSON(Binary-JSON)文档的格式存储在磁盘上。BSON(Binary Serialized DocumentFormat)是一种类json的一种二进制形式的存储格式,简称BinaryJSON。

    • BSON和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。

    • BSON采用了类似于 C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的三个特点,可以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想。

    • Bson中,除了基本的JSON类型:string,integer,boolean,double,null,array和object,mongo还使用了特殊的数据类型。这些类型包括date,object id,binary data,regular expression 和code。每一个驱动都以特定语言的方式实现了这些类型,查看你的驱动的文档来获取详细信息。

    • 下表为MongoDB中常用的几种数据类型。:

      • 数据类型描述String字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
      • Integer整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
      • Boolean布尔值。用于存储布尔值(真/假)。
      • Double双精度浮点值。用于存储浮点值。
      • Min/Max keys将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
      • Array用于将数组或列表或多个值存储为一个键。
      • Timestamp时间戳。记录文档修改或添加的具体时间。
      • Object用于内嵌文档。
      • Null用于创建空值。
      • Symbol符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言Date日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
      • Object ID对象 ID。用于创建文档的 ID。
      • Binary Data二进制数据。用于存储二进制数据。
      • Code代码类型。用于在文档中存储 JavaScript 代码。
      • Regular expression正则表达式类型。用于存储正则表达式。
  • 特点 (三高)

    • 高性能
      • MongoDB提供高性能的数据持久性。特别是:对嵌入式数据模型的支持减少了数据库系统上的I/O活动。
      • 索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。(文本索引解决搜索的需求、TTL索引解决历史数据自动过期的需求、地理位置索引可用于构建各种 O2O 应用)mmapv1、wiredtiger、mongorocks(rocksdb)、in-memory 等多引擎支持满足各种场景需求。
      • Gridfs解决文件存储的需求
    • 高可用
      • MongoDB的复制工具称为复制集(replica set),它可提供自动故障转移和数据冗余。支持2-50个成员,一边建议3个左右自动恢复多中心容灾能力
    • 高可扩展
      • MongoDB提供了水平可扩展性作为其核心功能的一部分。
      • 分片将数据分布在一组集群的机器上。(海量数据存储,服务能力水平扩展) 从3.4开始,MongoDB支持基于片键创建数据区域。在一个平衡的集群中,MongoDB将一个区域所覆盖的读写只定向到该区域内的那些片。轻松支持TB-PB数量级别
  • 丰富的查询支持

    • MongoDB支持丰富的查询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等。
  • 其他特点

    • 如无模式(动态模式)、灵活的文档模型、

使用场景

  • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新
  • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
  • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
  • 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
  • 视频直播,使用 MongoDB 存储用户信息、礼物信息等
  • 价值低的数据,对事物要求不高,比如银行转账业务,就不适合

技术选型依据

  1. 应用不需要事务及复杂 join 支持
  2. 新应用,需求会变,数据模型无法确定,想快速迭代开发
  3. 应用需要2000-3000以上的读写QPS(更高也可以)
  4. 应用需要TB甚至 PB 级别数据存储
  5. 应用发展迅速,需要能快速水平扩展
  6. 应用要求存储的数据不丢失
  7. 应用需要99.999%高可用
  8. 应用需要大量的地理位置查询、文本查询

安装

  1. 版本的选择: MongoDB的版本命名规范如:x.y.z; y为奇数时表示当前版本为开发版,如:1.5.2、4.1.13; y为偶数时表示当前版本为稳定版,如:1.6.3、4.0.10; z是修正版本号,数字越大越好
  2. 进入linux 服务器 创建目录 mkdir -p /mongodb/data mkdir -p /mongodb/logs mkdir -p /mongodb/conf
  3. wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.1.tgz
  4. 解压文件 tar -zxvf tar -zxvf mongodb-linux-x86_64-rhel70-4.4.1.tgz
  5. 修改配置文件
vim  conf/mongod.conf

systemLog:
   #MongoDB发送所有日志输出的目标指定为文件
   destination: file
   #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
   path: "/opt/mongodb-4.4.1/logs/mongo.log"
   #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
   logAppend: true
storage:
   dbPath: "/opt/mongodb-4.4.1/data"
   journal:
      #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
      enabled: true
processManagement:
   #启用在后台运行mongos或mongod进程的守护进程模式。
   fork: true
   pidFilePath: "/opt/mongodb-4.4.1/logs/mongod.pid"
net:
   #服务实例绑定的IP,0.0.0.0,任何IP都可以访问
   bindIp: 0.0.0.0
   port: 27017
export PATH=$PATH:/mongodb/path/to/mongod.conf

启动mongodb服务  mongod --config /mongodb/conf/mongod.conf

连接  mongo --host=127.0.0.1 --port=27017
		 show databases

关闭
	1-命令窗口 use admin 
	1. 执行db.shutdownServer() 
	2.  mongod --config /usr/local/mongodb/conf/mongodb.conf --shutdown连接工具  MongoDBCompass 官方提供(免费)
  1. 客户端工具连接 MongoDBCompass 官方提供(免费)
  2. 导出 mongodump -h dbhost -d dbname -o dbdirectory
  3. 导入 mongorestore -h localhost:27017 -d daname --dir 指定备份的目录

数据库操作

  • 创建 use 数据库名称
  • 查看 db命令用于查看当前操作的数据库,MongoDB默认链接的是test数据库,如果没有选择其他数据库,集合默认存放在test数据库中。如果想查看所有数据库,可以使用show dbs命令: 注意:在mongdb中,数据库/集合只有在内容插入后才会真正创建。
  • 删除 use 进去 db.dropDatabase() show dbs
  • 修复数据 mongod --repair --dbpath=/mongodb/data

集合操作

  • ​ 创建
    • db.createCollection(name) --name 要创建的集合名称
    • db.createCollection("user")
    • 隐士 db..insert({name:"23123"})
  • 删除 db.集合.drop()
  • 查看 show collections

文档操作 https://docs.mongodb.com/manual/crud/

  • 新增 语法格式:
    • db.<集合>.insert()db.<集合>.insertOne()
    • db.<集合>.save() 示例:db.shop.save({name:"家电",price:4000})
      • 如果能根据_id找到一个已经存在的文档,那么就更新。如果没有传入_id参数或者找不到存在的文档,那么就插入一个新文档。
    • 多个文档 语法格式 db.<集合>.insertMany([,,....]) 示例:db.shop.insertMany([{name:"手机",price:3000},{name:"电脑",price:6000},{name:"日用百货",price:50}])
  • 查询 通用查询语法格式:
    • db.shop.find({}) 查询所有
    • db.shop.find({"name":"手机","price":3000}) //多条件查询,相当于 sql and
    • 查询db.shop.find({$and:[{"name":"手机"},{"price":3000}]}) //多条件查询
    • db.shop.find({$or:[{"name":"手机"},{"price":4000}]})//多条件or查询,相当于sql or
    • db.shop.find({"name":/^手/}) //正则表达式查询
      • 查询条件对照表:SQLMongoDBa=1单属性字段完全匹配
      • a<>1{a:{$ne:1}} $ne:不存在或者存在但不等于
      • a>1{a:{$gt:1}}$gt:存在并大于
      • a>=1{a:{$gte:1}}$gt:存在并大于等于
      • a<1{a:{$lt:1}}$lt:存在并小于
      • a<=1{a:{$lte:1}}$lte:存在并小于
      • 等于a=1 AND b=1{a:1,b:1} 或者{$and:[,]}$and:匹配全部条件
      • a=1 OR b=1{$or:[,]}$or:匹配两个或多个条件中的一个a
      • is NULL{a:{$exists:false}} $exists:true/$exists:false,是否为空
      • a in(1,2,3){a:{$in:[1,2,3]}}$in:存在并在指定数组中
      • a not in(1,2,3){a:{$nin:[1,2,3]}}$nin:不存在或不在指定数组中
      • a like '%中%' {a:/中/}mongodb通过正则实现模糊搜索
      • find搜索子文档MongoDB鼓励内嵌文档,实现关联查询示例:
      • insert db.shop.insert({name:"电脑",category:{name:"联想",cpu:"i7"}})
      • find db.shop.find({"category.name":"联想"})
      • 正确思考:区分 db.shop.find({"category":{"name":"联想"}})--
      • 错误 find搜索数组find支持对数组中的元素进行搜索示例:
      • insert db.shop.insert([{name:"联想",cpu:["i5","i7"]},{name:"戴尔",cpu:["i3","i7"]}])
      • find db.shop.find({cpu:"i5"}) db.shop.find({$or:[{cpu:"i5"},{cpu:"i3"}]})
      • find搜索数组中的对象示例:insert db.shop.insert({name:"手机",brand:[{name:"华为",price:4000},{name:"小米",price:3000},{name:"苹果",price:8000}]})
      • find db.shop.find({"brand.name":"华为"}) find 投影(projection)
      • 查询如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。 id字段必须明确指出不返回,否则每次默认返回 示例:db.shop.find({},{"name":1})
  • 删除
    • 语法格式: db..remove()
    • 示例:db.shop.remove({name:"手机"}) //删除name=手机的记录
    • db.shop.remove({price:{$lte:3000}}) //删除price<=3000的记录数
    • db.shop.remove({}) //删除所有记录
    • db.shop.remove() //报错
  • 更新
  • 聚合
    • 聚合框架(Aggregation) 聚合操作处理数据记录并返回计算结果。
    • 聚合操作将多个文档中的值分组在一起,并可以对分组后的数据进行各种操作,以返回一个结果。
    • MongoDB提供了三种执行聚合的方法:

副本集

  • 简介 :MongoDB中的副本集是一组维护相同数据集的mongod进程。复制集提供冗余和高可用性,是所有生产部署的基础。 目的-冗余和数据可用性复制提供了冗余,提高了数据的可用性。由于在不同的数据库服务器上有多个数据副本,复制提供了一定程度的容错能力,防止单个数据库服务器的损失。 在某些情况下,复制可以提供更高的读取能力,因为客户端可以向不同的服务器发送读取操作。在不同的数据中心维护数据副本可以提高分布式应用的数据定位和可用性。您还可以为专用目的维护额外的副本,如灾难恢复、备份。总结起来:高可用数据分发读写分离-提升读的能力(千万别记错,写能力,不仅没升,反而有些下降)灾难恢复

  • 副本集部署架构

    • 复制集是一组维护相同数据集的mongod实例。
    • 一个复制集包含几个数据承载节点和可选的一个仲裁器节点。
    • 在数据承载节点中,一个且仅有一个成员被视为主节点,而其他节点被视为从节点。
    • 一个副本集最多可以有50个成员,但只有7个投票成员。
    • 副本集必须有一个主节点只有主节点能写数据,所有节点都能读取数据,但默认数据只从主节点读取,从节点不读取,可配置Read Preference更改不推荐使用投票节点(Arbiter) 主节点(Primary)主节点接收所有的写操作。
    • 一个副本集只能有一个主节点,primary将其数据集的所有变化记录在其操作日志中,即oplog。
    • 从节点(Secondary)从节点复制主数据的oplog,并将操作应用于它们的数据集。
    • 如果主节点不可用,符合条件的从节点进行选举,产生新的主节点。
    • 仲裁节点(Arbiter)在某些情况下(例如只有一个主节点和一个从节点,但由于成本限制而无法再增加一个从节点),可以选择将一个 mongod 实例作为仲裁者添加到副本集中。
    • 仲裁者参与选举,但不持有数据(即不提供数据冗余)。
    • Oplog(operations log)是一个特殊的集合,记录所有的对于修改数据库(新增,修改,删除)的行为日志,这些日志,被称为Oplog MongoDB在主节点上应用数据库的操作,然后记录到oplog上,其他从节点通过异步的方式复制这些日志,所有从节点都包含主节点oplog的副本 为了方便复制,所有副本集成员,都会向所有其他成员发送心跳(ping).任何从节点,都可以从其他成员哪里导入oplog日志
    • oplog操作是幂等的,也就是说,oplog作用在目标数据库上的行为,不管是一次还是多次,效果都一样 oplog日志是有大小的,默认是物理磁盘的5%
    • 通过如下命令可以查看当前集群oplog的大小rs.printSlaveReplicationInfo()通常情况下,oplog增长速度等同于主节点插入新文档速度,一但超过阈值大小,旧的日志会被覆盖,所以一般情况下,oplog日志的大小要足够24小时新增的数量,一般都是保证72小时。如果出现从节点无法同步主节点oplog情况,可以考虑手动同步数据。mongodb提供两种数据同步策略 1-全量,新节点加入 2-初始化后的所有复制同步,都是非全量的,保证每个oplog是一样的文件
  • 数据同步

    • 为了保持副本集的数据实时同步,从节点从其他成员哪里同步数据,MongoDB提供了两种数据同步方式:
    • 初始同步,复制全量的数据从副本集当中的另一个成员哪里
    • 复制: 从节点在初始同步后连续复制数据。从节点会复制oplog操作并恢复数据从提供源数据的节点 根据ping时间和其他成员复制状态的更改,从节点可以根据需要自动更改其源的同步
  • 选举机制

    • 选举机制保证故障恢复 具有投票权的节点之间两两互相发送心跳,当5次心跳未收到时判断为节点失联,如果主节点失联,从节点会发起选举,选出新的主节点。如果从节点失联,不发生新的选举。

    • 选举算法:RAFT一致性算法。成功的必要条件是大多数投票节点存活。副本集中最多可以有50个节点,但具有投票权的节点最多7个。

    • 影响选举结果的因素:整个集群必须有大多数节点存活,被选举为主节点的节点条件:

    • 能够与多数节点建立连接 具有较新的oplog

    • 具有较高的优先级容错率成员数量 选举需要的大多数数量。默认容错数量321431532642添加成员不能总是提高容错率,只是添加的成员有额外的功能和目的

    • case:假如说;四个节点的副本集;其他选项一般情况下,搭建副本集的时候,可以不用额外的配置,如果想搭建更复杂高级的副本集,可以参考如下配置:

    • 是否具有投票权(参数:v):有则参与投票

    • 优先级(参数:priority):数字类型,数值越大,优先级越大,越容易成为主节点

    • 隐藏(参数:hidden):复制数据,但对应用不可见。隐藏节点可以具有投票权,但优先级必须为0

    • 延迟(参数:slaveDelay):复制n秒之前的数据。

    • 注意事项任何一个从节点都有可能成为主节点,所以硬件配置应该一样,以防止从节点升级主节点后,扛不住压力各个节点应该保证不会同时宕机,一般多机房多中心部署,即硬件环境需要隔离副本集当中MongoDB版本必须一致,防止不可预知的问题发生增加节点,不会增加系统写性能,从节点,主要用于备份,容灾,增加读性能等

    • 典型架构 一主二从,不建议仲裁节点

副本集环境创建

1.环境准备 linux centos7  MongoDB版本4.4.1
2.目标:同一台机器上搭建一主二从的副本集(端口号不一样)
3.创建副本集目录-操作
	mkdir -p /mongodb/db28017/data
	mkdir -p /mongodb/db28017/conf
	mkdir -p /mongodb/db28017/logs 
	mkdir -p /mongodb/db28018/data
	mkdir -p /mongodb/db28018/conf
	mkdir -p /mongodb/db28018/logs 
	mkdir -p /mongodb/db28019/data
	mkdir -p /mongodb/db28019/conf
	mkdir -p /mongodb/db28019/logs 
	说明-备注生产环境,副本集当中的每个成员,一定要是独立的mongodb进程,实验中为了模拟,在同一台机器上操作,那么就要求,每个进程独立启动   独立的配置文件 
	端口  28017/28018/28019
	数据目录      
			/mongodb/db28017/data      
			/mongodb/db28018/data      
			/mongodb/db28019/data
	启动的配置文件 
			/mongodb/db28017/conf/mongod.conf      
			/mongodb/db28018/conf/mongod.conf            
			/mongodb/db28019/conf/mongod.conf
	日志路径       
			/mongodb/db28017/logs      
			/mongodb/db28018/logs      
			/mongodb/db28019/logs  
4.创建配置文件-操作
		vi /mongodb/db28017/conf/mongod.conf
		vi /mongodb/db28018/conf/mongod.conf
		vi /mongodb/db28019/conf/mongod.conf 
5. 配置参考下一个节点配置:只需添加如下配置即可
	 replication:  
	    replSetName: rs0 
6. 启动-操作
	 mongod -f /mongodb/db28017/conf/mongod.conf
	 mongod -f /mongodb/db28018/conf/mongod.conf
	 mongod -f /mongodb/db28019/conf/mongod.conf 
7.配置集群-操作主节点:
rs.initiate() 
rs.add("192.168.254.210:28018")
rs.add("192.168.254.210:28019")
rs.status()
可看见集群环境已经搭建完成测试:主节点写入数据,查看从节点是否能读取到 

配置文件
systemLog:
   destination: file
   path: "/opt/mongodb-4.4.1/logs/{端口}/mongo.log"
   logAppend: true
storage:
   dbPath: "/opt/mongodb-4.4.1/{端口}/data"
   journal:
      enabled: true
processManagement:
   fork: true
   pidFilePath: "/opt/mongodb-4.4.1/logs/{端口}/mongod.pid"
net:
   bindIp: 0.0.0.0
   port: 27017{端口}
replication:  
   replSetName: rs0

副本集配置

​ 副本集配置-操作 主节点操作

​ conf =rs.conf()

​ conf.members[0].priority=2

​ rs.reconfig(conf)

​ 几秒钟之后,重新选举

生产必备

https://docs.mongodb.com/v5.0/

mongo_生产必备