Что произойдет, если в MongoDB слишком много вставок? Как обеспечить сохранение всех данных?

24

Я использую MongoDB для хранения периодически измеренных значений. Каждые ~ 100 мс связка значений вставляется как документ. Это отлично работает, но я беспокоюсь о проблемах производительности. (Я использую безопасные вставки, кажется, что в PyMongo это по умолчанию.)

Что произойдет, если число вставок в секунду больше, чем mongod может сохранить на жесткий диск? Будет ли какое-нибудь предупреждение или он просто молча провалится?

Есть ли способ контролировать загрузку записи? Я нашел только то, db.serverStatus().writeBacksQueuedчто всегда устанавливается в ложь, когда я звоню. Как я могу проверить, сколько данных мне нужно вставить, чтобы заполнить очередь записи?

mongostatотображает замки. Это то, что я должен беспокоиться?

insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
  *117     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:6.5%          0       0|0     0|0   124b     6k     2  SLV   09:58:10 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:0.8%          0       0|0     0|0   124b     6k     2  SLV   09:58:11 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:4.2%          0       0|0     0|0   124b     6k     2  SLV   09:58:1

Должен ли я беспокоиться о блокировках записи? Что происходит со вставкой в ​​течение периода блокировки записи? Это поставлено в очередь и сохранено позже?

Я думаю о простой настройке репликации с использованием одного главного и одного подчиненного. Начальная синхронизация или процесс повторной синхронизации блокируют базы данных?

(Я использую версию 2.4.3.)

Обновление: я думаю, что частично ответил на мой собственный вопрос. Мне удалось получить до 12.000 вставок в секунду, используя простой цикл while для вставки небольшого тестового документа. Но qr | qw по-прежнему показывает, что там очередь на чтение и запись по-прежнему пуста:

insert  query update delete getmore command flushes mapped  vsize    res faults       locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
 11234     *0      2     *0    1563     1|0       1  21.9g  44.3g  1.22g      0    testdb:58.9%          0       1|0     1|1   797k   980k     6  PRI   10:26:32 
 12768     *0      2     *0    1284     1|0       0  21.9g  44.3g  1.22g      0    testdb:58.0%          0       0|0     0|1   881k     1m     6  PRI   10:26:33 
 12839     *0      2     *0    1231     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.3%          0       0|0     0|1   883k     1m     6  PRI   10:26:34 
 12701     *0      2     *0     910     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   858k     1m     6  PRI   10:26:35 
 12241     *0      2     *0    1206     1|0       0  21.9g  44.3g  1.22g      0    testdb:56.7%          0       0|0     0|0   843k     1m     6  PRI   10:26:36 
 11581     *0      2     *0    1406     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   811k     1m     6  PRI   10:26:37 
  8719     *0      2     *0    1210     1|0       0  21.9g  44.3g  1.22g      0    testdb:43.8%          0       0|0     0|1   618k   762k     6  PRI   10:26:38 
 11429     *0      2     *0    1469     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.6%          0       0|0     0|1   804k   993k     6  PRI   10:26:39 
 12779     *0      2     *0    1092     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.2%          0       1|0     0|1   872k     1m     6  PRI   10:26:40 
 12757     *0      2     *0     436     1|0       0  21.9g  44.3g  1.22g      0    testdb:59.7%          0       0|0     0|1   838k   432k     6  PRI   10:26:41 

Я предполагаю, что это означает, что одна только вставка не вызовет много проблем: «Очереди будут иметь тенденцию к скачкам, если вы выполняете много операций записи наряду с другими операциями записи с большими объемами операций, такими как операции удаления с большим диапазоном». (найдено здесь )

Мой открытый вопрос: что произойдет с моими данными, если очередь записи увеличится в долгосрочной перспективе?

lumbric
источник

Ответы:

25

Вы ответили на некоторые свои вопросы здесь, в частности, у вас есть хорошее представление об аспекте блокировки записи в уравнении - 12000 вставок / сек дает вам ~ 60% блокировки записи. Это разумный уровень для получения стабильной производительности - вы будете испытывать некоторое раздор, а некоторые операции будут немного медленнее, но вы действительно хотите начать беспокоиться примерно на 80% - как многие вещи, когда вы начинаете превышать 80% доступных емкость вы начнете чаще сталкиваться с проблемами.

Что касается других узких мест, в частности, как быстро вы можете записывать на диск - это может вызвать проблемы, но чтобы посмотреть соответствующую статистику с течением времени, я бы порекомендовал установить MMS с плагином munin-node, чтобы предоставить вам аппаратную и IO статистику в дополнение к статистике MongoDB.

Когда у вас есть это, показатели, которые вы хотите следить, являются:

  • Среднее время сброса (это время, которое занимает периодическая синхронизация MongoDB с диском)
  • IOStats на вкладке оборудования (IOWait в частности)
  • Сбои страниц (если ваш диск занят записью и вам нужно прочитать данные, они будут конкурировать за дефицитный ресурс)

Это немного сложно, но вот основная идея:

  • Когда среднее время промывки начинает увеличиваться, беспокойтесь
  • Если он попадает в диапазон нескольких секунд, вы, вероятно, находитесь на пределе (хотя это зависит от объема записанных данных и скорости диска)
  • Если оно приблизится к 60 секундам, вы увидите, что производительность резко снизится (сброс происходит каждые 60 секунд, поэтому они, по сути, будут в очереди)
  • Высокий IOWait также может снизить производительность, особенно если вам нужно читать с диска в любой момент
  • Следовательно, рассмотрение уровней сбоев страниц также будет важно

Другая часть этой загадки, о которой мы еще не упомянули, это журнал. Это будет также сохранение данных на диск (по умолчанию каждые 100 мс), и поэтому оно будет увеличивать нагрузку на диск, если он находится на том же томе. Следовательно, если вы видите высокую загрузку диска, то перенос журнала на другой диск был бы хорошей идеей.

Там нет реальных «магических чисел», чтобы остаться под, в большинстве случаев это все относительно, так что получить хорошую базовую линию для вашего нормального трафика, проверьте, если вещи растут, и, возможно, нагрузочный тест, чтобы увидеть, каковы ваши ограничения и когда вещи начать ухудшаться, и вы будете в хорошей форме.

После всего этого предварительного, на некоторые из ваших вопросов:

Что произойдет, если число вставок в секунду больше, чем mongod может сохранить на жесткий диск? Будет ли какое-нибудь предупреждение или он просто молча провалится?

Если вы начнете нагружать диск до уровней, описанных выше, в конечном итоге все будет замедляться, и в какой-то момент (и это будет зависеть от тайм-аутов, от того, насколько мощным является ваше оборудование, как вы обрабатываете исключения), ваши записи прервутся - если вы используете последнюю версию pymongo, тогда вы будете использовать безопасные записи по умолчанию, и тогда они потерпят неудачу. Если вы хотите быть немного более параноиком, вы можете время от времени делать запись j: true, которая будет ждать возвращения OK, пока запись не будет сделана в журнал (то есть на диск). Это, конечно, будет медленнее, чем обычная безопасная запись, но это будет немедленное указание на проблемы, связанные с емкостью диска, и вы можете использовать его для блокировки / постановки в очередь других операций и, по сути, действовать как дроссель, чтобы предотвратить работу вашей базы данных. перегружены.

Я думаю о простой настройке репликации с использованием одного главного и одного подчиненного. Начальная синхронизация или процесс повторной синхронизации блокируют базы данных?

Я думаю, что вначале я рассмотрел блокировку в целом, но чтобы ответить на этот вопрос конкретно: во-первых, убедитесь, что вы используете набор реплик , а не master / slave. Реализация master / slave устарела и не рекомендуется для использования в целом. Что касается начальной синхронизации, это добавит некоторую нагрузку на первичную систему с точки зрения чтения, но не с точки зрения записи, поэтому с блокировкой все должно быть в порядке.

Что происходит с моими данными, если очередь записи увеличивается в долгосрочной перспективе?

Как вы, вероятно, можете понять из приведенного выше объяснения, ответ во многом зависит от того, как вы пишете свое заявление, как вы хотите, чтобы ваши записи были подтверждены, и сколько у вас есть возможностей. По сути, вы можете быть настолько безопасны, насколько хотите, когда дело доходит до записи на диск в MongoDB, но есть компромисс производительности, как упомянуто в j:trueобсуждении выше.

Как правило, вы хотите выяснить свой ограничивающий фактор - будь то блокировка, скорость диска и т. Д., А затем отслеживать уровни с течением времени и масштабировать (разделять) или увеличивать (улучшать аппаратное обеспечение), прежде чем вы достигнете жесткого предела и увидите проблемы с производительностью.

И последнее: db.serverStatus().writeBacksQueuedфактически метрика, которая когда-либо будет отлична от нуля в изолированной среде, связана с тем, что записи в чанк во время миграции обрабатываются надлежащим образом (обрабатывается слушателем обратной записи ). Следовательно, это, по сути, красная сельдь - ничего общего с объемом записи.

Адам С
источник