Как настроить Java-драйвер MongoDB MongoOptions для производственного использования?

Я искал в интернете лучшие рекомендации по настройке MongoOptions для Java-драйвера MongoDB, и я не придумал ничего, кроме API. Этот поиск начался после того, как я столкнулся с ошибкой "com.mongodb.DBPortPool$SemaphoresOut: Out of semaphores to get db connection" и, увеличив число соединений / множитель, я смог решить эту проблему. Я ищу ссылки или ваши рекомендации по настройке этих параметров для производства.

Варианты драйвера 2.4 включают в себя: http://api.mongodb.org/java/2.4/com/mongodb/MongoOptions.html

  • autoConnectRetry
  • connectionsPerHost
  • ConnectTimeout
  • maxWaitTime
  • socketTimeout
  • threadsAllowedToBlockForConnectionMultiplier

У более новых драйверов больше возможностей, и мне было бы интересно услышать о них.

1 ответ

Решение

Обновлено до 2.9:

  • autoConnectRetry просто означает, что драйвер автоматически попытается повторно подключиться к серверу (серверам) после неожиданного отключения. В производственных средах вы обычно хотите, чтобы этот параметр был установлен на true

  • connectionsPerHost - это количество физических соединений, которые один монго-экземпляр (он одноэлементный, поэтому обычно у вас есть одно на приложение) может быть установлен с процессом mongod/mongos. Во время написания java-драйвер в конечном итоге установит это количество соединений, даже если фактическая пропускная способность запроса будет низкой (в словах порядка вы увидите, что статистика "conn" в mongostat будет расти, пока она не достигнет этого числа на сервер приложений).

    В большинстве случаев нет необходимости устанавливать это значение выше 100, но этот параметр является одним из тех, которые "проверяют и видят". Обратите внимание, что вы должны убедиться, что вы установили достаточно низкое значение, чтобы общее количество подключений к вашему серверу не превышало

    db.serverStatus().connections.available

    В производстве у нас сейчас это на 40.

  • connectTimeout. Как следует из названия, количество миллисекунд будет зависать от драйвера, прежде чем попытка подключения будет прервана. Установите тайм-аут на что-то длинное (15-30 секунд), если нет реалистичного, ожидаемого шанса, что это будет мешать в противном случае успешным попыткам соединения. Обычно, если попытка подключения занимает больше пары секунд, ваша сетевая инфраструктура не способна обеспечить высокую пропускную способность.

  • maxWaitTime. Количество мс, которое поток будет ожидать, пока соединение не станет доступным в пуле соединений, и вызывает исключение, если это не произойдет во времени. Сохранить по умолчанию.

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

  • threadsAllowedToBlockForConnectionMultiplier. Множитель для connectionsPerHost, который обозначает количество потоков, которым разрешено ждать, пока соединения станут доступными, если пул в настоящее время исчерпан. Этот параметр вызывает исключение "com.mongodb.DBPortPool$SemaphoresOut: Out of semaphores to get db connection". Это исключение будет выдано, как только эта очередь потока превысит значение threadsAllowedToBlockForConnectionMultiplier. Например, если connectionPerHost равен 10, а это значение от 5 до 50, потоки могут блокироваться, прежде чем будет создано вышеупомянутое исключение.

    Если вы ожидаете большие пики пропускной способности, которые могут вызвать большие очереди, временно увеличьте это значение. У нас это в 1500 на данный момент именно по этой причине. Если загрузка вашего запроса постоянно опережает сервер, вам следует соответствующим образом улучшить ситуацию с аппаратным обеспечением и масштабированием.

  • прочитайте предпочтение. (ОБНОВЛЕНО, 2.8+) Используется для определения предпочтения чтения по умолчанию и заменяет "slaveOk". Установите ReadPreference через один из методов фабрики классов. Полное описание наиболее распространенных настроек можно найти в конце этого поста.

  • с (ОБНОВЛЕНО, 2.6+) Это значение определяет "безопасность" записи. Когда это значение равно -1, запись не будет сообщать о каких-либо ошибках независимо от ошибок сети или базы данных. WriteConcern.NONE является подходящим предопределенным WriteConcern для этого. Если w равно 0, то сетевые ошибки приведут к ошибке записи, но ошибки Монго не будут. Это обычно называется записью "запускай и забывай" и должно использоваться, когда производительность важнее, чем согласованность и долговечность. Используйте WriteConcern.NORMAL для этого режима.

    Если вы установите значение 1 или выше, запись считается безопасной. Безопасные записи выполняют запись и следуют за ней по запросу к серверу, чтобы убедиться, что запись прошла успешно, или, если это не удалось, получить значение ошибки (другими словами, после записи она отправляет команду getLastError()). Обратите внимание, что до тех пор, пока эта команда getLastError() не будет завершена, соединение резервируется. В результате этой и дополнительной команды пропускная способность будет значительно ниже, чем запись с w <= 0. При значении w равном 1, MongoDB гарантирует успешную запись (или ошибку проверки) в экземпляре, в который вы отправили запись.

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

  • fsync. Опция долговечности, которая заставляет монго записываться на диск после каждой записи при включении. У меня никогда не было проблем с долговечностью, связанных с невыполненной записью, поэтому мы имеем это в false (по умолчанию) в рабочей среде.

  • j * (NEW 2.7+) *. Логическое значение, которое при значении true заставляет MongoDB ожидать успешной фиксации группы журналирования перед возвратом. Если у вас включено ведение журнала, вы можете включить его для увеличения срока службы. Обратитесь к http://www.mongodb.org/display/DOCS/Journaling чтобы узнать, что вам дает журналирование (и, следовательно, почему вы можете захотеть включить этот флаг).

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

  • ReadPreference.primary (): все чтения идут только на основной элемент repset. Используйте это, если вам требуется, чтобы все запросы возвращали согласованные (самые последние записанные) данные. Это по умолчанию.

  • ReadPreference.primaryPreferred (): Все чтения передаются первичному члену repset, если это возможно, но могут запрашивать вторичные члены, если первичный узел недоступен. Таким образом, если первичный становится недоступным, чтения в конечном итоге становятся согласованными, но только если первичный недоступен.

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

  • ReadPreference.secondaryPreferred (): все операции чтения передаются вторичным членам набора, если они доступны. Основной член используется исключительно для записи, если все вторичные члены не становятся недоступными. Кроме возврата к основному члену для чтения, это то же самое, что ReadPreference.secondary ().

  • ReadPreference.nearest (): операции чтения переходят к ближайшему элементу repset, доступному клиенту базы данных. Используйте только в том случае, если в конечном итоге согласуются чтения Ближайший элемент - это элемент с наименьшей задержкой между клиентом и различными членами repset. Поскольку занятые участники в конечном итоге будут иметь более высокие задержки, это также должно автоматически уравновесить нагрузку чтения, хотя в моем опыте вторичные (Предпочитаемые), кажется, делают это лучше, если задержки членов относительно постоянны.

Примечание. Все вышеперечисленное имеет версии с поддержкой тегов одного и того же метода, которые вместо этого возвращают экземпляры TaggableReadPreference. Полное описание тегов набора реплик можно найти здесь: Теги набора реплик

Драйверы MongoDB предоставляют клиентам Mongo несколько вариантов обработки ошибок сетевого тайм-аута, которые могут возникнуть во время использования. Опции зависят от версии драйвера и языка. Я настоятельно рекомендую прочитать документацию класса MongoClient вашего драйвера. В производстве важно установить правильные значения для этих параметров, чтобы избежать неожиданной паузы в потоке вашего приложения. Интеллектуальное подключение к серверу базы данных может повысить производительность вашего приложения.

Вот несколько важных опций для MongoClient, которые вы хотите установить при подключении к серверу MongoDB в рабочей среде.

ServerSelctionTimeOut: Тайм- аут выбора сервера - это количество миллисекунд, в течение которых драйвер монго будет ожидать выбора сервера для операции, прежде чем отказаться и вызвать ошибку. Драйвер монго использует 30 секунд в качестве значения по умолчанию для таймаута выбора сервера. В зависимости от варианта использования мы можем увеличить или уменьшить этот порог.

Тайм-аут соединения: Тайм-аут соединения - это количество миллисекунд, в течение которых драйвер будет ожидать, прежде чем новая попытка соединения будет прервана. Значение по умолчанию для таймаута соединения зависит от версии и языка драйвера. В последних версиях драйверов Mongo для Java и Ruby по умолчанию устанавливается время ожидания 10 с, а у драйвера NodeJ нет времени ожидания. Если время ожидания слишком велико, вы рискуете остановить свое приложение. Если время ожидания слишком мало, вы можете сдаться слишком быстро. Лучше тестировать с разными значениями, чтобы найти правильное время ожидания для вашего приложения.

SocketTimeout: Тайм- аут сокета - это количество миллисекунд, которое может пройти отправка или получение в сокете до истечения времени ожидания. Для драйвера Java и Nodejs по умолчанию установлен тайм-аут сокета по умолчанию, равный 0 с, что практически не означает, что тайм-аут. В то время как Ruby предлагает время ожидания сокета 5 с. Вы не хотите устанавливать ограничение на это время ожидания, так как различные операции потребуют переменного времени.

Понимание параметров времени ожидания клиента MongoDB содержит подробное описание, позволяющее лучше понять эти параметры.

Другие вопросы по тегам