`

mongodb 的一次性能问题

阅读更多
转:[url] http://huoding.com/2011/08/09/104[/url]

记一次MongoDB性能问题
Posted on 2011-08-09
最近忙着把一个项目从MySQL迁移到MongoDB,在导入旧数据的过程中,遇到了些许波折,犯了不少错误,但同时也学到了不少知识,遂记录下来。


公司为这个项目专门配备了几台高性能务器,清一色的双路四核超线程CPU,外加32G内存,运维人员安装好MongoDB后,就交我手里了,我习惯于在使用新服务器前先看看相关日志,了解一下基本情况,当我浏览MongoDB日志时,发现一些警告信息:

WARNING: You are running on a NUMA machine. We suggest launching mongod like this to avoid performance problems: numactl –interleave=all mongod [other options]

当时我并不太清楚NUMA是什么东西,所以没有处理,只是把问题反馈给了运维人员,后来知道运维人员也没有理会这茬儿,所以问题的序幕就这样拉开了。

迁移工作需要导入旧数据。MongoDB本身有一个mongoimport工具可供使用,不过它只接受json、csv等格式的源文件,不适合我的需求,所以我没用,而是用PHP写了一个脚本,平稳运行了一段时间后,我发现数据导入的速度下降了,同时PHP抛出异常:

cursor timed out (timeout: 30000, time left: 0:0, status: 0)

我一时判断不出问题所在,想想先在PHP脚本里加大Timeout的值应付一下:

<?php

MongoCursor::$timeout = -1;

?>
可惜这样并没有解决问题,错误反倒变着花样的出现了:

max number of retries exhausted, couldn’t send query, couldn’t send query: Broken pipe

接着使用strace跟踪了一下PHP脚本,发现进程卡在了recvfrom操作上:

shell> strace -f -r -p <PID>
recvfrom(<FD>,
通过如下命令查询recvfrom操作的含义:

shell> apropos recvfrom
receive a message from a socket
或者按照下面的方式确认一下:

shell> lsof -p <PID>
shell> ls -l /proc/<PID>/fd/<FD>
此时如果查询MongoDB的当前操作,会发现几乎每个操作会消耗大量的时间:

mongo> db.currentOp()
与此同时,运行mongostat的话,结果会显示很高的locked值。



我在网络上找到一篇:MongoDB Pre-Splitting for Faster Data Loading and Importing,看上去和我的问题很类似,不过他的问题实质是由于自动分片导致数据迁移所致,解决方法是使用手动分片,而我并没有使用自动分片,自然不是这个原因。



询问了几个朋友,有人反映曾遇到过类似的问题,在他的场景里,问题的主要原因是系统IO操作繁忙时,数据文件预分配堵塞了其它操作,从而导致雪崩效应。

为了验证这种可能,我搜索了一下MongoDB日志:

shell> grep FileAllocator /path/to/log
[FileAllocator] allocating new datafile ... filling with zeroes...
[FileAllocator] done allocating datafile ... took ... secs
我使用的文件系统是ext4(xfs也不错 ),创建数据文件非常快,所以不是这个原因,但如果有人使用ext3,可能会遇到这类问题,所以还是大概介绍一下如何解决:

MongoDB按需自动生成数据文件:先是<DB>.0,大小是64M,然后是<DB>.1,大小翻番到128M,到了<DB>.5,大小翻番到2G,其后的数据文件就保持在2G大小。为了避免可能出现的问题,可以采用事先手动创建数据文件的策略:

#!/bin/sh

DB_NAME=$1

cd /path/to/$DB_NAME

for INDEX_NUMBER in {5..50}; do
    FILE_NAME=$DB_NAME.$INDEX_NUMBER

    if [ ! -e $FILE_NAME ]; then
        head -c 2146435072 /dev/zero > $FILE_NAME
    fi
done
注:数值2146435072并不是标准的2G,这是INT整数范围决定的。



最后一个求助方式就是官方论坛了,那里的国际友人建议我检查一下是不是索引不佳所致,死马当活马医,我激活了Profiler记录慢操作:

mongo> use <DB>
mongo> db.setProfilingLevel(1);
不过结果显示基本都是insert操作(因为我是导入数据为主),本身就不需要索引:

mongo> use <DB>
mongo> db.system.profile.find().sort({$natural:-1})


问题始终没有得到解决,求人不如求己,我又重复了几次迁移旧数据的过程,结果自然还是老样子,但我发现每当出问题的时候,总有一个名叫irqbalance的进程CPU占用率居高不下,搜索了一下,发现很多介绍irqbalance的文章中都提及了NUMA,让我一下子想起之前在日志中看到的警告信息,我勒个去,竟然绕了这么大一个圈圈!安下心来仔细翻阅文档,发现官方其实已经有了相关介绍,按如下设置搞定:

shell> echo 0 > /proc/sys/vm/zone_reclaim_mode
shell> numactl --interleave=all mongod [options]
关于zone_reclaim_mode内核参数的说明,可以参考官方文档。

注:MongoDB1.9.2+:check for /proc/sys/vm/zone_reclaim_mode at startup。

至于NUMA的含义,简单点说,在有多个物理CPU的架构下,NUMA把内存分为本地和远程,每个物理CPU都有属于自己的本地内存,访问本地内存速度快于访问远程内存,缺省情况下,每个物理CPU只能访问属于自己的本地内存。对于MongoDB这种需要大内存的服务来说就可能造成内存不足,NUMA的详细介绍,可以参考老外的文章。

This entry was posted in Technical and tagged MongoDB, Performance by 老王. Bookmark the permalink.
分享到:
评论

相关推荐

    MongoDB数据库查询性能提高40倍的经历分享

    数据库性能对软件整体性能有着至关重要的影响,本文给大家分享了一次MongoDB数据库查询性能提高40倍的经历,感兴趣的朋友们可以参考学习。 背景说明 1、数据库:MongoDB 2、数据集: A:字段数不定,这里主要...

    记一次MongoDB性能问题(从MySQL迁移到MongoDB)

    公司为这个项目专门配备了几台高性能务器,清一色的双路四核超线程CPU,外加32G内存,运维人员安装好MongoDB后,就交我手里了,我习惯于在使用新服务器前先看看相关日志,了解一下基本情况,当我浏览MongoDB日志时,...

    如何对 MongoDB 进行性能优化(五个简单步骤)

    大家在使用MongoDB的时候有没有碰到过性能问题呢?这里总结了MongoDB性能优化的五个步骤,希望能够有所帮助。 第一步:找出慢语句 一般来说查询语句太慢和性能问题瓶颈有着直接的关系,所以可以用MongoDB的性能分析...

    MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像...

    SpringBoot+MongoDB+Vue前后分离

    前后端分离开发,即当前端又当后端,分角色开发【课程受益】一次上手,即学即会,提供全套源代码,直接可以运行【技术介绍】MongoDB目前NoSql中最流行的数据库,互联网的必备神器,目前最新的版本4.x;本课程针对4.x...

    mongodb-org-server-4.0.10-1.el7.x86_64.zip

    MongoDB是一个基于分布式文件存储 [1] 的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像...

    Mongodb设置TTL索引自动清除数据与过期数据的方法

    当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期,并且删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间...

    MongoDB4.x之单机搭建一次搞定

    作为一个适用于敏捷开发的数据库,MongoDB的数据模式可以随着应用程序的发展而灵活地更新。与此同时,它也为开发人员?提供了传统数据库的功能:二级索引,完整的查询系统以及严格一致性等等。?MongoDB能够使企业更加...

    mongodb使用心得简单总结

    3)没有严格的事务特性,但是它保证任何一次数据变更都是原子性的。 4)也没有固定的数据模型 5)mongo以javascript作为命令行执行引擎,所以利用shell进行复杂的计算和查询时会相当的慢。 6)mongo本身支持集群和...

    非关系型数据库MongoDB入门

    十次方项目的文章评论两项功能存在以下特点:数据量大写入操作频繁数据价值较低对于这样的数据,我们更适合使用MongoDB来实现数据的存储其他方案:Redis不适合在数据量大时使用MySQL使用集群投入成本过大MongoDB是一...

    JSON文档数据库ToroDB.zip

    NoSQL 一样重复造轮子无模式数据库存储大量的重复元数据,ToroDB 只存储一次因为基于 PostgreSQL 开发,确保真正的可用性和事务支持JSON 查询简单还不够,还支持更新操作与 MongoDB 的性能比较: 标签:...

    heartMon:MongoDB 的快速 REST 心跳监视器

    heartMon 是一个 Python Tornado REST 服务,用于检查连接到 MongoDB 的健康 mongos 服务器的所有副本集的状态和性能 这是示例代码,可帮助为演示 UI 构建 JQuery 兼容小部件,或用作独立的近实时监视器,以便在演示...

    【最新版】navicatess150_premium_en.dmg【亲测可用】最好的数据库开发工具

    无论您是在Windows,macOS还是Linux上运行,都可以购买一次并选择要激活的平台,然后再转让许可证。 暗模式 设置深色主题,以保护您的眼睛免受传统上令人眼花white乱的计算机白度的影响。在黑暗模式下,页面的...

    GithubDatamining

    Github 数据挖掘使用的技术下载和存储数据这部分已经大致搞... 在不太可能的情况下,我们创建了性能依赖指标,我们可以切换到另一种语言事件存储一次写入多次读取的数据库,针对事件流进行了优化,并在数据上创建了投

    EpicScrapy1024:BOOM:collision:BOOM:collision:BOOM:collision:!! Python3 + Scrapy + MongoDB。 每天有500万个数据和10 GB的洪流文件! :collision:全球最大的中文BBS

    搜寻器一次请求10个线程。 如果您的网络性能更高,则可以每天请求更多线程并抓取更多帖子。建筑学Python 3.6 Scrapy框架。 从池中随机提取Cookie和用户获取。 下载发布的种子文件并将其存储在本地磁盘中。 将结果项...

    vladmihalcea.wordpress.com:vladmihalcea.com的某些源代码。 hibernate-master-class和high-performance-java-persistence也用作博客源代码存储库-java source code

    不再有性能问题,也不必花费无数小时来弄清楚为什么您的应用程序几乎没有进行爬网。 想象一下在开发周期的早期发现您正在使用次优映射和实体关系,或者您缺少与性能相关的设置。 此外,借助Hypersistence ...

    轻量级JAVA实时业务风控系统框架.zip

    最近统计,比如最近一次交易才过数秒,可能机器下单 行为习惯,比如用户常用登录地址,用户经常登录时间段,可以用来分析盗号等 抽象:某时间段,在条件维度(可以是多个维度复合)下,利用统计方法统计结果维度的值...

    stock-player:一个自定义查看股市行情的应用

    #stock-player 一个自定义查看股市行情的应用 #功能 ...这个是我第一次做架构,做下来感觉获益颇多,对Nodejs全栈开发架构有了更多的理解。同时审视这个应用,感觉有太多可以改近的地方(其实太糙了

Global site tag (gtag.js) - Google Analytics