诊断 mongodb 主要故障和不稳定行为

诊断 mongodb 主要故障和不稳定行为

我们有一个 mongodb 实例运行在 amazon ec2 大型 (7.5GB) ubuntu 实例上(我们的 node.js 服务器运行在同一台机器上)。最近流量增加了很多,我们开始看到 mongodb 的一些不稳定行为。当前状态:

我们在使用分析器时注意到了一些速度很慢的查询:

query   mydb.user 1327ms Wed Aug 01 2012 14:01:39
query:{ "_id" : ObjectId("500f45486562e7053d070363") } idhack responseLength:178 client:127.0.0.1 user: 

用户表中的条目很少,但表中大约有 5000 万个条目。这种情况每隔一两分钟就会发生一次,随后会出现一系列慢查询。当我们使用 命令行执行慢查询时explain(),不会报告任何异常。

mongostat告诉我:

insert  query update delete getmore command flushes mapped  vsize    res faults locked % idx miss %     qr|qw   ar|aw  netIn netOut  conn   set repl       time
138    804      9      0      96      36       0  60.2g   121g  3.42g      2      1.8          0       0|0     1|0    93k   479k    19 fgset    M   14:15:59
94    755      4      0      71      35       0  60.2g   121g  3.41g      0      1.5          0       0|0     1|0    78k   344k    19 fgset    M   14:16:00
93     17      4      0      75      27       0  60.2g   121g  3.41g      0      1.2          0       0|0     1|0    24k    31k    19 fgset    M   14:16:01
87     86      6      0      73      33       0  60.2g   121g  3.41g      0      0.9          0       0|0     1|0    31k   260k    19 fgset    M   14:16:02
101    531      3      0      62      19       0  60.2g   121g  3.41g      0        1          0       0|0     1|0    60k     1m    19 fgset    M   14:16:03
92    713      2      0      66      24       0  60.2g   121g  3.41g      1      0.9          0       0|0     0|0    72k     1m    17 fgset    M   14:16:04
163     91      6      0      93      46       0  60.2g   121g  3.41g      2      9.5          0       0|0     1|0    44k   256k    17 fgset    M   14:16:05
108     62      6      0      79      38       0  60.2g   121g  3.41g      4      1.2          0       0|0     1|0    32k   122k    17 fgset    M   14:16:06
137     23      6      0      81      32       0  60.2g   121g  3.41g      0      2.3          0       0|0     0|0    32k    67k    17 fgset    M   14:16:07

pidstat -r -p <pid> 5告诉我:

02:18:01 PM      1700    647.00      0.80 126778144 3578036  46.80  mongod
02:18:06 PM      1700   1092.00      1.20 126778144 3586364  46.91  mongod
02:18:11 PM      1700    689.60      0.20 126778144 3578912  46.81  mongod
02:18:16 PM      1700    740.80      1.20 126778144 3577652  46.79  mongod
02:18:21 PM      1700    618.60      0.20 126778144 3578100  46.80  mongod
02:18:26 PM      1700    246.00      1.00 126778144 3577392  46.79  mongod

请注意,我们的数据库卷是单个 ext4 卷,而不是 raid 集受到推崇的

我不确定下一步该怎么做才能充分理解问题并实施修复。任何意见都值得赞赏。

答案1

我必须更仔细地观察一段时间内的趋势才能确定(彩信会有所帮助),但您可能遇到一个问题,即您已达到该实例上 MongoDB 的最大驻留内存 - 页面错误不是那么高,但我确实看到驻留内存略有下降。如果其他地方(来自另一个进程)存在内存压力,您可能会从 MongoDB 中逐出页面和/或不得不比应有的更频繁地将页面发送到磁盘(EBS 上的页面发送到磁盘非常慢)。

有几件事你可以做,以使你的 RAM 使用更加高效:

  1. 删除不必要的索引 - 如果使用它们,它们只会占用宝贵的 RAM - 适合删除的是单个索引,它们是其他地方的复合索引的最左边元素。这实际上取决于您的使用情况和架构,因此我只能提供一般性建议。
  2. 调整 EBS 卷上的预读向下- 这与您通常阅读到的关于调整 EBS 卷的内容相反,但当您的访问配置文件是随机的而不是顺序的时,预读设置得太高实际上会拖累内存使用。

要查看卷的预读设置,请运行此命令(需要 root/sudo 权限):

sudo blockdev --report

输出将列出如下内容:

RO    RA   SSZ   BSZ   StartSec            Size   Device
rw   256   512  4096          0     10737418240   /dev/xvda1

我们想在这里调整的是 RA 列(256,我相信这是亚马逊的默认设置)。您可以通过运行以下命令来执行此操作:

blockdev --setra <value> <device name>

对于上面的例子,我首先将值减半:

blockdev --setra 128 /dev/xvda1

我将更详细地介绍应该将此值设置多低以及其背后的原因这个答案如果您想了解更多信息。请注意,更改需要重新启动 mongod 进程才能生效。

完成上述两件事后,您可能能够从该 xlarge 实例的 RAM 中榨取更多性能。如果不能,或者内存压力来自其他地方,而效率不够高,那么是时候获得更多 RAM 了。

将 EBS 存储升级到 RAID 卷(如您所述)或使用新的预配置 IOPS 和 EBS 优化实例(或者如果你有足够的钱,可以使用 SSD 集群计算节点)将有助于解决操作中“缓慢”的部分(从磁盘分页),但没有什么能比得上内存操作的好处——即使磁盘子系统有所改进,它们仍然快一个数量级。

相关内容