MongoDB中的插入率不稳定

时间:2019-01-16 06:32:14

标签: mongodb nosql crud

我有一个过程,每秒可以生成2万条记录(记录大小〜30Kb)。我试图将它们尽可能快地插入到MongoDB的单个实例中。但是我每秒获得约1500次插入,不稳定速率介于每秒1000次插入到2000次插入之间。问题是什么原因以及如何解决它? :)这是mongostat中2.5小时的数据:

设置

我正在云中运行具有8核,16Gb RAM,150Gb HDD,Ubuntu 18.04,MongoDB 4.0 official docker image}的实例。在同一个实例上,运行2个工作程序,每个工作程序每秒生成10000条记录,并将它们insert_many cases每个MongoDB 100条记录中。每个记录分为两个集合docsdocscases使用zlib压缩。 {'info': {'judge': 'Орлова Олеся Викторовна', 'decision': 'Отменено с возвращением на новое рассмотрение', 'entry_date': datetime.datetime(2017, 1, 1, 0, 0), 'number': '12-48/2017 (12-413/2016;)', 'decision_date': datetime.datetime(2017, 2, 9, 0, 0)}, 'acts': [{'doc': ObjectId('5c3c76543d495a000c97243b'), 'type': 'Решение'}], '_id': ObjectId('5c3c76543d495a000c97243a'), 'sides': [{'name': 'Кузнецов П. В.', 'articles': 'КоАП: ст. 5.27.1 ч.4'}], 'history': [{'timestamp': datetime.datetime(2017, 1, 1, 15, 6), 'type': 'Материалы переданы в производство судье'}, {'timestamp': datetime.datetime(2017, 2, 9, 16, 0), 'type': 'Судебное заседание', 'decision': 'Отменено с возвращением на новое рассмотрение'}, {'timestamp': datetime.datetime(2017, 2, 17, 15, 6), 'type': 'Дело сдано в отдел судебного делопроизводства'}, {'timestamp': datetime.datetime(2017, 2, 17, 15, 7), 'type': 'Вручение копии решения (определения) в соотв. с чч. 2, 2.1, 2.2 ст. 30.8 КоАП РФ'}, {'timestamp': datetime.datetime(2017, 3, 13, 16, 6), 'type': 'Вступило в законную силу'}, {'timestamp': datetime.datetime(2017, 3, 14, 16, 6), 'type': 'Дело оформлено'}, {'timestamp': datetime.datetime(2017, 3, 29, 14, 33), 'type': 'Дело передано в архив'}], 'source': {'date': datetime.datetime(2017, 1, 1, 0, 0), 'engine': 'v1', 'instance': 'appeal', 'host': 'bratsky.irk.sudrf.ru', 'process': 'adm_nar', 'crawled': datetime.datetime(2018, 12, 22, 8, 15, 7), 'url': 'https://bratsky--irk.sudrf.ru/modules.php?name=sud_delo&srv_num=1&name_op=case&case_id=53033119&case_uid=A84C1A34-846D-4912-8242-C7657985873B&delo_id=1502001'}, 'id': '53033119_A84C1A34-846D-4912-8242-C7657985873B_1_'} 记录的平均大小约为1Kb。以随机记录为例:

docs

{'_id': ObjectId('5c3c76543d495a000c97243b'), 'data': 'PEhUTUw+PEhFQUQ+DQo8TUVUQSBodHRwLWVxdWl2PUNvbnRlbnQtVHlwZSBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9V2luZG93cy0xMjUxIj4NCjxTVFlMRSB0eXBlPXRleHQvY3NzPjwvU1RZTEU+DQo8L0hFQUQ+DQo8Qk9EWT48U1BBTiBzdHlsZT0iVEVYVC1BTElHTjoganVzdGlmeSI+DQo8UCBzdHlsZT0iVEVYVC1JTkRFTlQ6IDAuNWluOyBURVhULUFMSUdOOiBjZW50ZXIiPtCgINCVINCoINCVINCdINCYINCVPC9QPg0KPFAgc3R5bGU9IlRFWFQtSU5ERU5UOiAwLjVpbjsgVEVYVC1BTElHTjoganVzdGlmeSI+0LMuINCR0YDQsNGC0YHQuiAwOSDRhNC10LLRgNCw0LvRjyAyMDE3INCz0L7QtNCwPC9QPg0KPFAgc3R5bGU9IlRFWFQtSU5ERU5UOiAwLjVpbjsgVEVYVC1BTElHTjoganVzdGlmeSI+0KHRg9C00YzRjyDQkdGA0LDRgtGB0LrQvtCz0L4g0LPQvtGA0L7QtNGB0LrQvtCz0L4g0YHRg9C00LAg0JjRgNC60YPRgtGB0LrQvtC5INC+0LHQu9Cw0YHRgtC4INCe0YDQu9C+0LLQsCDQni7Qki4sINGA0LDRgdGB0LzQvtGC0YDQtdCyINCw0LTQvNC40L3QuNGB0YLRgNCw0YLQuNCy0L3QvtC1INC00LXQu9C+IOKEliAxMi00OC8yMDE3INC/0L4g0LbQsNC70L7QsdC1INC40L3QtNC40LLQuNC00YPQsNC70YzQvdC+0LPQviDQv9GA0LXQtNC/0YDQuNC90LjQvNCw0YLQtdC70Y8g0JrRg9C30L3QtdGG0L7QstCwIDxTUE.....TlQ6IDAuNWluOyBURVhULUFMSUdOOiBqdXN0aWZ5Ij7QoNC10YjQtdC90LjQtSDQvNC+0LbQtdGCINCx0YvRgtGMINC+0LHQttCw0LvQvtCy0LDQvdC+INCyINCY0YDQutGD0YLRgdC60LjQuSDQvtCx0LvQsNGB0YLQvdC+0Lkg0YHRg9C0INCyINGC0LXRh9C10L3QuNC1IDEwINGB0YPRgtC+0Log0YEg0LzQvtC80LXQvdGC0LAg0L/QvtC70YPRh9C10L3QuNGPINC10LPQviDQutC+0L/QuNC4LjwvUD4NCjxQIHN0eWxlPSJURVhULUlOREVOVDogMC41aW47IFRFWFQtQUxJR046IGp1c3RpZnkiPtCh0YPQtNGM0Y8g0J4u0JIuINCe0YDQu9C+0LLQsDwvUD48L1NQQU4+PC9CT0RZPjwvSFRNTD4=', 'extension': '.html'} 记录平均约为30Kb:

docker stats

分析

要弄清楚发生了什么,我使用mongostatCPU %。关键指标突出显示:

我在数据插入期间收集了2.5小时的指标,并从上图绘制了insertdirtycpu

人们可以看到,当脏率达到20%时,插入率会下降,而当脏率低于20%时,插入率会上升到〜2000:

当CPU处于活动状态时,脏污会减少。可以看到,当dirty大约为300%时,docker stats开始下降(由于mongostatcpu分开运行,因此病情有所降低),当{{ 1}}是200%,dirty回到20%,插入速度变慢:

问题

  1. 我的分析正确吗?这是我第一次使用MongoDB,所以我可能是错的
  2. 如果分析正确,为什么MongoDB并不总是使用300%+的CPU(实例具有8个内核)来保持dirty低和高插入率?是否可以强迫它这样做,这是解决我的问题的正确方法吗?

更新

也许HDD IO是个问题?

我没有记录IO使用率,但是

  1. 我记得在插入过程中查看了cloud.mongodb.com/freemonitoring,有一个图叫做“磁盘利用率”,最大为50%
  2. 当前,我的问题是插入率不稳定性。我目前每秒最多2000次插入就可以了。这意味着当前的HDD可以解决这个问题,对吗?我不明白为什么定期插入率会下降到1000。

分片时

目前,我正在尝试在单台计算机上达到最高性能

解决方案

只需将HDD更改为SSD。

之前: before

之后: after

在每秒〜1500次插入的情况下,脏度稳定在〜5%。插入和CPU使用率现在稳定。这是我期望看到的行为。 SSD从此问题的标题“ MongoDB中的不稳定插入率”解决了问题

1 个答案:

答案 0 :(得分:0)

使用更好的磁盘肯定会提高性能。您还可以监视其他指标。

  • 脏字节百分比表示数据已在wiredTiger缓存中修改,但尚未持久保存到磁盘。如果磁盘IOPS达到预配置的限制,则应对其进行监视。使用命令iostat监视MongoDB FTDC数据或从中获取数据。
  • 当CPU出现峰值时,请监视是否在 iowait 上花费了CPU时间。如果 iowait%很高,则表示您有I / O阻止,即更快的磁盘或更多的IOPS将有所帮助。
  • mongostat输出监视 qrw (排队的读写请求)和 arw (活动的读写请求)。如果这些数字仍然像示例输出一样低,尤其是 qrw ,则mongo可以支持您的请求而无需排队。
  • 通过将注入工作转移到其他实例来避免资源竞争。
  • 您可以使用不同的磁盘分区进一步优化mongo数据路径和日志位置。
  • 观察者通常会忽略客户(饮食工作者)的表现。 CPU峰值可能来自您的工作人员,因此吞吐量较低。使用top命令或等效命令监视客户端性能。

希望以上帮助。