Що станеться, якщо в 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 вставок за секунду, використовуючи простий цикл, вставивши невеликий тестовий документ. Але 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 

Я вважаю, що це означає, що окремі вставки не спричинять багато клопотів: "Черги, як правило, шиплять, якщо ви робите багато операцій з записом поряд з іншими великими операційними записами, такими як видалення великих значень". (знайдено тут ]

Моє відкрите запитання: Що станеться з моїми даними, якщо черга запису збільшується на тривалий термін?

Відповіді:


25

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

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

Коли у вас це є, показники, про які ви хочете стежити, це:

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

Це трохи складніше, але ось основна ідея:

  • Коли середній час промивання починає збільшуватися, хвилюйтеся
  • Якщо він потрапляє в діапазон декількох секунд, ви, ймовірно, на межі (хоча це залежить від обсягу записаних даних та швидкості диска)
  • Якщо наблизиться до 60 секунд, ви побачите, що продуктивність сильно погіршиться (флеш трапляється кожні 60 секунд, тому вони по суті будуть стояти в черзі)
  • Високий IOWait також буде перешкоджати продуктивності, особливо якщо вам доведеться читати з диска в будь-який момент
  • Отже, важливо також переглянути рівні помилок сторінки

Інший фрагмент цієї головоломки, про який ми ще не згадували, - це журнал. Це також буде зберігати дані на диску (за замовчуванням кожні 100 мс), і тому він буде додавати до навантаження диска, якщо він буде на тому ж обсязі. Отже, якщо ви бачите високу завантаженість диска, то переміщення журналу на інший диск було б хорошою ідеєю.

Немає справжніх "магічних цифр", на яких слід залишатись, у більшості випадків це все відносно, тому отримайте хорошу базову лінію для вашого звичайного трафіку, перевірте, чи є в тренді, і, можливо, завантажуйте тест, щоб побачити, які ваші обмеження і коли речі почніть деградувати, і ви будете в хорошій формі.

Зрештою, це попереднє повідомлення про деякі ваші запитання:

Що станеться, якщо вкладишів більше в секунду, ніж mongod здатний зберігати на жорсткому диску? Чи буде якесь попередження або воно просто мовчки вийде з ладу?

Якщо ви почнете напружувати диск до рівня, описаного вище, врешті-решт все сповільниться і в якийсь момент (а це буде залежати від тайм-аутів, наскільки надійний ваш апарат, як ви обробляєте винятки), ваше записування не вдасться - якщо ви користуєтеся останньою версією pymongo, тоді ви будете використовувати безпечні записи за замовчуванням, і ті потім не вдасться. Якщо ви хочете бути трохи параноїднішим, ви можете час від часу зайнятися запитанням j: true, яке буде чекати, коли повернеться ОК, поки запис не зробить це в журналі (тобто на диску). Це, звичайно, буде повільніше, ніж звичайне безпечне записування, але це буде негайною вказівкою на проблеми, пов’язані з ємністю диска, і ви можете використовувати його для блокування / черги інших операцій і, по суті, діяти як дросель, щоб запобігти створенню вашої бази даних переповнений.

Я думаю про просту настройку реплікації, використовуючи одного ведучого та одного підлеглого. Чи блокує базу даних початкова синхронізація чи процес повторної синхронізації?

Я думаю, що на початку я загалом охоплював блокування, але щоб відповісти на цю деталь конкретно: По-перше, переконайтеся, що ви використовуєте набір реплік , а не master / slave. Реалізація головного / підлеглого застаріла і не рекомендується для використання загалом. Що стосується початкової синхронізації, додасть деяке навантаження до основного з точки зору читання, але не з точки зору запису, тож вам слід добре в частині блокування.

Що відбувається з моїми даними, якщо черга запису збільшується на тривалий термін?

Як ви, напевно, можете сказати з пояснення, поданого вище, відповідь дуже залежить від того, як ви пишете заявку, як ви вирішили визнати свої записи та наскільки ємність у вас є. По суті, ви можете бути настільки ж безпечними, як хочете, якщо мова заходить про запис на диск на MongoDB, але є компроміс продуктивності, про що говорилося в j:trueдискусії вище.

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

І останнє, що db.serverStatus().writeBacksQueuedнасправді - це показник, який коли-небудь буде ненульовим у затіненому середовищі, і це стосується того, щоб переконатися, що записи на шматок під час міграції розглядаються належним чином (обробляється слухачем запису ). Отже, це по суті червона оселедець - нічого спільного з загальним обсягом запису.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.