近期忙着把一个项目从MySQL迁移到MongoDB,在导入旧数据的过程中。遇到了些许波折,犯了不少错误,但同一时候也学到了不少知识,遂记录下来。

公司为这个项目专门配备了几台高性能务器,清一色的双路四核超线程CPU,外加32G内存,运维人员安装好MongoDB后。就轮到我了。我习惯于在使用新server前先看看相关日志。了解一下基本情况。当我浏览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是什么东西,所以没有处理,仅仅是把问题报告给了运维人员。事实证明运维人员也没有处理,所以问题的序幕就这样拉开了…

迁移工作首先要导入旧数据。開始一切倒还正常。只是几小时之后,我无意中发现不知道什么时候開始数据导入的速度下降了,同一时候我的PHP脚本開始不停的抛出异常:

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

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

MongoCursor::$timeout = -1;

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

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

无奈之下用strace跟踪了一下PHP脚本:

shell> strace -p <PID>

发现进程卡在了recvfrom操作上:

recvfrom(<FD>,

通过例如以下命令查询recvfrom操作的含义是:receive a message from a socket

shell> apropos recvfrom

还能够依照以下的方式确认一下:

shell> lsof -p <PID>
shell> ls -l /proc/<PID>/fd/<FD>

此时查询MongoDB当前操作。发现差点儿每一个操作会消耗大量的时间:

shell> echo "db.currentOp()" | /path/to/mongo

同一时候执行mongostat显示非常高的locked值。

…

反复做了非常多工作。但始终无法找到问题的症结在哪里,仅仅好求助官方论坛,那里的技术支持都非常热心,在我描写叙述了问题后,没过多久就有了回复,建议我检查一下是不是索引不佳所致,为了验证这样的可能,我激活了Profiler记录慢操作:

mongo> use <DB>
mongo> db.setProfilingLevel(1);

只是结果显示基本都是insert操作(由于我是导入数据为主),本身就不须要索引:

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

…

问题到了这里,似乎已经走投无路了。为了死马当活马医。我又反复了几次迁移旧数据的过程,结果自然是次次都出问题,但幸运的是我发现每当出问题的时候,在top命令的结果中,总有一个名叫irqbalance的进程居高不下,搜索了一下,结果非常多介绍irqbalance的文章中都提及了NUMA。让我一下子记起之前在日志中看到的警告信息,于是乎依照信息里介绍的,又一次启动了一下MongoDB:

shell> numactl --interleave=all /path/to/mongod

一切都正常了。为了解决问题。浪费了非常多精神。实在没有力气再解释NUMA究竟是什么东西了。有想了解的网友能够參考老外的文章,里面的介绍非常翔实。

原文链接:huoding.com

对于罪魁祸首,作者留给大家去学习,NoSQLFan在这里能够给大家做一个简单的描写叙述,先解释几个概念

NUMA:NUMA是多核心CPU架构中的一种,其全称为Non-Uniform
Memory Access。简单来说就是在多核心CPU中。机器的物理内存是分配给各个核的。架构简图例如以下所看到的:

每一个核訪问分配给自己的内存会比訪问分配给其他核的内存要快。有以下几种訪问控制策略:

  • 1.缺省(default):总是在本地节点分配(分配在当前进程执行的节点上);
  • 2.绑定(bind):强制分配到指定节点上。
  • 3.交叉(interleave):在全部节点或者指定的节点上交织分配;
  • 4.优先(preferred):在指定节点上分配,失败则在其它节点上分配。

上面文章中最后使用numactl –interleave命令就是指定其为交叉共享模式。

irqbalance:这是作者在上面提到的一个占用CPU的进程。这个进程的作用是在多核心CPU的操作系统中,分配系统中断信号的。

參见:irqbalance.org

概念说完了。以下是上面问题的简单描写叙述:

我们知道虚拟内存机制是通过一个中断信号来通知虚拟内存系统进行内存swap的,所以这个irqbalance进程忙。是一个危急信号。在这里是因为在进行频繁的内存交换。这样的频繁交换现象称为swap insanity,在MySQL中常常提到。也就是在NUMA框架中。採用不合适的策略,导致核心仅仅能从指定内存块节点上分配内存,即使总内存还有富余,也会因为当前节点内存不足时产生大量的swap操作。

对于NUMA。进一步了解能够參考:NUMA与英特尔下一代Xeon处理器 和MySQL单机多实例方案 两篇文章

mongodb性能问题及原理分析的更多相关文章

  1. mongodb基本命令,mongodb集群原理分析

    mongodb基本命令,mongodb集群原理分析 集合: 1.集合没有固定数据格式. 2. 数据: 时间类型: Date() 当前时间(js时间) new Date() 格林尼治时间(object) ...

  2. 基于Lucene查询原理分析Elasticsearch的性能

    前言 Elasticsearch是一个很火的分布式搜索系统,提供了非常强大而且易用的查询和分析能力,包括全文索引.模糊查询.多条件组合查询.地理位置查询等等,而且具有一定的分析聚合能力.因为其查询场景 ...

  3. 性能测试之数据库监控分析工具PMM

    PMM(Percona Monitoring and Management) 是一个用于管理和监控数据库性能的开源平台. . 它能提供全面的基于时间和各类监控指标.计数器的分析. 性能测试中,是做数据 ...

  4. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  5. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  6. MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划

    这篇文章主要介绍了MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划的相关资料,需要的朋友可以参考下 一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存 ...

  7. paip.性能跟踪profile原理与架构与本质-- python扫带java php

    paip.性能跟踪profile原理与架构与本质-- python扫带java php ##背景 弄个个输入法音标转换atiEnPH工具,老是python性能不的上K,7k记录浏览过k要30分钟了. ...

  8. web压测工具http_load原理分析

    一.前言 http_load是一款测试web服务器性能的开源工具,从下面的网址可以下载到最新版本的http_load: http://www.acme.com/software/http_load/ ...

  9. MongoDB 性能优化五个简单步骤

    MongoDB 一直是最流行的 NoSQL,而根据 DB-Engines Ranking 最新的排行,时下 MongoDB 已经击败 PostgreSQL 跃居数据库总排行的第四位,仅次于 Oracl ...

随机推荐

  1. 初识JdbcTemplate

    1.spring配置文件里注冊:參照使用 Spring jdbcTemplate 进一步简化 JDBC 操作 2.写javabean 3.写rowmapper(依据javabean来封装结果集) 4. ...

  2. RTOS系统与Linux系统的区别

    RTOS是实时操作系统 Linux是时分系统,不过可以通过配置内核改成实时系统 分时操作系统 英文:Time-sharing Operating System  释义:使一台计算机同时为几个.几十个甚 ...

  3. RequireJS全面讲解

    异步模块定义(AMD)  谈起RequireJS,你无法绕过提及JavaScript模块是什么,以及AMD是什么. JavaScript模块只是遵循SRP(Single Responsibility  ...

  4. 解读Spark Streaming RDD的全生命周期

    本节主要内容: 一.DStream与RDD关系的彻底的研究 二.StreamingRDD的生成彻底研究 Spark Streaming RDD思考三个关键的问题: RDD本身是基本对象,根据一定时间定 ...

  5. Java中的值传递与“引用传递”

    首先,Java没有 引用传递 这么一说. Java仅仅有值传递.传递的都是值,基本数据类型传递的是值.引用类型传递的是地址值. 我来理一下这当中宛如米线跟米面绞在一起了,再跟粉丝混在一起的关系. 好的 ...

  6. TreeView 拖拽 增删改

    using Endv.Tools; using System; using System.Data; using System.Drawing; using System.IO; using Syst ...

  7. perl学习笔记——哈希

    哈希 哈希是一种数据结构,它和数组的相似之处在于可以容难任意多的值并能按需取用,而他和数组的不同在于索引的方式,数组是以数字为索引而哈希则是以名字为索引. 哈希的键是唯一的,哈希的值可以重复. 哈希的 ...

  8. wifi破解到局域网渗透

    本文转自 _博客 一,密码破解 wifi破解最主要的还是抓握手包破解(不要给我说某某钥匙的“分享”). wifi认证主要分为四步: 1,无线客户端与ap连接时,首先发送一个认证请求包 2,ap收到请求 ...

  9. NSDate 问题

    类型 比特数 有效数字 数值范围 float 32 6-7 -3.4*10(-38)-3.4*10(38) double 64 15-16 -1.7*10(-308)-1.7*10(308) long ...

  10. C++ 和 java 使用 AES CBC 128 加解密

    Java 使用jce, code: import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax ...