Подписка

Очереди сообщений, AMQP, RabbitMQ

Использование очередей сообщений в архитектуре распределенных систем довольно распространенная техника разделения большой системы на компоненты.

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

Их задача предоставить возможность различным подсистемам обмениваться сообщениями обеспечивая маршрутизацию, гарантированную доставку и масштабирование.

Ниже пойдет речь о самых простых очередях сообщений построенных на основе БД, стандарте AMQP и отличной системе управления очередями RabbitMQ.

Асинхронные MySQL запросы в HipHop PHP

Большим недостатком стандартной реализации MySQL клиента является отсутствие поддержки асинхронных запросов, выполняющихся в отдельном потоке не блокируя основной. Такие запросы отлично подходят для операций не нуждающихся в ответе сервера, как например обновление статистики, логирование и т.д. Особенно если операции работают с большими объемами данных и занимают много времени (например добавления строки в таблицу статистики вызывает триггер пересчета общей статистики для всех пользователей).

Для обхода этого ограничения MySQL клиента, приходиться придумывать разнообразные костыле-методы позволяющие выполнять запросы не блокируя выполнение приложения.

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

Ниже речь пойдет о похожем, но более красивом методе, использующем встроенный в HipHop сервер сообщений XBox.

Шардинг в MySQL

Шардинг - хранение разбитых по некоторому принципу данных на нескольких серверах. Например, хранение большой таблицы истории покупок в интернет магазине на 3х серверах, где выбор сервера зависит от первой цифры идентификатора пользователя.

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

Так как MySQL не поддерживает автоматического шардинга, его приходиться делать вручную. Ниже рассмотрим небольшой практический пример реализации.

Автоматизация деплоя на продакшен сервера

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

На то мы и программисты чтобы автоматизировать рутину, поэтому ниже речь пойдет о автоматизации процесса выгрузки обновлений в продакшен, при помощи подсмотренной в рубистов утилиты Capistrano.

Стратегии масштабирования MySQL

Продолжая тему распределения нагрузки, рассмотрим стратегии масштабирования базы данных, а именно партиционирование, шардинг и репликацию. Как всегда с практическими примерами - придумаем парочку проблем и попробуем их решить.

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

Горизонтальное масштабирование - балансировка нагрузки

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

Кроме увеличения мощности, горизонтальное масштабирование добавляет надежности системе - при выходе из строя одного из серверов, нагрузка будет сбалансирована между работающими и приложение будет жить.

Ниже рассмотрим одну из простых схем горизонтального маштабирования, состоящую из двух серверов приложений, одного сервера БД и балансировщика нагрузки. Такая схема оптимальна для приложений с большой нагрузкой на PHP и неинтенсивном использовании базы данных.

PCNTL - параллельные вычисления

Поддержка параллельных вычислений важная часть любого высокоуровневого языка программирования. Возможность выполнять операции в разных процессах с разделением ресурсов не только увеличивает производительность приложения, но и упрощает вертикальное маштабирование. Ниже речь пойдет об упомянутом раньше расширении PCNTL, содержащем интересный набор функций для реализации многопоточности.

Многопоточность в PHP

Иногда появляется необходимость выполнять несколько действий одновременно, например, проверять изменения в одной таблице БД и вносить модификации в другую. Причем если одна из операций (например, проверка изменений), занимает много времени, очевидно, что последовательное выполнение не обеспечит балансировки ресурсов.

Для решения такого рода задач, в программировании используется многопоточность - каждая операция помещается в отдельный поток с выделенным объемом ресурсов и работает внутри него. При таком подходе, все задачи будут выполнятся отдельно и независимо.

Хотя PHP и не поддерживает многопоточность, есть несколько методов её эмуляции, о них и пойдет речь ниже.

Прожорливые массивы

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

Компиляция PHP приложений - HipHop-php

PHP - интерпретируемый язык программирования, при каждом запросе происходит анализ и "выполнение" исходного кода. Такой подход, конечно, очень удобен на стадии разработки проекта, но вносит лишний шаг в процесс выполнения продакшен кода. Таким образом интерпретация, на первый взгляд сильная сторона PHP, стоит лишнего процесорного времени и ресурсов.

Ниже речь пойдет о компиляторах, позволяющих компилировать php код в C++, а его в исполняемый. Таким образом PHP приложения выполняются непосредсвенно процессором, минуя интерпретатор.

Проверим все ли так хорошо на практике.

Кеширование файлов в память

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

Основным требованием к системе кеширования файлов является изолированость, а также интеграция без изменения архитектуры и кода приложения, чтобы иметь возможность использовать ее в популярных CMS, таких как Wordpress, Drupal и др.

Рассмотрим метод кеширования файлов при помощи MFS и проверим есть ли прирост производительнсти на примере Drupal блога.

Шустрые фреймворки-расширения (продолжение)

В предыдущей статье, мы создали базовое приложение-блог на PhalconPHP, способное работать с базой данных и выводить записи в виде списка. Ниже закончим разработку функционала приложения и проведем испытания производительности, для проверки скорости работы блога.

Шустрые фреймворки-расширения

PHP язык расширяемый, причем расширять можно не только путем создания кастомных классов и библиотек, но и дописывая расширения (extensions) на языке C, которые подключаются непосредственно к интерпретатору. Естественно, такие расширения работают намного быстрее PHP кода, так как не нуждаются в интерпретации, а сразу выполняются.
Существует несколько фреймворков, реализованных в виде расширений, об одном из которых пойдет речь дальше.

Быстрый код

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

Жизненный цикл HTTP запроса

Для того, чтобы понять что оптимизировать, нужно для начала разобраться как работает Интернет и какие этапы проходит запрос для получения результата.

О чём планирую писать

​Мастерство написания приложений умеющих работать при больших нагрузках, наверняка можно считать апофеозом развития PHP разработчика. И несмотря на незамысловатую архитектуру, PHP дает простор для развития.

Кроме того, мне не нравится, что PHP программисты ассоциируются с "говнокодерами", из-за неудовлетворительной усредненной оценки специалистов, обусловленной низким порогом вхождения в специальность.

Поэтому в этом блоге буду писать о разработке высоконагруженных проектов на PHP и качественном коде.

Надеюсь будет полезно и мне, и читателям.

На последок: