Диагностирование основных ошибок mongodb и неустойчивого поведения

У нас есть экземпляр mongodb, работающий на большом экземпляре ubuntu amazon ec2 (7,5 ГБ) (на той же машине, на которой работает наш сервер node.js). В последнее время объем трафика увеличился, и мы начинаем видеть некоторые странности в работе mongodb. Текущее состояние:

Мы заметили несколько медленных запросов с использованием профилировщика:

query   mydb.user 1327ms Wed Aug 01 2012 14:01:39
query:{ "_id" : ObjectId("500f45486562e7053d070363") } idhack responseLength:178 client:127.0.0.1 user: 

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

mongostat говорит мне:

insert  query update delete getmore command flushes mapped  vsize    res faults locked % idx miss %     qr|qw   ar|aw  netIn netOut  conn   set repl       time
138    804      9      0      96      36       0  60.2g   121g  3.42g      2      1.8          0       0|0     1|0    93k   479k    19 fgset    M   14:15:59
94    755      4      0      71      35       0  60.2g   121g  3.41g      0      1.5          0       0|0     1|0    78k   344k    19 fgset    M   14:16:00
93     17      4      0      75      27       0  60.2g   121g  3.41g      0      1.2          0       0|0     1|0    24k    31k    19 fgset    M   14:16:01
87     86      6      0      73      33       0  60.2g   121g  3.41g      0      0.9          0       0|0     1|0    31k   260k    19 fgset    M   14:16:02
101    531      3      0      62      19       0  60.2g   121g  3.41g      0        1          0       0|0     1|0    60k     1m    19 fgset    M   14:16:03
92    713      2      0      66      24       0  60.2g   121g  3.41g      1      0.9          0       0|0     0|0    72k     1m    17 fgset    M   14:16:04
163     91      6      0      93      46       0  60.2g   121g  3.41g      2      9.5          0       0|0     1|0    44k   256k    17 fgset    M   14:16:05
108     62      6      0      79      38       0  60.2g   121g  3.41g      4      1.2          0       0|0     1|0    32k   122k    17 fgset    M   14:16:06
137     23      6      0      81      32       0  60.2g   121g  3.41g      0      2.3          0       0|0     0|0    32k    67k    17 fgset    M   14:16:07

pidstat -r -p <pid> 5 говорит мне:

02:18:01 PM      1700    647.00      0.80 126778144 3578036  46.80  mongod
02:18:06 PM      1700   1092.00      1.20 126778144 3586364  46.91  mongod
02:18:11 PM      1700    689.60      0.20 126778144 3578912  46.81  mongod
02:18:16 PM      1700    740.80      1.20 126778144 3577652  46.79  mongod
02:18:21 PM      1700    618.60      0.20 126778144 3578100  46.80  mongod
02:18:26 PM      1700    246.00      1.00 126778144 3577392  46.79  mongod

Обратите внимание, что наш том базы данных - это отдельный том ext4, а НЕ рейдовый набор, как рекомендуется.

Я не уверен, что следующий шаг должен понять проблему достаточно, чтобы осуществить исправление. Любой вклад приветствуется.

1 ответ

Решение

Мне нужно было бы лучше взглянуть на тенденцию с течением времени, чтобы быть уверенным ( MMS поможет), но вы можете столкнуться с проблемой, когда вы достигли максимальной резидентной памяти для MongoDB в этом случае - ошибки страницы не отображаются. не так высоко, но я вижу небольшое падение резидентской памяти. Если в другом месте существует нехватка памяти (из другого процесса), возможно, вы выгружаете страницы из MongoDB и / или вынуждены перелистывать страницы на диск чаще, чем должны (страница на диске в EBS довольно медленная).

Есть несколько вещей, которые вы можете сделать, чтобы повысить эффективность использования оперативной памяти:

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

Чтобы посмотреть настройки чтения для тома, вы запускаете эту команду (требуются права root/sudo):

sudo blockdev --report

Вывод выдаст что-то вроде этого:

RO    RA   SSZ   BSZ   StartSec            Size   Device
rw   256   512  4096          0     10737418240   /dev/xvda1

Столбец RA (256, который, по моему мнению, является стандартным для Amazon) - это то, что мы хотим настроить здесь. Вы делаете это, запустив что-то вроде этого:

blockdev --setra <value> <device name>

Для приведенного выше примера я бы начал с того, что наполовину уменьшил значение:

blockdev --setra 128 /dev/xvda1

Я подробно расскажу о том, как низко вы должны установить это значение, и о причинах этого ответа, если вы хотите узнать больше. Обратите внимание, что изменения вступили в силу после перезапуска процесса Mongod.

После того, как вы выполнили обе эти вещи, вы сможете выжать больше производительности из ОЗУ на этом экземпляре xlarge. Если нет, или если давление памяти исходит из других источников и недостаточно эффективно, то пришло время получить больше оперативной памяти.

Обновление хранилища EBS до тома RAID, как вы упомянули, или использование новых подготовленных экземпляров IOPS и EBS (или узлов SSD Cluster Compute, если у вас есть деньги для записи) поможет "медленной" части операций (подкачки с диска) но ничто не сравнится с преимуществами операций в памяти - они все еще на порядок быстрее, даже с улучшениями дисковой подсистемы.

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