Назад | Перейти на главную страницу

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

У нас есть экземпляр mongodb, работающий на большом (7,5 ГБ) экземпляре ubuntu amazon ec2 (тот же компьютер, с которого работает наш сервер 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, а НЕ набег, как рекомендуемые.

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

Чтобы убедиться в этом, мне нужно будет лучше рассмотреть тенденцию с течением времени (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, если у вас есть деньги, которые нужно записать) помогут в «медленной» части операций (подкачка с диска), но ничто не сравнится с преимуществами операций в памяти - они все еще на порядок быстрее, даже с улучшением дисковой подсистемы.