锁粒度与并发性能怎么样?

数据库的读写并发性能与锁的粒度息息相关,不管是读操作还是写操作开始运行时,都会请求相应的锁资源,如果请求不到,操作就会被阻塞。读操作请求的是读锁,能够与其它读操作共享,但是当写操作请求数据库时,它所申请的是写锁,具有排它性。

MongoDB在2.2之前的版本,锁的粒度是非常粗的,它会锁住整个mongod实例。这意味着当一个数据库上的写锁被请求后,对mongod实例上管理的其它数据库的操作都会被阻塞。2.2版本降低了锁的粒度,引入了单个数据库范围的锁,也就是说读写操作的锁被限定在单个数据库上,当一个数据库被锁住后,其它数据库上的操作可以继续被执行。尽管相对于全局实例范围锁,数据库范围锁性能有所提高,但是对于同一个数据库大量的并发读写还是会有性能瓶颈出现,本书介绍的2.6版本仍然是数据库范围锁,所以并发性能问题仍然存在。

在即将发布的2.8版本中将会引入基于文档级别的锁,相当于关系数据库中的行级锁,锁的粒度更进一步变细。因此当一个写操作发生时,只有涉及到的文档会被锁住,如果写操作涉及到整个集合,那么将会产生一个集合锁来锁住整个集合,同理,如果写操作涉及多个数据库,仍然会有一个全局实例锁产生。

是否支持ACID事务?

经典ACID事务有四种特性即Atomicity,Consistency,Isolation和Durability。其中原子性保证了事务的操作要么全部成功,要么失败后进行回滚,使数据库回到原来的状态;一致性保证了事务在开始之前和结束以后,数据库中的数据完全符合所设置的各种约束和规则;隔离性保证了多个事务操作同一数据时,相互之间按照约定的隔离级别访问和修改相同的数据,不同的关系数据库会有不同的默认隔离级别;持久性保证了事务结束后,事务所涉及到的数据变化被持久的保存在数据库中,即使断电重启数据也会存在,并且是完整的。

MongoDB并不支持ACID事务特性,但是MongoDB支持在单个文档(记录)上的原子操作,设计数据模型时,通过文档嵌套的方式也能解决关系数据库中ACID事务特性所要求的大多数问题。例如,在关系数据库中多条相关联的记录存储,可以通过嵌套数组或文档的形式作为一条记录保存在MongoDB中,这样相当于实现了原子性。

内存映射文件如何工作?

内存映射文件是指调用操作系统的底层函数mmap( )将磁盘上的文件映射到一个操作系统虚拟地址空间中,只是地址与地址之间建立一个映射关系,实际数据还在物理磁盘上,不在内存中。内存映射文件是MongoDB存储引擎管理数据的核心方法,一旦完成映射,MongoDB对这部分文件数据的访问,就好像在内存中访问一样,通过一个地址就能直接访问了。

MongoDB利用内存映射文件的方式管理和操作所有的数据,如果数据没有被映射到内存中,则不能被访问。对已经完成内存映射的文件进行访问时,如果发现数据不在内存中,则会发生缺页错误,操作系统将通过映射好的地址关系找到在磁盘上的数据文件并将它加载到内存中。

服务器的内存多大合适?

MongoDB采用内存映射文件的机制来加快数据的读写速度,使用操作系统自带的虚拟内存管理器来管理内存,理论上MongoDB会占用服务器上所有的空闲内存,但实情况下的数据文件总是远大于物理内存的大小,况且可能会有新的进程运行在服务器上,这也需要占用内存,因此全部将数据文件映射到虚拟地址空间是不可能的。

MongoDB在实际运行过程中,会有一部分经常被客户端访问的数据和索引,称之为活跃“工作集”,如果能保证这部分“工作集”的数据常驻内存,系统性能将比较高效,否则,大量的磁盘I/O操作将会发生,降低系统性能。因此,服务器的内存大小最少大于“工作集”数据的大小比较合适。当服务器的空闲内存不足时,操作系统会根据内存管理算法将最近最少使用的数据从内存中移除,腾出空间给有需要的数据。

不支持join查询怎么办?

Join查询是关系数据库中一种经典的多表联合查询的方式,但MongoDB并不支持这种操作。如果你想在多个Collection中检索数据,那么你必须做多次的查询,如果觉得手动做的查询太多了,你可以重设计你的数据模型来减少整体查询的数量。

MongoDB中的文档可以是任何类型,我们可以轻易的对数据结构进行重构,这样就可以让它始终和应用程序保持一致,用一次查询就能满足需求。切记,避免用关系数据库的思维来设计MongoDB的表结构。

复制集提供了数据冗余功能为什么还要用Journaling?

Journaling是特别有用的当数据库遇到突然断电等异常情况时,尤其是对只有单个节点的数据中心,它能使数据库快速的恢复起来。Journaling类似关系数据库MySql中的事务日志功能,它与复制集的冗余功能不一样,后者更强调的是一种数据备份,而journaling偏向与数据库灾难恢复。关于Journaling的工作机制,请参考本书第5章。

什么时候该用GridFS?

GridFS本质上还是基于MongoDB的collection和document等核心技术的,只是它会将大于16MB的文件分割成许多小文件,然后将这些小文件存储在相应的collection中。如果需要存储的单个文件的大小超过16MB,就应该用MongoDB自带的GridFS系统,有的时候将大文件存储在MongoDB的GridFS中比直接存在操作系统的文件系统中要更加高效;如果需要存储的文件数超过了操作系统中一个目录下允许包含的文件总数,则可以用GridFS系统;当你想要将你的文件分布式部署在各个数据中心并提供冗余保护时,可以用GridFS系统。

此外,当你的所有文件大小都小于16MB时,不要用GridFS系统,因为将每个文件保存在一个document中往往会更高效。

分片集群如何分发查询请求的?

如何分发查询请求在一个分片集群上取决于集群的配置和查询语句本身。例如一个被分片的集合,有两个字段:user_id和user_name,其中user_id为分片的片键,当一个查询语句利用user_id作为过滤条件返回结果时,mongos路由进程将先利用配置服务器上的元信息解析出需要从哪个或哪几个片上获取数据,然后直接将查询请求定向到具体的片上,最后返回结果给客户端;当一个查询利用user_id作为过滤条件同时要求对查询结果进行排序时,mongos先将查询请求路由到具体的片上,并在各个片上完成排序,最后mongos将合并排序结果返回给客户端;当一个查询利用user_name作为过滤条件时,则查询请求将被定向到所有的片上,mongos合并各片上查询结果返回给客户端。

复制集从故障中自动恢复要多久?

复制集从故障中恢复并选择一个新的primary节点大约需1分钟的时间。通常其它成员节点将会花大约10到30秒的时间发送心跳包到发生故障的primary节点,判断primary节点发生了故障;接着触发一个选举,大约再花10到30秒的时间选举出新的primary节点,在选举的过程中,复制集不能响应写操作请求。如果配置了允许客户端从其它secondary节点读取,则在选举的过程中复制集能够响应客户端的读请求。

为什么磁盘分配的空间大于数据库中数据大小?

这主要有以下几方面的原因:

(1)MongoDB存储引擎采取预分配数据文件机制,这样能够减少文件系统的碎片。MongoDB将第一个数据文件命名为<数据库名>.0,第二个命名为<数据库名>.1,依次类推下去。第一个文件的大小为64MB,第二个为128MB,后面分配的文件大小都是前面一个的两倍,这样会导致最后分配的数据文件可能会有部分空间是没有保存数据库数据的,因此会浪费一点磁盘空间。

(2)如果mongod实例是复制集的成员,则会在数据目录下产生一个oplog.rs文件,文件中包含用来同步数据的操作日志,类似于MySql中的二进制日志,这个文件的大小约占5%的磁盘空间,它是可以被重复使用的。

(3)数据目录中还会包含journal文件,在写作的更改刷新到数据文件之前,用来保存写操作日志,实现数据库的恢复功能,类似于MySql中的redo日志。

(4)当删除一些集合或文档时,MongoDB存储引擎会重用这部分数据空间,但是不会把这部分空间返还给操作系统,除非执行repairDatabase命令。

所以mongod实例占用的磁盘空间大小总是大于数据库中数据文件的大小。

大数据存储:MongoDB实战指南

大数据存储:MongoDB实战指南——常见问题解答的更多相关文章

  1. 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

    下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...

  2. 《大数据Spark企业级实战 》

    基本信息 作者: Spark亚太研究院   王家林 丛书名:决胜大数据时代Spark全系列书籍 出版社:电子工业出版社 ISBN:9787121247446 上架时间:2015-1-6 出版日期:20 ...

  3. MapGis如何实现WebGIS分布式大数据存储的

    作为解决方案厂商,MapGis是如何实现分布式大数据存储的呢? MapGIS在传统关系型空间数据库引擎MapGIS SDE的基础之上,针对地理大数据的特点,构建了MapGIS DataStore分布式 ...

  4. Sqlserver 高并发和大数据存储方案

    Sqlserver 高并发和大数据存储方案 随着用户的日益递增,日活和峰值的暴涨,数据库处理性能面临着巨大的挑战.下面分享下对实际10万+峰值的平台的数据库优化方案.与大家一起讨论,互相学习提高!   ...

  5. 从 RAID 到 Hadoop Hdfs 『大数据存储的进化史』

    我们都知道现在大数据存储用的基本都是 Hadoop Hdfs ,但在 Hadoop 诞生之前,我们都是如何存储大量数据的呢?这次我们不聊技术架构什么的,而是从技术演化的角度来看看 Hadoop Hdf ...

  6. 大数据存储的进化史 --从 RAID 到 Hdfs

    我们都知道现在大数据存储用的基本都是 Hdfs ,但在 Hadoop 诞生之前,我们都是如何存储大量数据的呢?这次我们不聊技术架构什么的,而是从技术演化的角度来看看 Hadoop Hdfs. 我们先来 ...

  7. 数据存储 mongodb

    数据存储 mongodb from pymongo import MongoClient import os base_dir = os.getcwd() class MongoPipeline(ob ...

  8. MongoDB实战指南(一):大数据与云计算

    1.1 什么大数据 具体来说,大数据技术涉及到数据的创造,存储,获取和分析,大数据的主要特点有下面几个: 数据量大.一个典型的PC机载2000年前后其存储空间可能有10GB,今天facebook一天增 ...

  9. Hadoop第三天---分布式文件系统HDFS(大数据存储实战)

    1.开机启动Hadoop,输入命令:  检查相关进程的启动情况: 2.对Hadoop集群做一个测试:   可以看到新建的test1.txt和test2.txt已经成功地拷贝到节点上(伪分布式只有一个节 ...

随机推荐

  1. angular报$injector / unpr的错误

    原因:angular引用未定义的错误,因为JS代码压缩过后找不到申明的变量,,没在使用之前定义,且代码被压缩,则报错(变量压缩后会变成单个字母无法识别,需在引用前分别定义): 解决:angular.m ...

  2. MySQL-Front 建表引发的一点小思考(数据表格模版)

    我们建表的时候,有一些字段总是会常用到的.也就是每一张表都会有这些字段. 我用mysql有一点时间了,今天(2016-02-27 21:53:38)在用mysql-front建表的时候,感觉有点点不太 ...

  3. 炼数成金(dataguru)IT技能修炼

    2016我定的目标就是要走出舒适区,进入学习区!为了少走弯路,节约学习的成本和时间,我选择了dataguru.看到心仪的课程毫不犹豫的就报了名. 分享了炼数成金邀请码,使用邀请码报名课程可以减免50% ...

  4. .Net中的加密解密

    返回博客列表 转 .Net中的加密解密 李朝强 发布时间: 2015/11/23 12:55 阅读: 33 收藏: 3 点赞: 0 评论: 0 在一些比较重要的应用场景中,通过网络传递数据需要进行加密 ...

  5. 项目jar包管理,使用 .userlibraries 文件增加jar包的可移植性,明确jar包依赖,多项目共用jar包里

    当一个普通的项目,在不适用maven 等jar包管理工具的时候,通常我都会直接把jar 包复制lib下,并且在build path 中直接添加额外jar包,或者使用user_libraries包所用的 ...

  6. Android 测试Handler的基本使用

    package com.sherlock.app_handler; import java.io.ByteArrayOutputStream; import java.io.InputStream; ...

  7. bibnernate(2)

    2. 实例代码 新建一个java工程,假设取名为HibernateHelloWorld.在src下新那一个package,可取名为com.sun.hibernate.model 2.1 类代码 新建一 ...

  8. flex表格的使用

    Flex中表格使用datagrid+columns两个组件构成,dagagrid中定义了表格的外观属性和数据源Columns中定义了表格的列名还有对应的字段,方便从数据源取得数据 数据源的赋值一般有两 ...

  9. js常用的地址栏参数获取

    用JS获取地址栏参数的方法(超级简单) 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实用又方便!) function GetQueryString(name) {      var reg ...

  10. Linux的phpstudy mysql登录

    使用绝对路径登录 /phpStudy/mysql/bin/mysql -uroot -p; 设置远程登录密码 GRANT ALL PRIVILEGES ON *.* TO 'itoffice'@'%' ...