Использование pconnect для нескольких баз данных в PHP на Apache2
Я использую PHP в preforked(MOD_PHP) на сервере apache2. Настройка на Linux Ubuntu 10.04. База данных, которую я использую, является базой данных Firebird 2.5.2. Сервер apache2 работает в веб-кластере, состоящем из 8 веб-серверов.
В какой-то момент у нас возникли серьезные проблемы с производительностью из-за значительных скачков в запросах к приложению (у нас есть часы работы). Узким местом было количество подключений к базе данных, необходимое для разрешения количества запросов, пришедших за очень короткое время. Firebird справился с этим не очень хорошо, и запросы просто вышли из строя.
Этот тип базы данных не имеет пула соединений, поэтому я использую pconnect в PHP, чтобы снять нагрузку с базы данных. Это сохраняет соединение с базой данных в процессе apache2. Это было значительное повышение производительности. Недостатком является то, что мы должны были разрешить процессу apache2 принимать много запросов, прежде чем он будет повернут, и мы продолжаем работать с большим количеством процессов apache2, даже если для него нет нагрузки. Веб-серверы работают с 70 процессами Apache каждый. Это должно держать соединения открытыми и готовыми. В основном мы пытались сделать apache2 нашим пулом соединений. Это работает. Когда пользователь запрашивает приложение, дескриптор базы данных готов, и Firebird не нужно беспокоиться о стоимости создания нового подключения к базе данных.
Теперь вот мой вопрос. Теперь нам нужно иметь много баз данных - маленьких. Но все они будут работать в кластере серверов apache2. Это означает, что во время жизни процесса apache2 очень вероятно, что он получит постоянные соединения с несколькими базами данных (возможно, 80-100).
Я обеспокоен тем, как apache2 справится с этим сценарием. Есть ли предел в apache2, сколько соединений он может обрабатывать? Будет ли он медленнее... просто будет расти в памяти и справляться со всем идеально?
На данный момент нет ничего общего с шардингом базы данных. Мы (как команда разработчиков) совсем не любили идею разделения баз данных. Но не было зеленого света для переписывания приложения и создания новой структуры базы данных, чтобы повысить производительность кода. Аппаратное обеспечение, на данный момент, является ответом. Существуют также юридические вопросы, которые вынуждают нас разделять базы данных на несколько. Но это то, что меня беспокоит, что apache2 может обработать.
Кто-нибудь знает?
2 ответа
Прежде всего, вы должны тщательно продумать этот дизайн. Передовой опыт в проектировании баз данных - избегать разделения ваших данных на несколько баз данных, насколько это возможно. Конечно, есть исключения (например, если вам нужно разрешить клиентам / приложениям изменять свою схему), но в целом масштабируемость в направлении подключения к нескольким базам данных плохая. Кроме того, перекрестные запросы к базам данных трудно писать, они дорогостоящие и плохо поддерживаются во многих (большинстве?) Системах баз данных, что вынуждает вас выполнять большую работу, которую вместо этого может выполнять база данных в приложении. Ремонтопригодность - это кошмар, когда у вас есть отношения N..N между базами данных и приложениями.
Во-вторых, ваше объяснение немного неясно, но мне интересно, как вы используете свой пул..? Обычно с помощью prefork вы держите несколько серверов, чтобы увеличить время ожидания. Пока сервер живет, должно быть постоянное соединение. pconnect на самом деле не объединяет и не звучит так, как вы. Не могли бы вы привести более четкий пример?
В-третьих, есть несколько ресурсов, из которых вы можете исчерпать. Дескрипторы файлов, скорее всего, создадут проблему довольно рано, и наличие большого количества соединений от каждого работника потребляет память как в Apache, так и в базе данных. Кроме того, установление соединений будет дорогостоящим, даже с пулом соединений. Если вы не можете уменьшить количество используемых баз данных, вам, скорее всего, придется съесть стоимость использования connect вместо pconnect, чтобы уменьшить количество ресурсов, затрачиваемых на устаревшие соединения с БД.
Если бы кто-нибудь пришел ко мне с проектом, требующим подключения к сотням баз данных от работника Apache, я отправил бы их обратно на чертежную доску. Есть слишком много вещей, которые могут и пойдут не так с таким дизайном. Объедините базы данных или, если это невозможно, поместите в промежуточный слой.
редактировать: хорошо, теперь все немного яснее.
Это частично вопрос планирования производительности, и на него, как правило, невозможно дать хорошие ответы. Но, чтобы уточнить несколько моментов.
Как упоминалось ранее, у вас есть много жестких ограничений, которые вы можете использовать при попытке установить соединение со многими базами данных. Файловые дескрипторы и память (особенно разделяемая память), вероятно, будут ранними ограничениями, которые вы достигнете.
То, что вы делаете, на самом деле не является пулом соединений, так как постоянные соединения никогда не будут возвращены в пул. Это просто постоянные связи, которые экономят ваши накладные расходы.
Мой подход, если я действительно должен ограждать базы данных таким образом (что я считаю ОЧЕНЬ плохим выбором дизайна), заключается в выделении процессов Apache для каждой базы данных. Таким образом я уменьшу риск накопления слишком большого количества постоянных соединений в одном процессе. Насколько я знаю, нет способа сделать это без нескольких установок Apache2 и разделения запросов на основе FQDN. Альтернативные решения, которые я бы рассмотрел, заключались бы в том, чтобы сократить расходы на использование соединения и использовать кэширование, чтобы попытаться минимизировать количество обращений к БД, и проверить, не могу ли я отделить веб-приложение от беспорядка базы данных.
Есть ли предел в apache2, сколько соединений он может обрабатывать?
Да, он ограничен параметрами конфигурации (MaxClients, MaxServers, KeepAlive, MaxRequestsPerChild и т. Д.) И процессором / памятью (с KeepAlive вы можете обменять некоторые из них на другие).
это просто будет расти в памяти...?
Да, чем больше соединений, тем больше потоков и больше памяти. Посмотрите, сколько памяти использует каждый поток Apache (обычно 20–30 МБ), чтобы вы могли составить представление о максимальном объеме, который вы можете получить при наличии доступной оперативной памяти. Если вы отключите неиспользуемые модули, вы будете использовать меньше памяти на поток.
При желании, если проблема с памятью, вы можете использовать Nginx вместо Apache, поскольку nginx потребляет (небольшой) фиксированный объем памяти.
В любом случае, как правило, узким местом является не веб-сервер, а база данных и дисковый ввод-вывод, которые решаются с помощью кэширования и настроек базы данных / оптимизации кода / схемы.
В конечном итоге это выглядит как вопрос планирования емкости, и, в конце концов, единственный способ точно определить, может ли ваша система обработать несколько соединений, - это попытаться воспроизвести настройку (или ее репрезентативную часть) в тестовой среде и в тестах производительности. Это.