问题

线上应用服务的连接MongoDB经常出现timeout,然后应用服务查MongoDB服务请求夯住不动。请求夯住在请求mongoDB导致mongoDB 服务crash。

调查

前期调查方向:

  1. 导出slow query log,发现有些没有加索引的collection,全表扫描。加上索引在观察。还是出现请求夯住问题。
  2. 升级mongoDB主机服务配置,观察还是有问题。
  3. 因为我们碰不到线上mongoDB机器,我只能通过prometheus指标组合mongostat请求信息。

因为没有搞mongostat,但是做了mongodb_exporter metrics采集。通过mongostat文档看到了指标的计算逻辑,发现dirty和used达到一定阈值会阻塞新请求。

mongostat 指标详细

dirty

Only for WiredTiger Storage Engine. The percentage of the WiredTiger cache with dirty bytes, calculated by wiredTiger.cache.tracked dirty bytes in the cache / wiredTiger.cache.maximum bytes configured.

used

Only for WiredTiger Storage Engine. The percentage of the WiredTiger cache that is in use, calculated by wiredTiger.cache.bytes currently in the cache / wiredTiger.cache.maximum bytes configured.

prometheus计算逻辑

wiretiger存储引擎的缓冲中脏字节的百分比

dirty= mongodb_ss_wt_cache_tracked_dirty_bytes_in_the_cache{instance=”x.x.x.x”} / mongodb_ss_wt_cache_maximum_bytes_configured{instance=”x.x.x.x”} * 100

已经使用的wiretiger存储引擎缓存比例

used= (mongodb_ss_wt_cache_bytes_currently_in_the_cache{instance=”x.x.x.x”} / mongodb_ss_wt_cache_maximum_bytes_configured{instance=”x.x.x.x”}) * 100

正在执行的读取文档个数与正在执行的写入文档个数

ar = mongodb_ss_globalLock_activeClients_readers{instance=”x.x.x.x”}
aw = mongodb_ss_globalLock_activeClients_writers {instance=”x.x.x.x”}

正在执行请求全部数量

at= mongodb_ss_globalLock_activeClients_total{instance=”x.x.x.x”}

等待读取的文档个数与等待写入的文档个数

qw = mongodb_ss_globalLock_currentQueue{instance=”x.x.x.x”,count_type=”writers”}
qr = mongodb_ss_globalLock_currentQueue{instance=”x.x.x.x”,count_type=”readers”}

等待请求全部数量

qt= mongodb_ss_globalLock_currentQueue{instance=”x.x.x.x”,count_type=”total”}

结论

发现used平均值在90%以上。然后再去看mongo的cache size居然只给了1G。然后让DBA 设置了(主机内存 -1)*50%大小。请求夯住问题解决。