У меня есть процесс, который может генерировать 20 000 записей в секунду (размер записи ~ 30 КБ). Я пытаюсь вставить их как можно быстрее в один экземпляр MongoDB. Но я получаю ~ 1500 вставок в секунду с нестабильной скоростью, которая варьируется от 1000 вставок до 2000 вставок в секунду. Вопрос в чем причина и как это исправить? :) Вот данные от mongostat
за 2,5 часа:
![](https://i.stack.imgur.com/3P9XN.png)
Настройка
Я использую экземпляр в облаке с 8 ядрами, 16 ГБ ОЗУ, 150 ГБ HDD, Ubuntu 18.04, MongoDB 4.0 официальный образ докера . В одном и том же экземпляре запускается 2 рабочих, которые генерируют 10 000 записей в секунду каждый и insert_many
их в MongoDB 100 записей на блок. Каждая запись разбита на 2 коллекции cases
и docs
, docs
использует сжатие zlib. cases
размер записи составляет в среднем ~ 1 КБ. Случайная запись в качестве примера:
{'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_'}
docs
запись в среднем составляет ~ 30 КБ:
{'_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'}
Анализ
Чтобы выяснить, что происходит, я использую docker stats
и mongostat
. Ключевые показатели выделены:
![](https://i.stack.imgur.com/jL20s.png)
Я собираю метрики за 2,5 часа при вставке данных и графике CPU %
, insert
, dirty
из рисунков выше:
![](https://i.stack.imgur.com/W8Yjs.png)
Видно, что скорость вставки падает, когда уровень загрязнения достигает 20%, и увеличивается до ~ 2000, если уровень загрязнения ниже 20%:
![](https://i.stack.imgur.com/XDF9F.png)
Грязь снижается, когда процессор активен. Можно видеть, что, когда cpu
составляет ~ 300%, dirty
начинает снижаться (графики немного устарели, так как docker stats
и mongostat
работают отдельно), когда cpu
составляет 200%, dirty
растет обратно до 20% и вставки замедляются:
![](https://i.stack.imgur.com/UgeBh.png)
Вопрос
- Мой анализ верен? Я впервые использую MongoDB, поэтому могу ошибаться
- Если анализ верен, почему MongoDB не всегда использует 300% + ЦП (экземпляр имеет 8 ядер) для поддержания
dirty
низкого уровня и высокой скорости вставки? Можно ли заставить его сделать это и правильно ли я решил мою проблему?
Обновление
Может быть, проблема с IO HDD?
Я не регистрировал использование ввода-вывода, но
- Я помню, что просматривал cloud.mongodb.com/freemonitoring во время процесса вставки, там есть сюжет под названием «Disk Utilization», он был максимум 50%
- В настоящее время моей проблемой является скорость вставки нестабильность . Я в порядке с текущими 2000 вставками в секунду макс. Это означает, что нынешний жесткий диск может справиться с этим, верно? Я не понимаю, почему периодически вставлять скорость падает до 1000.
На шардинге
В настоящее время я пытаюсь достичь максимальной производительности на одной машине
Решение
Просто измените HDD на SSD.
До:
![before](https://i.stack.imgur.com/9m2Vc.png)
После того, как:
![after](https://i.stack.imgur.com/fADxk.png)
При тех же ~ 1500 вставках в секунду, грязь стабильна на уровне ~ 5%. Вставки и загрузка процессора теперь стабильны. Это поведение, которое я ожидал увидеть. SSD решает проблему из заголовка этого вопроса «Нестабильная скорость вставки в MongoDB»