PostgreSQL и современные веб-приложения

Сегодня хотел бы рассказать вам об использовании PostgreSQL в веб-приложениях, а именно, о кластерных решениях и понятиях отказоустойчивости, балансировки, репликации и масштабирования, о решениях, которые существуют в PostgreSQL для устранения данных проблем. Начну с небольшого вступления. Что такое Postgres, возможно, знают не все. Далее будет некоторый бриф, посвященный этому понятию. Потом расскажу, что собой представляет всё это.

Затем перейдём к самой интересной части: непосредственно к разговору о решениях по отказоустойчивости, балансировке, репликации и масштабированию. Будет интересно: новые решения, о которых мало кто знает.

PostgreSQL — это самая продвинутая из открытых СУБД в мире. Есть слоган, и, в принципе, с ним мало кто спорит.

Немного расскажу об основных понятиях. PostgreSQL — это надёжность и устойчивость на любых нагрузках в силу своей архитектуры. Прежде всего, это превосходная поддержка от community. Живой пример: буквально позавчера у человека, мигрировавшего с MySQL, возникла какая то проблема, он написал в рассылку и по привычке, думает долго будет, пошёл пить кофе, а по возвращении обнаруживает 15 сообщений, как решать его проблему. То есть community работает. Postgres — это кроссплатформенность, никаких проблем с операционной системой нет, можете использовать, что угодно.

PostgreSQL — это высокий уровень соответствия стандартам SQL 92, 99 и 2003 гг., один из самых высоких среди СУБД. Есть интерфейсы для любых языков: даже нет смысла все перечислять. Для людей, которым не нравится работать в консоли и с текстом, существуют административные утилиты. Можно кликать мышкой и настраивать сервер, как угодно.

Я сделал кучу малу из базвордов. Просто зачитаю. Здесь, наверное, только 10% функциональности. В PostgreSQL есть представления, sequences, наследование, joins, subselects, ссылочная целостность, rules triggers, пользовательские функции, хранимые процедуры.
Есть огромное количество языков: PL/SQL, PgSQL, Perl, PHP, Tcl, Shell, Ruby, Python, расширяемые типы данных (можете свои придумывать), горячий backup. Postgres — это ACID совместимая база, то есть настоящая база данных. Postgres поддерживает функциональные и частичные индексы, интернационализацию, Unicode. Есть отличный полнотекстовый поиск, очень быстрый и гибкий в конфигурации. Есть поддержка XML, есть SSL. Есть всё, что угодно.

Это база для «серьёзных ребят»: её используют Яндекс (с недавнего времени), Рамблер, РБК в некоторых проектах, Работа.ру, Вебальта и, например, компания Skype, которую Илья Сегалович вчера в приветственном слове так хорошо охарактеризовал. Плюс очень много других анонимных проектов. Потом в кулуарах расскажу, если кому интересно.

Теперь собственно о четырёх понятиях PostgreSQL. Отказоустойчивость включает в себя понятие failover. У нас есть некоторый сервер, который общается с приложением, и есть второй сервер, который с ним синхронизуется. Вдруг случается неприятность: в него попадает молния. Что-то должно взять и переключить нагрузку на резервный сервер, эта услуга и называется failover.

Балансировка нагрузки в Postgres. Есть некоторый сервер Load Balancer, непосредственно с которым общается приложение. Что стоит за ним, приложению не важно. А Load Balancer берёт и распределяет нагрузку на несколько других серверов.

Масштабирование. Есть набор серверов. Приложению не важно, как они устроены, главное, что их много. И подчеркиваю, пишите крупные приложения с расчётом на scale-out, то есть на горизонтальное масштабирование, когда вы покупаете много одинаковых горизонтальных ящиков. В противоположность scale-up, когда вы покупаете один большой ящик и растите его, растите и растите. Инвесторы любят scale-out. Если есть в проекте n пользователей сервиса на одном сервере, который стоит m денег, инвестору понятно, что если он хочет в k раз увеличить кол-во пользователей, то ему нужно затратить k*m денег, а не больше. Это называется scale-out.

Теперь о репликация в PostgreSQL. Вкратце расскажу о том, какие виды репликации бывают, чтобы все себе это хорошо представляли. Простейший вид репликации это Master/Slave. Master — это сервер, на который идут модифицирующие запросы. Slave — сервер, который дублирует его. Я не сказал про асинхронность: если падает сетевое соединение между серверами, то, когда оно восстанавливается, ваш Slave (сервер, который справа) берёт и спокойно догоняет Master.

Master/Slave, синхронная репликация, означает, что модификации Master’а синхронно дублируются на Slave. Чуть позже объясню, что это.

Multi-Master репликация подразумевает наличие нескольких серверов, которые одновременно принимают на себя модифицирующие запросы, insert, delete, update. Синхронная в данном случае означает, что до того момента, пока все сервера не подтвердили получение изменений, то есть не сказали accept модифицирующим изменениям, изменения не комитятся: все сервера ждут. Собственно, в этом и заключается понятие синхронности. Этим же вызван некоторый bottleneck, то есть узкое место. Это связано с тем, что все сервера ждут, пока последний из них не скажет accept, потом только наступает commit.

И последний тип репликации — это асинхронный Multi-Master. Надо сказать, что это мечта человечества. В PostgreSQL, она не реализуется в общем виде, она антипаттерн. Если у вас приложение или бизнес требуют асинхронного Multi-Master’а, вам нужно что-то делать либо с приложением, либо с бизнесом. В общем виде проблему не решить по причине конфликтов. Вы можете научить базу данных разрешать какие-то конкретные конфликты. Например, на одном Master’е пользователь обновил запись о своём адресе, а на другом запись о своём телефоне — вот такой конфликт базу данных можно научить разрешать. Но если возникает что-то сложное, то, понятно, что без ручного вмешательства проблему решить невозможно, поэтому асинхронный Multi-Master это зло.

Теперь перейдём к более интересной части, конкретно к решениям. Первое из того, что стоит упомянуть это Pgpool-II. Прошу отметить, что это совершенно новое решение. Это не Pgpool-I. Это Pgpool, написанный заново авторами первой версии. Он решил все проблемы, которые были ранее, то бишь, сняты все ограничения на работу с серверами, с количеством серверов. Из картинки должно быть понятно, что простейшее применение, это балансировка нагрузки, когда на все сервера распространяются модифицирующие изменения: insert, update, delete, а на какой-то конкретный, в рамках балансировки, уходят select’ы.

Список фич Pgpool’а из PostgreSQL короткий. Во-первых, основное его значение это менеджер соединений, connection pooling с кэшем, то есть можно кэшировать соединение. Во-вторых, очень полезная вещь Failover, я уже говорил о ней. Это обнаружение отказа и переключение нагрузки на резервный сервер: ему не страшно, если падает машина. Репликация. Из предыдущего снимка вы должны были понять, что Pgpool является синхронной мульти-мастер системой. Он ждёт, пока все сервера скажут accept, и после этого коммитится, таким образом, удостоверяясь, что изменения попали на все Master. Его можно тюнить. Bottleneck, о котором я говорил раньше, можно немножко улучшать, но при этом мы теряем надёжность.

На этом пока все, материал о взаимодействии PostgresSQL c Ruby On Rails будет выложен в ближайшее время. Следите за обновлениями.

Вход для пользователей