`
yuanzhen
  • 浏览: 31926 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

MongoDB一些常见及生僻的问题做出分析(转)

阅读更多
Russell对MongoDB一些常见及生僻的问题做出分析:

32位 vs 64位

现在大多数的服务器都对32位操作系统实现支持,更有许多新型硬件支持着允许更多RAM的64位操作系统。

MongoDB也同时发布了32位及64位两个版本的数据库。归结于MongoDB使用的内存映射文件,32位版本只支持2G数据的存储。对于标准的Replica Set,MongoDB只拥有单一的处理策略 —— mongod。如果你想在未来储存2G以上的数据,请使用64位版本的MongoDB。如果拥有分片安装,那么32位版本同样可以使用。

总结:使用64位版本或者理解32位版本的限制。

文件大小限制

不同于RDBMS把数据储存在行与列中,MongoDB的数据是储存在文件中的。这些文件使用二进制存储形式,其格式为类似JSON格式的BSON格式。

和其它的数据库一样,单个文件的储存大小是有限制的。在旧版本的MongoDB中,单个文件都限制在4M以内。而新版本的MongoDB单文件已经支持到16M大小。这样的限制也许是令人厌烦的,但是10gen的意见是:如果这项设置不停的困扰到你,那么是否你的设计模式存在着问题;或者你可以使用文件无大小限制的GridFS。

这种情况通常的建议是避免存储过大的文件,不定期的更新数据库中存储的各种对象。而像Amazon S3或者Rackspace Cloudfiles这样的服务通常可能会是更好的选择,而非必要情况下最好别让基础设施陷入过载。

总结:把每个文件保持在16M以下,那么一切都好。

写入失败

MongoDB在默认的情况下允许高速的写入和更新,而付出的代价就是没有明确的错误通知。默认情况下多数的驱动都在做异步、“不安全”写入 —— 这就意味着驱动程序不能立即反馈错误信息,类似于MySQL的INSERT DELAYED。如果你想知道某个事情是否成功,你必须使用getLastError手动的检查错误信息。

某些情况下如果你需要在错误发生后立刻得到错误信息,即:大多数的驱动中都很容易实现同步“安全”查询。这将谋杀掉MongoDB不同于传统数据库的优点。

如果对比“完全安全”的同步写入你需要多一点性能,同时还想要一定程度的安全,那么你可以使用getLastError with‘j’让MongoDB只到一份日志提交后再发出错误报告通知。那么日志将以100毫秒一次的速度输出到磁盘,而不是60秒。

总结:如果必须要写入确认,你可以使用安全写入或getLastError。

数据结构模型的弱化不等于没有数据结构模型

RDBMS一般都拥有一个预定义的数据结构模型:表格的行和列,每个字段都拥有名称和数据类型。如果你想给其中一行加一列,那么你必须给整个表格都添加一列。

MongoDB则是移除了这个设置,对于Collection和文件没有强制的模型限定。这有益于快速开发及简易修改。

当然这不意味着你就可以无视结构模型的设计,一个合适的结构模型可以让你获得MongoDB的最佳性能。赶快阅读MongoDB文档,或者观看这些结构模型设计的相关视频吧!

Schema Design Basics
Schema Design at Scale
Schema Design Principles and Practice
总结:设计结构模型并充分利用MongoDB的特色。

默认情况下修改语句修改的只是单个文件

在传统的RDBMS中除非使用LIMIT子句,修改语句作用的将是所有匹配的地方。然而MongoDB每个查询上都默认使用等价“LIMIT 1”的设置。虽然无法做到“LIMIT 5”,但是你可以通过下面的语句整个的移除限制:

db.people.update({age: {$gt: 30}}, {$set: {past_it: true}}, false, true)

同样在官方的驱动中还有类似的选项 —— ‘multi’。

总结:可以通过指定多个文件的multi为true来完成多文件修改

查询区分大小写

字符串的查询可能不按预期的那样发展 —— 这归结于MongoDB默认区分大小写。

例如:db.people.find({name: ‘Russell’})与db.people.find({name: ‘ russell‘})是不同的。在这里最理想的解决方案就是对需要查询数据进行确认。你也可以通过正则表达式进行查询,比如:db.people.find({name:/Russell/i}),但是这样会影响到性能。

总结:查询是区分大小写的,在牺牲速度的情况下可以利用正则表达式。

对输入的数据无容错性

当你尝试向传统数据库插入错误类型的数据,传统的数据库一般会把数据转换成预定义的类型。然而这在MongoDB中是行不通的,因为MongoDB的文件是没有预定义数据模型的。这样的话MongoDB会插入你输入的任何数据。

总结:使用准确的数据类型。

关于锁

当资源被代码的多个部分所共享时,需要确信锁必须要确保这处资源只能在一个地方被操作。

旧版本的MongoDB (pre 2.0)拥有一个全局的写入锁。这就意味贯穿整个服务器中只有一个地方做写操作。这就可能导致数据库因为某个地方锁定超负载而停滞。这个问题在2.0版本中的得到了显著的改善,并且在当前2.2版本中得到了进一步的加强。MongoDB 2.2使用数据库级别的锁在这个问题上迈进了一大步。同样值得期待的Collection级别的锁也计划在下一个版本中推出。

尽管如此,Russell还是认为:大多数受此限制的应用程序于其说是受MongoDB影响,还不如说是程序本身的问题来的更直接。

总结:使用最新的稳定版本才能获得最高的性能。

关于包

在类Ubuntu和Debian系统上安装时,许多人都出现过“过时版本”这样的问题。解决方案很简单:使用10gen官方库,那么在Ubuntu和Debian上安装也会像在Fedora和Centos上安装一样流畅。

总结:使用拥有大多数最新版本的官方包。

使用偶数个Replica Set成员

Replica Set是增加冗余及提升MongoDB数据集群性能的有效途径。数据在所有的节点中被复制,并选出一个作为主节点。假如主节点出故障,那么会在其他的节点中票选一个作为新的主节点。

在同一个Replica Set中使用两台机器是很有诱惑的,它比3台机器来的便宜并且也是RDBMS的标准行事风格。

但是到了MongoDB这里,同一个Replica Set中的成员数量只能是奇数个。假如你使用了偶数个成员,那么当主节点发生故障时那么其它的节点都会变成只读。发生这种情况是因为剩下待选节点的数目不满足票选主节点的规定。

如果你想节约成本,同时还希望支持故障转移和冗余的增强,那么你可以使用Arbiter。Arbiter是一种特殊的Replica Set成员,它不储存任何用户数据(这就意味着他们可以使用非常小的服务器)。

总结:只可以使用偶数个Replica Set成员,但是可以使用Arbitter来削减成本。

没有join语句

MongoDB不支持join:如果你想在多个Collection中检索数据,那么你必须做多次的查询。

如果你觉得你手动做的查询太多了,你可以重设计你的数据模型来减少整体查询的数量。MongoDB中的文件可以是任何类型,那么可以轻易的对数据进行De-Normalize。这样就可以让它始终和你的应用程序保持一致。

总结:没有join不妨看一下如何设计数据结构模型。

Journaling

MongoDB使用内存映射文件并且每60秒向磁盘输出一次通知,这就意味着最大程度上你可能丢失60秒加上向硬盘输出通知这段时间内所有的数据。

为了避免数据丢失,MongoDB从2.0版本起就添加了Journaling(默认情况下开启)。Journaling把时间从60秒更改为100ms。如果数据库意外的停机,在启动之前它将会被重启用以确保数据库处于一致状态。这也是MongoDB与传统数据库最接近的地方。

当然Journaling会轻微的影响到性能,大约5%。但是对于多数人来说额外带来的安全性肯定是物有所值的。

总结:最好别关闭Journaling。

默认情况下没有身份认证

MongoDB在默认设置下并没有身份验证。MongoDB会认为自身处在一个拥有防火墙的信任网络。但是这不代表它不支持身份验证,如果需要可以轻松的开启。

总结:MongoDB的安全性可以通过使用防火墙和绑定正确的接口来保证,当然也可以开启身份验证。

Replica Set中损失的数据

使用Replica Set是提高系统可靠性及易维护的有效途径。这样的话,弄清节点间故障的发生及转移机制就变得至关重要。

Replica Set中的成员一般通过oplog(记录了数据中发生增、删、改等操作的列表)来传递信息,当其中一个成员发生变化修改oplog后,其他的成员也将按照oplog来执行。如果你负责处理新数据的节点在出错后恢复运行,它将会被回滚至最后一个oplog公共点。然而在这个过程中:丢失的“新数据”已经被MongoDB从数据库中转移并存放到你的数据目录‘rollback’里面等待被手动恢复。如果你不知道这个特性,你可能就会认为数据被弄丢了。所以每当有成员从出错中恢复过来都必须要检查这个目录。而通过MongoDB发布的标准工具来恢复这些数据是件很容易的事情。查看官方文档以了解更多相关信息。

总结:故障恢复中丢失的数据将会出现在rollback目录里面。

分片太迟

分片是把数据拆分到多台机器上,通常被用于Replica Set运行过慢时进行性能提升。MongoDB支持自动分片。然而如果你让分片进行太迟的话,问题就产生了。因为对数据的拆分和块的迁移需要时间和资源,所以如果当服务器资源基本上耗尽时很可能会导致在你最需要分片时却分不了片。

解决的方法很简单,使用一个工具对MongoDB进行监视。对你的服务器做最准确的评估,并且在占整体性能的80%前进行分片。类似的监视工具有:MMS、Munin(+Mongo Plugin)和CloudWatch。

如果你确定从一开始就要分片处理,那么更好的建议会是选用AWS或者类似的云服务进行分片。而在小型服务器上,关机或者是调整机器明显比转移成千上万条数据块来的更直接一点。

总结:尽早的分片才能有效的避免问题。

不可以更改文件中的shard key

对于分片设置,shard key是MongoDB用来识别分块对应文件的凭证。当你插入一个文件后,你就不可以对文件的shard key进行更改。而这里的解决方案是把文档删除然后重新建立,这样就允许把它指定到对应的分块了。

总结:shard key不可以修改,必要的时候可以删除文件重新建立。

不可以对256G以上的Collection进行分片

重新回到分片太迟的问题上来 —— MongoDB不允许对增长到256G以上的Collection进行分片,之前版本的设置还没有256G。这个限定在以后肯定会被移除,而这里也没有更好的解决方案。只能进行重编译或者把大小控制在256G以下。

总结:在Collection达到256G以前进行分片。

唯一性索引与共享

索引的唯一性约束只能通过shard key来保证。

更多详情

选择了错误的shard key

MongDB需要你选择一个shard key来将数据分片。如果选择了错误的shard key,更改起来将是件很麻烦的事情。

点击查看如何更改

总结:选择shard key之前先阅读这个文档。

与MongoDB通信的未经加密

与MongoDB的连接默认情况下都是非加密的,这就意味你的数据可能被第三方记录和使用。如果你的MongoDB是在自己的非广域网下使用,那么这种情况是不可能发生的。

然而如果你是通过公网访问MongoDB的话,那么你肯定会希望你的通信是经过加密的。公版的MongoDB是不支持SSL的。庆幸的是可以非常简单的定制自己的版本。10gen的用户则拥有特别定制的加密版本。幸运的是大部分的官方驱动都支持SSL,但是小麻烦同样是不可避免的。点击查看文档。

总结:当用公网连接时,要注意和MongoDB的通信是未加密的。

事务

不像MySQL这些支持多行数据原子操作的传统数据库,MongoDB只支持单文件的原子性修改。解决这个问题的方法之一是在应用程序中使用异步提交的方式;另一个是:建立一个以上的数据存储。虽然第一种方法并不适用于所有情况,但是很显然比第二个来的要好。

总结:不支持对多文件事务。

日志预分配慢

MongDB可能会告诉你已经准备就绪,但事实上它还在对日志进行分配。如果你选择了让机器自行分配,而恰巧你的文件系统和磁盘速度又很慢,那么烦恼的事情发生了。通常情况下这不会成为问题,但是一旦出现了可以使用undocumented flag –nopreallocj来关闭预分配。

总结:如果机器文件系统和磁盘过慢的话,那么日志的预分配也可能很慢。

NUMA + Linux +MongoDB

Linux、NUMA与MongoDB遇到一起的时候运行总是不会很好。如果你在NUMA硬件上运行MongoDB的话,这里建议是直接关掉。因为各种奇怪的问题随之而来,比如:速度会阶段性或者在CPU占用率很高的时候大幅下降。

总结:禁NUMA。

Linux里面的进程限制

如果你在MongoDB未满载的时候出过SEGMENTATION FAULT错误,你可能会发现这是因为使用了过低或者默认的打开文件或用户进程限制。10gen建议把限制设置在4K+,然而设置的大小该取决具体情况。阅读ulimit了解更多。

总结:长久的为MongoDB在Linux加上软或硬的打开文件或用户进程限制。
分享到:
评论

相关推荐

    php_mongodb-1.5.5-7.2-ts-vc15-x64.zip

    3. **README.md**:这是一个Markdown格式的文档,通常包含了安装指南、配置说明、常见问题解答等重要信息。对于用户来说,这是快速了解如何使用和配置扩展的关键文件。 4. **php_mongodb.dll**:这是实际的PHP扩展...

    NoSQL误用和常见陷阱分析

    ### NoSQL误用和常见陷阱分析 #### 一、被误用的NoSQL:循环网络调用 在NoSQL数据库的使用过程中,一种常见的误用是循环网络调用,这通常发生在开发者没有充分利用NoSQL数据库的批量操作能力时。例如,在使用...

    大数据市场分析平台.zip

    Hadoop HDFS(分布式文件系统)和NoSQL数据库(如MongoDB、Cassandra)是常见的存储解决方案,它们提供高可扩展性和容错性。 3. 数据处理与预处理:Apache Spark等计算框架用于快速处理数据,进行清洗、转换和整合...

    区域性地铁客流量智能分析系统的设计与实现.zip

    本设计与实现的目标是构建一个高效、精准的智能分析系统,以应对日益复杂的地铁客流问题。 首先,系统设计的核心在于数据采集。这通常涉及到多个方面:一是地铁闸机进出站数据,通过读取IC卡或二维码的使用记录来...

    软件工程与大数据分析融合.pptx

    - **大数据分析模型**:常见的有预测模型、分类模型、聚类模型等。这些模型不仅能够帮助我们理解数据,还能够对未来的情况做出预测,为企业提供前瞻性的指导。 - **大数据可视化技术**:将复杂的分析结果转化为易于...

    摩拜单车小程序开发实践与框架分析

    在小程序框架方面,摩拜单车小程序的实践分析会包括对小程序组件化开发的讨论,比如在小程序中常见的页面组件、轮播组件、地图组件等,这些组件是构成小程序用户界面的基础。同时,对于用户交互层面,小程序开发要...

    云计算的顶级威胁:深度分析-CSA-2018.pdf

    1. **数据泄露**:由于云环境中数据的复杂性和分布性,数据泄露成为了最常见的安全问题之一。这不仅涉及到外部攻击者窃取敏感信息,还包括内部人员的不当行为。 2. **账户劫持**:账户劫持是指未经授权的用户通过...

    医疗运作管理大数据的应用.pdf

    借助分布式系统、云计算和Hadoop、MongoDB等分布式数据库,可以缓解这些问题,为医疗决策提供支持。 3. 医疗大数据分析方法及研究 面对海量的医疗大数据,传统分析方法已力不从心,需要借助如Apriori等算法来挖掘...

    Java 全栈知识点问题汇总(16).pdf

    设计模式是软件工程中的最佳实践,常见的有工厂模式、单例模式、装饰器模式等23种设计模式,它们提供了在特定场景下解决问题的标准解决方案,有助于提高代码的可读性和可维护性。 在开源协议方面,主要讨论了MIT、...

    大型网站技术架构:核心原理与案例分析+李智慧.zip

    《大型网站技术架构:核心原理与案例分析》是李智慧所著的一本深入探讨大型网站技术架构的专业书籍。这本书旨在揭示支撑大型网站背后的复杂技术体系,解析其核心原理,并通过实际案例来帮助读者理解和应用这些知识。...

    帮助数据科学家和机器学习工程师更有效地处理和优化他们的数据集和模型。.zip

    5. 鲁棒性与泛化能力:过拟合和欠拟合是数据科学中的常见问题。正则化(L1和L2)可防止过拟合,集成学习(如bagging、boosting)可以提高模型的泛化能力。 6. 模型评估:准确率、精确率、召回率、F1分数、AUC-ROC...

    工业大数据技术架构白皮书

    常见的分析方法包括预测分析、关联分析、聚类分析等。 - **决策与控制应用**:基于数据分析的结果,为企业管理者提供决策支持,帮助他们制定战略规划;同时也包括将分析结果反馈到生产流程中,实现闭环控制,进一步...

    trafiic-management-:这是一个用于解决其城市中与交通有关的问题的网站。 有关当局将对此问题做出回应,并将问题的状态通过短信发送给用户手机

    同时,它还负责将这些数据以JSON格式发送到服务器端,这是现代Web应用中常见的数据交换格式,便于数据的解析和处理。 服务器端接收到数据后,会进行进一步的处理和存储。通常,这涉及到数据库操作,如MySQL或...

    在线调查平台

    常见的分析方式有交叉分析、趋势分析和比例分析等。 5. 报告生成:自动生成包含图表和统计数据的报告,以便分享给决策者或其他利益相关者。 6. 安全性:确保数据的隐私和安全,采用加密技术存储和传输数据,防止未...

    数据挖掘工程师岗位职责.docx

    数据挖掘工程师是IT行业中一个关键的角色,他们负责从海量数据中发现有价值的信息,帮助企业做出决策。以下是关于数据挖掘工程师的详细岗位职责和任职要求: **数据挖掘工程师的主要职责:** 1. **业务数据分析和...

    毕设&课程作业_智能客服系统V2.zip

    NLP技术如词法分析、句法分析、语义理解等,使系统能够解析用户输入的问题,并做出准确的回应。 2. **机器学习(Machine Learning)**:机器学习算法用于训练模型,让系统能从历史对话数据中学习并优化其响应策略。...

    9-4+物联网大数据平台的选型及应用.zip

    "9-4+物联网大数据平台的选型及应用"这个主题涉及到的知识点广泛,涵盖了物联网技术、大数据处理、平台选型策略以及实际应用场景等多个方面。下面将对这些关键点进行详细的阐述。 首先,物联网(IoT)是指通过各种...

    基于大数据的炼化装置机泵设备异常状态预警技术研究.zip

    5. 异常检测算法:常见的异常检测方法有统计方法(如Z-score、IQR)、机器学习(如SVM、随机森林、深度学习)和时间序列分析。在炼化装置中,这些算法用于识别机泵设备的异常运行状态,例如,通过分析振动频率变化来...

    李智慧_大型网站技术架构:核心原理与案例分析(全本)

    书中可能介绍了常见的安全威胁及对应的防护措施,比如防火墙、入侵检测系统和安全编码实践。 最后,这本书也可能涵盖了持续集成和持续部署(CI/CD)的重要性,以及如何利用自动化工具实现快速迭代和部署。 综上所述...

    这些问题涵盖了大数据处理、分布式系统、机器学习等多个方面.docx

    ### 大数据处理 #### 1....通过以上内容,我们了解了大数据处理的基本概念、关键技术、工具框架以及面试中常见问题的回答技巧。对于准备从事大数据相关工作的人来说,掌握这些知识点是非常重要的。

Global site tag (gtag.js) - Google Analytics