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

Использование pconnect в нескольких базах данных в PHP на Apache2

Я использую предварительно подготовленный PHP (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.

Кто-нибудь знает?

Есть ли у apache2 ограничение на количество подключений, которые он может обрабатывать?

Да, он ограничен параметрами конфигурации (MaxClients, MaxServers, KeepAlive, MaxRequestsPerChild и т. Д.) И ЦП / памятью (с KeepAlive вы можете обменивать одни из них на другие).

он просто будет расти в памяти ...?

Да, чем больше подключений, тем больше потоков и памяти используется. Посмотрите, сколько памяти использует каждый поток Apache (обычно 20–30 МБ), чтобы иметь представление о максимуме, который вы можете получить с учетом доступной оперативной памяти. Если вы отключите неиспользуемые модули, вы потребляете меньше памяти на поток.

При желании, если проблема с памятью, вы можете использовать Nginx вместо Apache, поскольку nginx потребляет (небольшой) фиксированный объем памяти.

В любом случае, как правило, узким местом является не веб-сервер, а база данных и дисковый ввод-вывод, которые устраняются с помощью кэширования и оптимизации настроек / кода / схемы базы данных.

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

Прежде всего, вам действительно следует внимательно рассмотреть этот дизайн. Лучшие практики проектирования баз данных - максимально избегать разделения данных на несколько баз данных. Конечно, есть исключения (например, если вам нужно разрешить клиентам / приложениям изменять их схему), но в целом масштабируемость в направлении подключения к нескольким базам данных плохая. Кроме того, кросс-запросы к базе данных сложно писать, они дороги и плохо поддерживаются во многих (большинстве?) Систем баз данных, что вынуждает вас выполнять большую работу, которую вместо этого могла бы выполнять база данных в приложении. Ремонтопригодность - это кошмар, когда между базами данных и приложениями существует неразрывная связь.

Во-вторых, ваше объяснение немного неясно, но мне интересно, как вы используете свой бассейн? Обычно с prefork вы держите несколько серверов, чтобы уменьшить задержку. Пока сервер жив, постоянное соединение должно быть. pconnect на самом деле не пул, и не похоже на вас. Не могли бы вы привести более наглядный пример?

В-третьих, вы можете исчерпать несколько ресурсов. Дескрипторы файлов могут вызвать проблему довольно рано, и наличие большого количества соединений от каждого рабочего будет потреблять память как в Apache, так и в базе данных. Кроме того, установка соединений будет дорогостоящей, даже с пулом соединений. Если вы не можете уменьшить количество используемых баз данных, вам, скорее всего, придется съесть затраты на использование connect вместо pconnect, чтобы уменьшить количество ресурсов, потраченных впустую из-за устаревших подключений к базе данных.

Если бы кто-нибудь пришел ко мне с проектом, требующим подключения к сотням баз данных от работника Apache, я бы отправил их прямо на чертежную доску. Слишком много вещей может пойти не так, как надо, с таким дизайном. Объедините базы данных или, если это невозможно, добавьте промежуточный уровень.

edit: Хорошо, теперь все немного яснее.

Отчасти это вопрос планирования мощности, на который, как правило, невозможно дать хорошие ответы. Но, чтобы прояснить несколько моментов.

  1. Как упоминалось ранее, у вас есть много жестких ограничений, с которыми вы можете столкнуться при попытке установить соединение со многими базами данных. Файловые дескрипторы и память (особенно разделяемая память), вероятно, станут вашими ранними ограничениями.

  2. То, что вы делаете, на самом деле не является пулом соединений, поскольку постоянные соединения никогда не будут возвращены в пул. Это просто постоянные соединения, которые позволяют сэкономить на накладных расходах.

  3. Мой подход, если я действительно абсолютно должен таким образом сегментировать базы данных (что я считаю ОЧЕНЬ плохим выбором дизайна), заключался бы в выделении процессов Apache для каждой базы данных. Таким образом я уменьшаю риск накопления слишком большого количества постоянных соединений в одном процессе. Насколько мне известно, это невозможно сделать без нескольких установок Apache2 и разделения запросов на основе FQDN. Альтернативные решения, которые я бы рассмотрел, - это съесть стоимость использования подключения и использовать кеширование, чтобы попытаться минимизировать количество обращений к БД, и проверить, не могу ли я отделить веб-приложение от беспорядка базы данных.