При выполнении медленного запроса мы сталкиваемся с полу-странным поведением в PHP-драйвере MongoDB (v1.3). Водитель, похоже, продолжает открывать соединения, когда запросы медленные, и я не совсем понимаю, почему. Может быть, у вас есть несколько предложений здесь.PHP MongoDB драйвер открывает множество соединений при медленном запросе
Вот некоторые факты: первые
- Сайт и запуск базы данных на одном сервере Ubuntu 13.04
- сервер является высоким класс 8 основных сервера 16GB RAM
- MongoDB v2.2.4
- проходит на сайте PHP 5.4
- Apache 2 как веб-сервер
- PHP Mongo driver 1.3.x (должен быть самым новым 1.3)
- Сайт использует Doctrine ODM
- Сайт имеет около 50 до 100 одновременных пользователей в любой момент
- ULIMIT открытые файлы (ULIMIT nofile) = 64000
Раз в день записи Memcache истекает и медленный запрос сделанный. Это приводит к тому, что PHP открывает до 800 соединений с MongoDB (обычно у нас есть 10 открытых подключений по журналам). Наш сайт почти полностью Memcached, поэтому наша база данных не имеет каких-либо других значительных нагрузок. В 800 открытых соединениях веб-сайт имеет 30 секунд загрузки в начале и бросает несколько типов MongoExceptions (слишком много соединений/исключений сокетов) позже.
Это уродливый запрос с группой. Чтобы быть совершенно ясным, мы понимаем, что этот запрос медленный и идиотский, и мы удаляем этот запрос сегодня. Просто непонятно, почему он закручивает весь сайт. Мы используем Учение, как уровень абстракции, но это реальный запрос в базе данных 200 000 документов (3 полей в документе: идентификатор/продукта/дата)) в соответствии с бревнами:
{"group":true,"keys":{"product":1},"initial":{"count":0},"reduce":"function (obj, prev) { prev.count++; }","options":[],"db":"Orders","collection":"History"}
После запроса его результаты записываются в Memcache в течение 24 часов. Таким образом, все новые запросы получают его от Memcache, а не от MongoDB. Но, тем не менее, он поддерживает около 800 соединений, проблема не решается сама собой, и через некоторое время веб-сайт больше не отвечает. Эти 800 соединений занимают около 10 минут.
Это похоже на типичное состояние гонки. Запрос просто не чувствует себя достаточно тяжелым, чтобы фактически вызвать состояние гонки на этом сервере с этой нагрузкой. Я имею в виду, похоже, что этого не должно быть.
Хорошо, поэтому вопросы:
- Почему PHP держать отверстие так много соединений?
- Почему MongoDB не может справиться с этим (это не должно быть ЧТОБЫ большая проблема, не так ли?)
- Любые другие предложения о том, что мы должны делать?
- Должен ли я устанавливать таймауты на соединениях и запросах, чтобы решить это, или это что-то еще?
Причина, по которой я спрашиваю об этом, потому что наш сайт растет очень быстро, и мы ожидаем, что больше трафика и нагрузки MongoDB в будущем.
Большое спасибо!