Як налаштувати драйвер MongoDB Java MongoOptions для використання у виробництві?


100

Я шукав в Інтернеті пошуки кращих практик налаштування MongoOptions для драйвера Java MongoDB, і я не придумав багато іншого, крім API. Цей пошук розпочався після того, як я зіткнувся з помилкою "com.mongodb.DBPortPool $ SemaphoresOut: Поза семафорами, щоб отримати db-з'єднання", і завдяки збільшенню з'єднань / множника я зміг вирішити цю проблему. Я шукаю посилання на ваші найкращі практики щодо налаштування цих параметрів для виробництва.

Параметри драйвера 2.4 включають: http://api.mongodb.org/java/2.4/com/mongodb/MongoOptions.html

  • autoConnectRetry
  • з'єднанняPerHost
  • connectTimeout
  • maxWaitTime
  • socketTimeout
  • темиAllowedToBlockForConnectionMultiplier

У нових водіїв є більше варіантів, і мені було б цікаво почути про них також.

Відповіді:


160

Оновлено до 2,9:

  • autoConnectRetry просто означає, що драйвер автоматично спробує знову підключитися до сервера (ів) після несподіваних відключень. У виробничих середовищах зазвичай потрібно, щоб цей набір був істинним.

  • connectionPerHost - це кількість фізичних з'єднань, які один екземпляр Mongo (це синглтон, тому у вас зазвичай є одне на додаток) може встановити процес mongod / mongos. Під час написання драйвера Java встановить цю кількість з'єднань у кінцевому підсумку, навіть якщо фактична пропускна здатність запиту є низькою (для того, щоб слова ви побачили статистику "conn" у монгостаті, поки вона не досягне цього числа на сервері додатків).

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

    db.serverStatus().connections.available

    Зараз у виробництві це в 40.

  • connectTimeout . Як випливає з назви, кількість мілісекунд водій буде чекати, перш ніж спроба з'єднання буде перервана. Встановіть час очікування на щось тривале (15-30 секунд), якщо немає реальної, очікуваної ймовірності, що це призведе до успішних спроб з'єднання. Зазвичай, якщо спроба підключення триває більше двох секунд, ваша мережева інфраструктура не здатна забезпечити високу пропускну здатність.

  • maxWaitTime . Кількість мс потоку буде чекати, коли з'єднання стане доступним у пулі з'єднань, і підвищить виняток, якщо це не відбудеться вчасно. Тримайте за замовчуванням.

  • socketTimeout . Стандартне значення тайм-аута розетки. Встановити на 60 секунд (60000).

  • темиAllowedToBlockForConnectionMultiplier . Мультиплікатор для з’єднаньPerHost, який позначає кількість потоків, яким дозволено чекати, коли з'єднання стануть доступними, якщо пул наразі вичерпаний. Цей параметр спричинить виняток "com.mongodb.DBPortPool $ SemaphoresOut: поза семафорами отримати db-з'єднання". Він викине цей виняток, коли ця черга потоку перевищить значення threadAllowedToBlockForConnectionMultiplier. Наприклад, якщо з'єднанняPerHost дорівнює 10 і це значення становить 5 до 50 потоків, можна заблокувати до того, як буде викинуто вищезгадане виняток.

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

  • readPreference . (ОНОВЛЕНО, 2.8+) Використовується для визначення переваг читання за замовчуванням та замінює "slaveOk". Налаштуйте ReadPreference за допомогою одного із заводських методів класу. Повний опис найпоширеніших налаштувань можна знайти в кінці цієї публікації

  • ш . (ОНОВЛЕНО, 2.6+) Це значення визначає "безпеку" запису. Якщо це значення дорівнює -1, запис не повідомлятиме про помилки незалежно від помилок мережі чи бази даних. WriteConcern.NONE є відповідним заздалегідь визначеним WriteConcern для цього. Якщо w дорівнює 0, то мережеві помилки змусять записувати помилку, але помилки mongo не будуть. Зазвичай це називається "вогонь і забудь", і його слід використовувати, коли продуктивність важливіша за послідовність та довговічність. Використовуйте WriteConcern.NORMAL для цього режиму.

    Якщо ви встановите w на 1 або вище, запис вважається безпечним. Безпечне записування виконайте запис та слідкуйте за ним за допомогою запиту на сервер, щоб переконатися, що запис вдалося або отримати значення помилки, якщо воно не відбулося (іншими словами, він надсилає команду getLastError () після написання). Зауважте, що поки ця команда getLastError () не буде виконана, з'єднання зарезервоване. В результаті цього та додаткової команди пропускна здатність буде значно нижчою, ніж записує з w <= 0. При значенні aw рівно 1 MongoDB гарантує, що запис вдався (або перевірено не вдалося) на екземплярі, якому ви надіслали запис.

    У випадку наборів реплік ви можете використовувати більш високі значення для того, що скаже MongoDB для надсилання запису принаймні "w" членам набору реплік перед поверненням (або точніше, зачекайте реплікації запису на "w" членів ). Ви також можете встановити w на рядок "більшість", який вказує MongoDB виконувати запис більшості членів набору реплік (WriteConcern.MAJORITY). Типово, ви повинні встановити це значення 1, якщо вам не потрібна необроблена продуктивність (-1 або 0) або реплікація записи (> 1). Значення вище 1 мають значний вплив на пропускну здатність запису.

  • фсинк . Варіант довговічності, який змушує монго заливатися на диск після кожного запису при включенні. У мене ніколи не було проблем із довговічністю, пов'язаними з відставанням у записі, тому у нас це є помилковим (за замовчуванням) у виробництві.

  • j * (НОВЕ 2.7+) *. Булево, що після встановлення справжнього змушує MongoDB дочекатися успішного виконання журнальної групи перед поверненням. Якщо увімкнено ведення журналу, ви можете ввімкнути це для додаткової довговічності. Перегляньте сторінку http://www.mongodb.org/display/DOCS/Journaling, щоб побачити, що отримує журнал (і, отже, чому ви хочете включити цей прапор).

ReadPreference ReadPreference клас дозволяє налаштувати на те , що mongod екземпляри запитів маршрутизировать , якщо ви працюєте з наборами реплік. Доступні наступні варіанти:

  • ReadPreference.primary () : Усі зчитування переходять лише до основного елемента скидання. Використовуйте це, якщо вам потрібні всі запити для повернення послідовних (останніх написаних) даних. Це за замовчуванням.

  • ReadPreference.primaryPreferred () : Усі читання переходять до основного елемента скидання, якщо це можливо, але можуть запитувати вторинні члени, якщо основний вузол недоступний. Таким чином, якщо первинне стає недоступним, читання з часом стають послідовними, але тільки якщо первинні недоступні.

  • ReadPreference.secondary () : всі зчитування переходять до другорядних членів скидання, а основний член використовується лише для запису. Використовуйте це лише в тому випадку, якщо ви можете жити з послідовно прочитаними. Додаткові члени скидання можуть бути використані для збільшення продуктивності читання, хоча існують обмеження кількості членів (голосуючих) членів, які може мати.

  • ReadPreference.secondaryPreferred () : Усі зчитування переходять до другорядних членів скидання, якщо такі доступні. Основний член використовується виключно для запису, якщо всі вторинні члени не стануть недоступними. За винятком резервного резервного елемента для читання це те саме, що і ReadPreference.secondary ().

  • ReadPreference.nerely () : Читання переходить до найближчого члена скидання, доступного клієнту бази даних. Використовуйте лише в тому випадку, якщо в кінцевому рахунку є прийнятними послідовні показання. Найближчий член - це член з найменшою затримкою між клієнтом та різними членами скидання. Оскільки зайняті учасники з часом матимуть більш високі затримки, це також повинно автоматично врівноважувати навантаження для читання, хоча, на мій досвід, вторинні (переважні), здається, роблять це краще, якщо затримки учасників відносно послідовні.

Примітка. Усі перераховані вище мають теги з увімкненими версіями того самого методу, які замість них повертають екземпляри TaggableReadPreference. Повний опис тегів набору реплік можна знайти тут: Репліка набір тегів


6
Чи не небезпечно залишати socketTimeout та connectTimeout за замовчуванням (нескінченно)? Якщо з'єднання зависне з якоїсь причини, ваш додаток (або принаймні цей потік) назавжди застрягне. Чи не варто їх просто встановити як дуже високі (щось на зразок 30 секунд для підключення, 2 хвилини для сокета)?
Ідріс Мохтарзада

Ідріс, дуже правда. У своєму дописі я помилково припускав, що в MongoOptions були наші за замовчуванням. У нашого шару ORM Mongo є це відповідно за 15 секунд та 1 хвилину, і під час написання я припускав, що це були типові параметри. Нескінченні тайм-аути, безумовно, погана ідея. Дякую за підняті голови, я виправив це на посаді
Remon van Vliet

параметр "slaveOk" тепер застарілий, якщо ви хочете, щоб еквівалент цього був істинним, зробіть: mongoOptions.readPreference = ReadPreference.secondaryPreferred ();
Губатрон

Хороша відповідь, але ваше визначення темиAllowedToBlockForConnectionMultiplier неправильне (множник ключових слів). Згідно з документами: "множник для з’єднаньPerHost для # потоків, які можуть блокувати, якщо з'єднанняPerHost дорівнює 10, а темиAllowedToBlockForConnectionMultiplier дорівнює 5, то 50 потоків можуть блокувати більше, ніж буде викид",
Тайлер Зале

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