什么是MongoDB?看完你就知道了
优质文章,第一时间送达。
链接| blog.csdn.net/hayre/article/details/80628431
1.什么是MongoDB?用一句话概括
MongoDB是一个为web应用程序和互联网基础设施设计的数据库管理系统。没错。MongoDB是一个数据库。这是一个NoSQL类型的数据库。
(1)MongoDB提出了文档和集合的概念,使用BSON (JSON-like)作为其数据模型结构,是面向对象的而不是二维表。在MongoDB中存储一个用户是这样的。
使用这种数据模型,MongoDB可以在生产环境中提供很高的读写能力,吞吐量相比mysql等SQL数据库有很大的增强。
(2)易于扩展和自动故障切换。可扩展性是指对数据集进行切片的能力,数据的存储压力由多台服务器分担。自动故障转移是副本集的概念。MongoDB可以检测主节点是否处于活动状态,当主节点处于非活动状态时,可以自动将从节点提升为主节点,实现故障转移。
(3)由于数据模型是面向对象的,所以可以表示丰富的层次化数据结构。例如,在博客系统中,“评论”可以直接插入到“文章”的文档中,而无需像myqsl一样创建三个表来描述这种关系。
3.主要特征
(1)文档数据类型
SQL型数据库是规范化的,通过主键或外键的约束可以保证数据的完整性和唯一性,所以SQL型数据库常用于数据完整性高的系统中。MongoDB在这方面不如SQL数据库,而且MongoDB没有固定的模式。正因为MongoDB缺少一些这样的约束,所以可以使数据存储结构更加灵活,存储速度更快。(2)即时查询能力
MongoDB保留了关系数据库的即时查询能力和索引能力(底层基于B树)。这一点借鉴了关系数据库的优点,与同类型的NoSQL redis相比不具备上述能力。(3)复制能力
MongoDB本身提供了一个副本集,可以将数据分布在多台机器上实现冗余,从而提供自动故障转移和扩展读取能力。(4)速度和坚持
MongoDB的驱动实现了一个写语义fire and forget,即通过驱动写的时候,可以立刻得到一个成功的结果(哪怕是错误),使得写的速度更快,当然会不安全,完全依赖网络。
MongoDB提供了日志日志的概念,实际上就像mysql的bin-log日志。当需要插入时,它会先将记录写入日志,然后再完成实际的数据操作。这样,如果停电,进程突然中断,可以保证数据不出错,修复功能可以读取日志日志进行修复。
(5)数据扩展
MongoDB使用碎片技术来扩展数据。MongoDB可以自动分片,分片传输数据块,使每台服务器存储的数据大小相同。
MongoDB的核心服务器主要由MongoDB程序启动,MongoDB使用的内存在启动时不需要配置,因为它的设计理念是内存管理最好留给操作系统,内存配置的不足是MongoDB设计的亮点。此外,还可以通过mongos路由服务器使用碎片功能。
mongoDB的主客户端是一个交互式js shell,通过Mongo启动。有了js shell,就可以直接用js与MongoDB通信,像sql语句一样使用js语法查询MongoDB的数据。另外还提供了各种语言的驱动包,方便各种语言的访问。
Mongodump和mongorestore,备份和恢复数据库的标准工具。输出BSON格式并迁移数据库。
Mongoexport和mongoimport用于导入和导出JSON、CSV和TSV数据,这在数据需要支持多种格式时很有用。Mongoimport也可以用于大型数据集的初始导入,但是顺便说一下,在导入之前需要注意的是,为了充分利用mongoDB,通常需要对数据模型进行一些调整。
Mongosniff是一个网络嗅探工具,用于观察发送到数据库的操作。基本上,它是将网络上传播的BSON转换成人们易于阅读的外壳声明。
因此,可以得出结论,MongoDB结合了键值存储和关系数据库的最佳特性。因为简单,所以数据速度极快,相对容易规模化,提供一个有复杂查询机制的数据库。MongoDB需要在64位服务器上运行,最好单独部署。因为是数据库,所以也需要热备用和冷备用。
因为本文不是API手册,所以这里对shell的使用也是基本介绍一下可以使用哪些函数,可以使用哪些语句,主要是为了展示使用MongoDB shell的便利性。如果需要了解具体的MongoDB shell语法,可以查阅官方文档。
创建数据库不是必要的操作。只有在第一次插入文档时才会创建数据库和集合,这与数据的动态处理是一致的。简化和加速开发过程,并有助于名称空间的动态分配。如果担心数据库或集合会被意外创建,可以打开严格模式。
上面的命令只是简单的例子。假设你之前没有学过任何数据库语法,同时开始学习sql查询语法和MongoDB查询语法,你会觉得哪个更简单?如果用java驱动操作MongoDB,你会发现任何查询都和Hibernate提供的查询方法一样。只要构建一个查询条件对象,就可以很方便地进行查询(接下来会给出一个例子)。博主之前对ES6比较熟悉,所以从MongoDB js shell入手是没有问题的,也正是因为这种简单完善的查询机制,才深深的爱上了MongoDB。
用java驱动链接MongoDB是一件很简单的事情,简单的引用,简单的添加,删除,查询。用了java驱动,发现spring对MongoDB的封装还不如官方自己提供的。简单展示一下吧。
这里只有简单的链接和简单的MongoDB操作,可见操作的轻松。驱动使用时,基于TCP socket与MongoDB通信。如果查询结果太多,无法放入第一个服务器,将向服务器发送getmore命令以获取下一批查询结果。
当向服务器插入数据时,它不会等待服务器的响应。驱动程序将假设写入成功,并实际使用客户机来生成对象id。但是,此行为可以通过配置进行配置,并且可以通过安全模式打开,安全模式可以检查服务器端插入错误。
了解清楚MongoDB的基本数据单元。在关系数据库中有包含列和行的数据表。MongoDB数据的基本单位是BSON文档,文档中有指向不定值的键。MongoDB有即时查询,但是不支持join操作。简单键值存储只能根据单个键获取值,不支持事务,但支持各种原子更新操作。
比如读写比是多少,需要什么样的查询,数据如何更新,有没有并发问题,数据结构化程度是高还是低。系统本身的需求决定了mysql还是MongoDB。
在设计图式时应注意一些原则,如:
数据库是集合的逻辑和物理分组。MongoDB不提供创建数据库的语法。只有当一个集合被插入时,数据库才开始建立。创建数据库后,将在磁盘上分配一组数据文件,数据库的所有集合、索引和其他元数据都将保存在这些文件中。您可以通过检查数据库的磁盘状态。
集合是具有相似结构或概念的文档的容器。收藏的名称可以包含数字、字母或。符号,但必须以字母或数字开头,并且必须完整。
将集合名称限制为不超过128个字符。事实上,符号在集合中非常有用,可以提供某种虚拟名称空间。这是一个组织原则,和其他集合一样。可以在集合中使用。
其次是键值,MongoDB中的所有字符串都是UTF-8。数字类型包括double、int和long。日期类型都是UTC格式,所以在MongoDB看到的时间会比北京时间慢8个小时。整个文档的大小将被限制在16m,因为这样可以防止创建难看的数据类型,小文档可以提高性能。批量插入文档的理想数字范围是10~200,大小不能超过16MB。
(2)在分析查询时,MongoDB通过最优方案选择一个索引进行查询。当没有最合适的索引时,它会先使用每个索引进行查询,最后选择一个最优的索引进行查询。
(3)如果存在a-b综合指数,那么只有A的指数是多余的。
(4)复合索引中键的顺序非常重要。
(2)综合指数
(3)独特性指数
(4)稀疏索引
例如将出现在索引字段中的值,或者大量文档不包含索引键。
如果数据集很大,建立索引的时间会很长,而且会影响程序的性能。
使用mongorestore时会重建索引。当执行大规模删除时,可以使用
压缩并重建索引。
(1)检查慢速查询日志。
(2)分析慢速查询
注意,MongoDB新版本的explain方法需要参数,否则只会显示普通信息。
本节还简要介绍了MongoDB副本集构造的简单性、副本集的健壮性以及监控的方便性。
提供主从复制能力、热备能力和故障转移能力。
实际上,MongoDB对副本集的操作类似于mysql的主从操作。我们先来看看mysql的主从数据流流程。
MongoDB主要依赖的日志文件是oplog。
写操作首先被记录并被添加到主节点的操作日志中。同时,所有从节点复制操作日志。首先,检查操作日志中最后一个条目的时间戳;其次,查询主节点的操作日志中大于该时间戳的所有条目;最后,将这些项目添加到您自己的操作日志中,并将它们应用到您自己的库中。从节点使用长轮询来立即应用来自主节点操作日志的新条目。
当满足以下条件时,从节点停止复制。
本地数据库存储所有副本集元素数据和操作日志日志。
您可以使用以下命令来查看复制。
每个副本集成员每秒钟ping所有其他成员一次,您可以通过rs.status看到最后一个心跳检测时间戳和节点的健康状态
这一点无需过多描述,但有一个特别的场景。如果从节点和仲裁节点都被杀死,只剩下主节点,他将把自己降级为从节点。
如果主节点的数据没有被写入从库,那么该数据不能被认为是提交。当主节点成为从节点时,将触发回滚。那些尚未写入从库的数据将被删除,回滚的内容可以通过回滚子目录中的BSON文件进行恢复。
您只能链接到主节点。如果您链接到从属节点,您将被拒绝写操作。但是如果不使用安全模式,由于mongo的火和忘的特性,会吃到拒绝写的异常。
(2)通过副本集进行链接。
它可以根据写入情况自动进行故障转移,但当副本集中进行新的选举时,它仍然会失败。如果不使用安全模式,还是会写不进去,但是现实中会成功。
碎片化是数据库分段的一种概念性实现,这里简单总结一下为什么要用碎片化,以及它的原理和操作。
当数据量过大时,索引和工作数据集会占用越来越多的内存,需要通过碎片化加载来解决这个问题。
(2)切片的核心操作
碎片的集合:按照一个属性的范围划分碎片,MongoDB使用所谓的碎片键让每个文档在这些范围内找到自己的位置。
Block:位于一个段中的连续的段键范围,可以理解为由若干个块组成的段,该段构成了MongoDB的所有数据。
(3)分裂和迁移
分块:初始化时只有一个分块,当最大分块大小为64MB或100000个文档时会触发分块。将原来的范围一分为二,这样就有两个块,每个块都有相同数量的文档。
迁移:当片段中的数据大小不同时,就会发生迁移。例如,如果片段A中有更多数据,片段A中的一些块将被转移到片段B..碎片集群通过移动碎片中的块来实现均衡,这由称为均衡器的软件进程来管理。任务是确保数据均匀分布在每个片段中。当簇中具有最多块的片段和具有最少块的片段之间的块差大于8时,均衡器将启动均衡过程。
启动两个副本集、三个配置服务器和一个mongos进程。
配置碎片
(2)索引
片段收集只允许在_id字段和片段键上添加唯一索引,而不允许在其他地方添加,因为它需要片段之间的通信,并且实现起来非常复杂。
创建切片时,会根据切片键创建一个索引。
(2)低效的碎片键
(3)理想的切片键
根据不同的数据中心。
(2)最低要求
(3)配置注意事项
需要估计集群大小时,可以使用以下命令对现有集合进行切片。
(4)备份分段的簇
备份切片时,您需要停止均衡器。
使用64位机和32位机会限制mongodb的内存,使其最大值为1.5GB。
(2)cpu mongodb只有在索引和工作集可以放入内存的情况下才会遇到cpu瓶颈。CPU在mongodb中的作用是检索数据。如果看到CPU饱和,可以通过查询慢速查询日志来检查是否是查询问题导致的。如果是,可以通过添加索引来解决问题。
Mongodb写数据的时候会用到CPU,但是mongodb每次只用一个内核。如果有频繁的写行为,这个问题可以通过切片(3)内存来解决。
大内存是mongodb的保证。如果工作集大小超过内存,会导致性能下降,因为会增加将数据加载到内存的动作。
(4)硬盘
默认情况下,mongodb会每60s强制与磁盘同步一次,称为后台刷新,会产生I/O操作。重启时,mongodb会将磁盘中的数据加载到内存中,高速磁盘会减少同步时间。
(5)文件系统
使用ext4和xfs文件系统
禁用上次访问时间
(6)文件描述符
linux默认的文件描述符是1024,需要大大增加。
(7)时钟
mongodb中的所有节点服务器都使用Ntp服务器。
在启动时使用- bind_ip命令。
(2)认证
在启动时使用- auth命令。
(3)副本集认证
使用keyFile时,注意keyFile文件的权限必须是600,否则无法启动。
构建副本集至少需要两个节点,仲裁节点不需要有自己的服务器。
(2)Journaling log先将数据写入日志,此时的数据不是直接写入硬盘,而是写入内存。
但是,日志记录会消耗内存,因此可以在主库上关闭它,在从库上启动它。
您可以单独使用SSD来记录日志。
插入时,驱动程序可以确保日志插入后的反馈,但会大大影响性能。
vvvvv选项(v越大,输出越详细)
db . run command({ logrotare:1 })打开滚动日志。
(2)顶部
(3)db . current top
mongodb活动数据的动态显示
占用当前mongodb监听端口上方的端口1000。
将数据库内容导出到BSON文件,mongorestore可以读取和恢复这些文件。
(2)蒙哥还原
将导出的BSON文件恢复到数据库。
(3)您可以通过备份原始数据文件来做到这一点。但是,在操作之前,您需要锁定数据库。DB。Runcommand ({fsync: 1,lock: true}) DB。$ cmd。sys。解锁。FindOne请求解锁操作,但数据库不会立即解锁,需要db.currentOp验证。
db . run command({ repair database:1 })修复单个数据库。
修复是根据Jourling文件读取和重写所有数据文件,并重建每个索引(2)压缩。
压缩将重写数据文件并重建集合的所有索引。它需要在从属库上停止或运行。如果它需要在主库上运行,它需要添加force参数来确保写锁。
(2)检查索引和查询以提高性能。
一般来说,扫描尽可能少的文档。
确保没有冗余索引。冗余索引会占用磁盘空间,消耗更多内存,每次写入时需要做更多工作。
(3)添加内存
如果dataSize数据大小和indexSize之和大于内存,就会影响性能。
如果存储大小超过数据大小的两倍,性能将受到磁盘碎片的影响,需要进行压缩。