Как я должен настроить кластер mongodb для обработки 20K одновременного

#mongodb #cluster-computing #connection

#mongodb #кластерные вычисления #подключение

Вопрос:

Мое приложение использует MongoDB в качестве базы данных. Мы ожидаем 20K одновременных подключений к кластеру mongodb. Как мне настроить сервер, если я хочу запустить mongodb на 20 серверах и разделить кластер 20 способами?

Вот что я сделал до сих пор: на каждом из моих 20 серверов у меня есть один mongos (маршрутизатор), работающий на порту 30000, а на 3 серверах я запускаю серверы конфигурации mongo на порту 20000. Затем на каждом сервере я запускаю 3 экземпляра mongod. Один из них является основным. Другими словами, у меня есть 20 mongo, 3 mongo-config, 60 серверов mongod (20 основных и 40 реплик).

Затем в моем приложении (которое также запускается на каждом сервере и подключается к локальному хосту: 30000 mongo) я устанавливаю параметры MongoOptions таким образом, чтобы connectionsPerHost = 1000.

через 10-15 минут после запуска всех служб некоторые из них перестали работать по ssh. Эти серверы по-прежнему поддерживают пинг. Я подозреваю, что было слишком много подключений, и это привело к остановке сервера.

Мой собственный анализ выглядит следующим образом: 1K соединений на пул соединений означает, что для каждого основного сегмента будет открыто 1K * 20 (сегменты) = 20K одновременных подключений. На нескольких серверах, вероятно, будет запущено более одного основного, что удвоит или утроит количество подключений до 60K. Каким-то образом mongod не может обрабатывать столько подключений, хотя я изменил системные настройки, чтобы позволить каждому процессу открывать больше файлов.

Вот что показывает ulimit -a:

 core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64000000
max memory size (kbytes, -m) unlimited
open files (-n) 320000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
  

Кстати, я не указал —maxConns при запуске mongod / mongos, я также не менял MONGO.РАЗМЕР ПУЛА.

Побочный вопрос: если мои рассуждения верны, общее количество одновременных требований к подключению будет указано для каждого основного, что мне кажется неправильным, это почти означает, что кластер mongodb вообще не масштабируется. Кто-нибудь, скажите мне, что я ошибаюсь, пожалуйста?

Комментарии:

1. Вы ничего не говорите о том, какие операции вы будете выполнять. Является ли он тяжелым для записи, чтения, обновления, смешанным? Это имеет значение. Количество подключений в основном не имеет значения, важно то, что будут делать соединения.

2. Вам действительно нужны 20k одновременных подключений или только 20k одновременных пользователей? Есть разница. MongoDB использует поток для каждого соединения.

Ответ №1:

О вашей кластерной архитектуре :

Запуск нескольких экземпляров mongod на одном сервере обычно не является хорошей идеей, есть ли у вас какие-либо особые причины для этого? Основной сервер каждого сегмента будет оказывать сильное давление на ваш сервер, репликация также увеличивает давление ввода-вывода, поэтому их смешивание не будет действительно хорошим для производительности. IMO, вы должны иметь 6 сегментов (1 master — 2 secondaries) и предоставить каждому экземпляру свой собственный сервер. (Экземпляр Conf и arbiter не требует больших ресурсов, поэтому можно оставить их на одних и тех же серверах).

Комментарии:

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

2. @RemonvanVliet даже сами 10gen делают это 🙂

3. Я лично заметил увеличение производительности при запуске нескольких экземпляров mongod с разделением на одном поле (из-за глобальной блокировки записи, я полагаю)

4. тогда я должен попробовать еще раз

Ответ №2:

Иногда ограничения не распространяются на сам процесс. В качестве теста перейдите на один из серверов и получите pid для службы mongo, которую вы хотите проверить, выполнив

 ps axu | grep mongodb
  

а затем выполните

 cat /proc/{pid}/limit
  

Это сообщит вам, вступили ли ограничения в силу. Если ограничение не действует, вам нужно указать ограничение в файле запуска, а затем остановить — запустить службу mongo и снова протестировать.

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

Мы устанавливаем наш лимит на 20000 на сервер и делаем то же самое для всех экземпляров mongod и mongos, и это, похоже, работает.

Ответ №3:

Мы запускаем набор реплик из 4 сегментов на 4 машинах. У нас есть 2 первичных сегмента на 2 хостах, 2 реплики сегментов на 2 других блоках, арбитры и серверы конфигурации распределены).

Мы получаем сообщения:

 ./checkMongo.bash: fork: retry: Resource temporarily unavailable
./checkMongo.bash: fork: retry: Resource temporarily unavailable
./checkMongo.bash: fork: retry: Resource temporarily unavailable
Write failed: Broken pipe 
  

Проверка ulimit -a:

 core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 773713
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited   
  

Хорошо, итак, мы, возможно, достигли предела процесса из-за сообщения fork. Вот как это проверить:

 $ ps axo pid,ppid,rss,vsz,nlwp,cmd | egrep mongo
27442     1 36572   59735772 275 /path/mongod --shardsvr --replSet shard-00 --dbpath /path/rs-00-p --port 30000 --logpath /path/rs-00-p.log --fork
27534     1 4100020 59587548 295 /path/mongod --shardsvr --replSet shard-02 --dbpath /path/rs-02-p --port 30200 --logpath /path/rs-02-p.log --fork
27769     1 57948   13242560 401 /path/mongod --configsvr --dbpath /path/configServer_1 --port 35000 --logpath /path/configServer_1.log --fork
  

Итак, вы можете видеть, что mongod имеют 275, 295 и 401 подпроцессы / потоки каждый. хотя сейчас я не достигаю предела, я, вероятно, был раньше. Итак, решение: измените системный лимит для пользователя, под которым мы работаем, с 1024 на 2048 (или даже неограниченный). Вы не можете изменить с помощью

 ulimit -u unlimited
  

если вы сначала не выполните sudo или что-то в этом роде; У меня нет привилегий для этого.