Диагностирование основных ошибок 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 довольно медленная).
Есть несколько вещей, которые вы можете сделать, чтобы повысить эффективность использования оперативной памяти:
- Удалите ненужные индексы - они просто займут ценную оперативную память, если используются - хорошими кандидатами на удаление являются отдельные индексы, которые являются самым левым элементом составного индекса в другом месте. Это действительно будет зависеть от того, что вы используете, и от того, что здесь можно удалить, поэтому я могу дать лишь общие рекомендации.
- Отрегулируйте время ожидания чтения на томе 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, если у вас есть деньги для записи) поможет "медленной" части операций (подкачки с диска) но ничто не сравнится с преимуществами операций в памяти - они все еще на порядок быстрее, даже с улучшениями дисковой подсистемы.