У меня есть процесс, который может генерировать 20 000 записей в секунду (размер записи ~ 30 КБ). Я пытаюсь как можно быстрее вставить их в один экземпляр MongoDB. Но я получаю ~ 1500 вставок в секунду с нестабильной скоростью, которая колеблется от 1000 до 2000 вставок в секунду. Вопрос в том, в чем причина и как исправить? :) Вот данные с mongostat за 2,5 часа:

Настраивать
Я запускаю экземпляр в облаке с 8 ядрами, 16 ГБ ОЗУ, 150 ГБ жесткого диска, 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. Выделены ключевые показатели:


Я собираю метрики в течение 2,5 часов во время ввода данных и строю графики CPU %, insert, dirty из изображений выше:

Видно, что скорость вставки падает, когда грязь достигает пика 20%, и достигает ~ 2000, когда грязь ниже 20%:

Dirty отключается, когда ЦП активен. Видно, что когда cpu составляет ~ 300%, dirty начинает снижаться (графики немного не в порядке, так как docker stats и mongostat работают отдельно), когда cpu составляет 200%, dirty вырастает до 20%, а вставки замедляются:

Вопрос
dirty и высокую скорость вставки? Можно ли заставить его сделать это и правильно ли это решить мою проблему?Обновлять
Может быть, проблема с вводом-выводом жесткого диска?
Я не регистрировал использование ввода-вывода, но
О шардинге
В настоящее время я пытаюсь достичь максимальной производительности на одной машине
Решение
Просто поменяйте HDD на SSD.
При тех же ~ 1500 вставок в секунду загрязнение стабильно на уровне ~ 5%. Вставки и загрузка процессора теперь стабильны. Это то поведение, которое я ожидал увидеть. SSD решает проблему из заголовка этого вопроса «Нестабильная скорость вставки в MongoDB»
Согласитесь с @RobbyCornelissen здесь. Дисковый ввод-вывод играет большую роль. Кроме того, мы перешли на SSD с жесткого диска и заметили 10-кратное изменение производительности. Для insertMany я использую от 500 - 1000 сразу вставлять. Когда я тестировал свой сервер, я увидел около 30 тысяч вставок за 5-6 секунд. Вам также следует рассмотреть возможность кластеризации и сегментирования, если вы собираетесь получать 10 000 записей в секунду.
Спасибо за ответ, добавлен раздел «Обновление» в ответ на ваши вопросы. В основном речь идет о нестабильность. Я вижу, что система может делать 2000 вставок в секунду. В настоящее время меня это устраивает. Это значит, что нынешний жесткий диск с этим справится, не так ли? Вопрос в том, почему периодически скорость вставки падает до 1000
У Mongodb или любого другого сервера также будут свои служебные задачи. ЦП и диск тоже заняты этими задачами. Если вы хотите узнать больше о том, что происходит, журналы mongodb - это то, что вам нужно. Вы также можете установить уровни детализации. Используйте db.setLogLevel () по вашему выбору, как указано в docs.mongodb.com/manual/reference/log-messages
Я бы попытался использовать для сжатия snappy, а не zlib - это с меньшей вероятностью вызовет проблемы и отклонения. И я согласен с @simagix проверить ваш iowait.

Использование более качественного диска определенно улучшит производительность. Есть и другие показатели, за которыми вы можете следить.
iostat для мониторинга или получения данных из MongoDB FTDC.mongostat. Если эти числа остаются низкими, как ваш пример вывода, особенно qrw, mongo сможет поддерживать ваши запросы без очереди запросов.top или ее эквивалента.Надеюсь, что это поможет.
Большое спасибо, замена жесткого диска на SSD решила мою проблему. Обновил вопрос, описал свои наблюдения в разделе «Решение»
Я ожидал, что узким местом здесь будет дисковый ввод-вывод, а не процессор.