一、 Mongodb 再入门
1. 什么是Nosql
NoSQL:Not Only SQL ,本质也是一种数据库的技术,相对于传统数据库技术,它不会遵循一些约束,比如:sql标准、ACID属性,表结构等。
优点:
满足对数据库的高并发读写
对海量数据的高效存储和访问
对数据库高扩展性和高可用性
灵活的数据结构,满足数据结构不固定的场景
缺点:
一般不支持事务
实现复杂SQL查询比较复杂
运维人员数据维护门槛较高
2. Mongodb 介绍
Mongodb的场景从电商、物联网、内容管理、社交等,方方面面。航空业、电信业都可以看到MongoDB的使用场景
JSON数据模型是采用JSON Document对象,比较适合面向对象的数据模型。
具有很强的横向扩展能力,可将大量数据放到一个分布式扩展的mongodb数据库。
Mongodb在4.0之后完全支持事务
企业版本包括图形管理和报表工具,需要付费
3. MongoDB 版本变迁
2007年google公司员工在美国纽约成立,初衷是要开发一个基础开发平台,大力降低开发者在基础功能上的精力,专注于核心功能的开发。这个平台存储用的是mongo,因为当时没有现成的数据库能支持云上的使用。后来发现大家都对mongo很感兴趣,反而对平台本身不感冒,所以在09年时,侧重点放到了mongodb上,
做为一个开源软件给大家使用。它最大的特色就是提供基于json的文档模型和基于json api的调用方式。
1.x时增加了复制集的概念,可以分成多个节点,支持分布式的部署,保证高可用。
2.x时增加了很多数据功能,之前主要是做数据存储用。包括聚合操作
3.x真正进入成熟阶段,整合一家专门做数据库引擎的WiredTiger公司。Mongodb之前是没有自己的数据库存储引擎的,只是利用操作系统的API来做。其性能在大批量操作时至少提升10倍。
4.x开始支持事务
4. MongoDB VS 关系型数据库
OLTP做前端交互式业务场景
OLAP做后端离线批处理分析业务场景
MQL:Mongo query language
在mongodb中是通过数据库、集合、文档的方式来管理数据,下边是mongodb与关系数据库的一些概念对比:****
1、一个mongodb实例可以创建多个数据库
2、一个数据库可以创建多个集合
3、一个集合可以包括多个文档。
5. MongoDB 使用场景
游戏场景:使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新
物流场景:使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
社交场景:使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
视频直播:使用 MongoDB 存储用户信息、礼物信息等
即时通讯: 存储聊天记录
6. 不适用MongoDB 场景
高度事务性系统:例如银行、财务等系统。MongoDB对事物的支持较弱;
传统的商业智能应用:特定问题的数据分析,多数据实体关联,涉及到复杂的、高度优化的查询方式;
使用sql方便的时候;数据结构相对固定,使用sql进行查询统计更加便利的时候;
二、 MongoDB 基本特性
1. 优势
1) 简单直观
以自然的方来来建模,以直观的方式来与数据交互
从关系模型到对象模型
一目了然的对象模型:与其用几十张表去表达表与表关系。可以直接用对象形式来表达。在有些场景下可以直接将对象模型当成mongodb的存储数据模型给mongodb进行管理。
2) 结构灵活
弹性模式从容响应需求的频繁变化
可以动态增加新字段
多形性:同一个集合中可以包含不同字段类型的文档对象。
动态性:线上修改数据模式,修改时应用与数据库均无需下线
数据治理:支持使用JSON Schema来规范数据模式,在保证模式灵活动态的前提下,提供数据治理能力。
3) 快速开发
做更多的事,写更少的代码。
在传统数据库中我们设计一个客户相关表
但是在mongodb中,我们可以如下设计
json模型快速特性:
数据库引擎只需要在一个存储区读写。
反范式、无关联的组织极大的优化查询速度。
通过mongodb提供的API,方便查询数据
1) 原生的高可用
应用程序通过Driver(类似于jdbc模块)可以连接到Primary主节点进行读写操作。
Replica Set由2-50个成员(默认3个,保证投票机制)
可以自动恢复
多中心容灾能力
滚动服务-最小化服务终端(mongodb版本的迭代升级不需要下线)
2) 横向扩展能力
通过分片集群实现,将数据通过水平方式扩展到N个分片,每个分片就是一个复制集。
需要时可以无限扩展
应用全透明,开发人员看到的是一个完整的逻辑数据库。
多种数据分布策略
轻松支持TB-PB数量级
3. 优势总结
面向集合文档的存储:适合存储Bson(json的扩展)形式的数据;
格式自由,数据格式不固定,生产环境下修改结构都可以不影响程序运行;
强大的查询语句,面向对象的查询语言,基本覆盖sql语言所有能力;
完整的索引支持,支持查询计划;
支持复制和自动故障转移;
支持二进制数据及大型对象(文件)的高效存储;
使用分片集群提升系统扩展性;
使用内存映射存储引擎,把磁盘的IO操作转换成为内存的操作;
三、 Mongo4.0 新特性
1. 跨文档ACID 事务
从单文档事务->跨文档事务
用户可以在同一个事务中对多个文档进行操作。
简单易用的事务API
2. 聚合数据类型转换
即使是同一个数据库集合,其中的文档格式也不一定统一。这种灵活的存储方式正是mongodb的一大优势,但是会给消费端在进行数据处理时的难度。在批量处理数据之前要统一数据格式,将不同类型数据转为同一类型数据。
mongodb4.0引入$convert聚合操作符用来在聚合管道中对聚合数据的转换。简化了ETL(数据抽取、转换、加载)的流程。同时将数据处理的负荷从客户端转移到服务器端。****
3. 修改订阅功能扩展
在3.6版本引入修改订阅功能,可以实时追踪文档各种操作(CRUD)。但该版本只支持数据库集合层面的修改订阅。如果要追踪多个集合或多个数据库中的文档操作就需要启动多个修改订阅,增加应用开发的复杂度。
4.0版本可以在数据库/集群层面引入修改订阅功能。只需要启动一个修改订阅就可以了。
为修改事件返回clusterTime属性,提供更加详细的事件信息。
4. 后备节点读取
后备节点读取从阻塞性读取变为非阻塞性读取。
阻塞性后备节点读取:
主节点在将数据复制给后备节点时,为提高效率,它是采用批量复制方式,并且并不一定按原来的顺序传递数据。如果客户端读取后备节点数据,而批量复制写入正进行到一半,后备节点的数据正处于无效状态,因为一个乱序的批量写入请求只有在全部完成之后才能保证数据的一致性。所以在后备节点的批量复制写入在没有完成请,客户端对后备节点读取的请求是会被阻塞的。
非阻塞性后备节点读取:
在一个批量数据复制写入请求之前,为数据库中的数据做一个快照,用来保留数据复制开始前数据的状态。这样即使是在数据批量复制写入的过程中,读取的请求也可以支持。只要从之前保存的快照中读取数据即可。
在任一时刻接受到的数据读写请求都可以及时处理,只要找到最新的快照。
四、 MongoDB 架构
1. MongoDB 逻辑结构
MongoDB 与 MySQL 中的架构相差不多,底层都使用了可插拔的存储引擎以满足用户的不同需要。用户可以根据程序的数据特征选择不同的存储引擎,在最新版本的 MongoDB 中使用了 WiredTiger 作为默认的存储引擎,WiredTiger 提供了不同粒度的并发控制和压缩机制,能够为不同种类的应用提供了最好的性能和存储率。
在存储引擎上层的就是 MongoDB 的数据模型和查询语言了,由于 MongoDB 对数据的存储与 RDBMS有较大的差异,所以创建了一套不同的数据模型和查询语言。
2. MongoDB 的数据模型
内嵌
内嵌的方式指的是把相关联的数据保存在同一个文档结构之中。MongoDB的文档结构允许一个字段或者一个数组内的值作为一个嵌套的文档
选择内嵌:
数据对象之间有包含关系 ,一般是数据对象之间有一对多或者一对一的关系。
需要经常一起读取的数据。
引用
引用方式通过存储数据引用信息来实现两个不同文档之间的关联,应用程序可以通过解析这些数据引用来访问相关数据
内嵌数据会导致很多数据的重复,且读性能的优势又不足于覆盖数据重复的弊端
需要表达比较复杂的多对多关系的时候
大型层次结果数据集 嵌套不要太深
3. MongoDB 存储引擎
1) wiredTiger
MongoDB从3.0开始引入可插拔存储引擎的概念。目前主要有MMAPV1、WiredTiger存储引擎可供选择。在3.2版本之前MMAPV1是默认的存储引擎,其采用linux操作系统内存映射技术,但一直饱受诟病;3.4以上版本默认的存储引擎是wiredTiger,相对于****MMAPV1 其有如下优势:
读写操作性能更好,WiredTiger能更好的发挥多核系统的处理能力;
MMAPV1引擎使用表级锁,当某个单表上有并发的操作,吞吐将受到限制。
WiredTiger使用文档级锁,由此带来并发及吞吐的提高
相比MMAPV1存储索引时WiredTiger使用前缀压缩,更节省对内存空间的损耗;
提供压缩算法,可以大大降低对硬盘资源的消耗,节省约60%以上的硬盘资源;
2) WT 写入原理
如果不用wt ,会直接写入缓存。使用wt 就可以使用Journaling 日志(起个线程每100 毫秒刷新日志)再结合写策略保证数据不会丢失。
Journaling类似于关系数据库中的事务日志。Journaling能够使MongoDB数据库由于意外故障后快速恢复。MongoDB2.4版本后默认开启了Journaling日志功能,mongod实例每次启动时都会检查journal日志文件看是否需要恢复。由于提交journal日志会产生写入阻塞,所以它对写入的操作有性能影响,但对于读没有影响。在生产环境中开启Journaling是很有必要的
3) 写策略解析
写策略配置:{ w: , j: , wtimeout: }
w: 数据写入到number 个节点才向用客户端确认
{w: 0} 对客户端的写入不需要发送任何确认,适用于性能要求高,但不关注正确性的场景
{w: 1} 默认的writeConcern,数据写入到Primary就向客户端发送确认
{w: “majority”} 数据写入到副本集大多数成员后向客户端发送确认,适用于对数据安全性要求比较高的场景,该选项会降低写入性能
j: 写入操作的journal 持久化后才向客户端确认
默认为{j: false},如果要求写入持久化了才向客户端确认,则指定该选项为true
wtimeout: 写入超时时间,仅w 的值大于1 时有效。
当指定{w: }时,数据需要成功写入number个节点才算成功,如果写入过程中有节点故障,可能导致这个条件一直不能满足,从而一直不能向客户端发送确认结果,针对这种情况,客户端可设置wtimeout选项来指定超时时间,当写入过程持续超过该时间仍未结束,则认为写入失败。
五、 安装(centos7)
1. 创建存储数据和日志的目录
mkdir -p /data /db
mkdir -p /data/logs
2. 下载
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.5.tgz
3. 解包
tar -zxvf mongodb-linux-x86_64-rhel70-6.0.5.tgz
4. 将安装包重命名为 mongodb 并拷贝到 /usr/local/ 目录
mv mongodb-linux-x86_64-rhel70-6.0.5 /usr/local/mongodb
5. 修改环境变量
因为 MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中,此后,在所有的路径下可以直接使用 MongoDB 的命令。
只对当前会话生效
export PATH=$PATH:/usr/local/mongodb/bin
永久生效
修改/etc/profile文件使其永久性生效,并对所有系统用户生效,在文件末尾加上
/etc/profile
export PATH=$PATH:/usr/local/mongodb/bin
6. 配置文件
vi /etc/mongod.conf
port=27017fork=true # 以创建子进程的方式运行dbpath=/data/db #日志输出方式数据库路径logappend=true #日志输出方式,日志append而不是overwritelogpath=/data/logs/mongo.log #日志路径auth=false#开启安全验证(可以不开启) |
---|
7. 运行服务
mongod --config /etc/mongod.conf
netstat -ntulp |grep 27017 //查看 MongoDB 服务是否启动成功
8. 启动 MongoDB shell
mongo
六、 安装测试数据
1. 下载测试数据
cd /data
curl -O -k
https://raw.githubusercontent.com/tapdata/geektime-mongodb-course/master/aggregation/dump.tar.gz
2. 解包
tar -xvf dump.tar.gz
3. 恢复数据
mongorestore -h localhost:27017
4. 基本操作数据库
show dbs
切换数据库
use mock
查看集合
show collections
查看数据
db.orders.findOne()
七、 MongoDB Compass
1. 下载
官方提供的免费 GUI 管理工具
● 数据管理(增删改查)
● Schema 管理
● 索引管理
● 性能排查
● 实时性能监控
2. 修改配置
没有指定bind_ip,会导致mongodb默认绑定为127.0.0.1,导致外部无法访问
vi /etc/mongod.conf
port=27017
fork=true # 以创建子进程的方式运行
dbpath=/data/db #日志输出方式数据库路径
logappend=true #日志输出方式,日志append而不是overwrite
logpath=/data/logs/mongo.log #日志路径
auth=false#开启安全验证(可以不开启)
3. 停止服务
在客户端中使用shutdown命令
use admin
db.shutdownServer()
4. 启动
cd /usr/local/mongodb/bin/
mongod -f /etc/mongod.conf
5. 连接服务器
关闭防火墙
systemctl stop firewalld
连接到服务器