Недавно мы пригласили в эфир "Цинкового прода" Алексея Лесовского из компании Data Egret. Разговор получился интересный и познавательный, поэтому предлагаю вашему вниманию расшифровку этого выпуска. Из-за внушительного объема пришлось разбить текст на части. Если лень ждать продолжения — можно просто послушать аудиоверсию здесь.

Всем привет, это сороковой выпуск подкаста "Цинковый прод", и с нами в студии постоянные ведущие Антон Околелов, Никита Васильченко и Грицак Олег.


Антон: Итак, у нас сегодня гость, Алексей Лесовский. Лёша, представься пожалуйста, кто ты, чем занимаешься и так далее.


Алексей: Всем привет, меня зовут Алексей Лесовский, как меня Антоха уже представил. Я занимаюсь администрированием Постгреса, я PostgreSQL DBA (database administrator), работаю с посгресом каждый день, 7 дней в неделю, и администрирую клиентские базы данных. У нас контора — она консалтинговая, занимается администрированием, поддержкой, сопровождением. И к нам приходят самые разные люди со своими базами данных, как правило это компании — мелкие крупные небольшие, всякие разные, — у них с базой данных есть проблемы, мы эти проблемы анализируем и как-то пытаемся их устранить. Собственно, решаем проблемы других людей, других компаний. Как-то так.


Ну а в свободное время я люблю заниматься разными делами, гулять по лесу, кататься на сноуборде, ходить в походы, пить пиво


Антон: копченое пиво пить


Никита: перед выпуском Лёха рассказывал про копченое пиво


Алексей: да, копченое пиво, есть такое, очень вкусное, рекомендую. Раухбир мерцен.


Антон: ну ладно, скажи пожалуйста, ты дба-шник, работаешь уже давно, несколько лет. Насколько это тяжело? Тебе звонят ночью и просят починить базу. Я тебе звонил в пять утра где-то год назад или полтора.


Алексей: да, было, было дело.


Антон: как ты вообще выживаешь, расскажи


Алексей: слушай, дба я работаю с 2014 года. До 2014 я работал линуксовым администратором в веб разработке. Админил много всего, у нас была kvm-виртуализация, было много линуксов, были всякие Руби-он-рейлс, nginx-ы, php, рельсы...


Олег: Докер уже был?


Алексей: докер только начинался, мы его в продакшн нигде не вводили, но уже начинались тенденции к этому.


И было много постгреса у нас в конторе. Потом я погнался за длинным рублем и решил, что можно работать на двух работах одновременно. И начал еще работать админом удаленно на московскую контору. Я две работы совмещал, там как раз базы администрировались Postgresql consulting-ом. Там был Макс Богук, Илья Космодемьянский, и я как администратор начал делать часть задач связанных с посгресом. Ну, т.е. я начал у них хлеб по-тихоньку отбирать. И вот мне в какой-то момент Макс такой говорит: слушай, а давай ты к нам пойдешь работать. Уйдешь со всех своих работ, подработок, пойдешь к нам на фултайм.


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


Антон: Ну а вообще, дба обязательно знать эти админские штуки? Это не просто там, база в вакууме, она ведь где-то крутится, надо настроить операционную систему, правильно ведь?


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


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


Олег: приходилось постгрес на Винде поддерживать?


Алексей: да, приходилось, у нас есть клиент, они с Виндоусом, мы обслуживали Питерскую контору какую-то, делали им аудит базы данных. У них база была на Винде, это было вообще страшно, мы подключались по терминальному протоколу какому-то, открывался Remote Desktop, мы запускали там какие-то штуки связанные с записью перфоманса. Короче, было тяжело, страшно, как страшный сон сейчас вспоминается. А сейчас клиенты в основном все на Линуксе сидят. Практически на винде никого нет.


Олег: а какая сейчас основная боль на Постгре, которую у всех можно заметить?


Алексей: очень много людей хотят автофейловер и мультимастер. Ну, мультимастер, понятно, штука такая, недостижимая. Но все поработали с Галерой (с Mysql), и такие говорят: почему, мы в поcгресе тоже хотим мультимастер.


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


Антон: Слушай, а можешь рассказать в двух словах рассказать, что такое патрони для простых программистов? Нас слушают в основном тимлиды и программисты


Никита: подождите, а можно я вас перебью, и попрошу еще более для непрограммистов объяснить, что такое мультимастер


Алексей: смотри, представим вот, Антоха — программист, он пишет приложения, а приложению надо хранить где-то свои данные. Он их складывает в базу, в посгрес. В какой-то момент база размещена на одном сервере, а потом сервер раз — и перестал работать. Блок питания сгорел, а приложению нужно продолжать работать с базой. И здесь возникает вариант, что нам нужно иметь какую-то копию базы и продолжать с ней работать. И либо переключиться на нее, а в идеале никакого переключения не делать, чтобы наше приложение знало про эту вторую базу и в нее продолжала писать.


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


Никита: и это непосредственно с аутофейловером, да, связано?


Алексей: да, и это связано с автофейловером, тут как бы одно вытекает из другого. Если мы не можем себе позволить мультимастер, то мы хотим какой-то прозрачный механизм, который будет переключать запасной узел в режим мастера, т.е. у нас есть приложение, оно работает, и как только у этого приложения из под ног выбили базу данных, разработчик не хочет менять конфиги этого приложения и указывать там новый адрес базы данных, перезапускать приложение, особенно если приложений много. Хочется какого-то прозрачного механизма, который где-то под капотом сработает, переключит базу, и наше приложение будет работать с тем же самым адресом и продолжать читать из этой базы. Для этого уже нужен автофейловер, который прозрачно переключает запасной узел в режим мастера, и для этого как раз используется Patroni


Антон: Patroni — это чисто переключалка или это форк постгреса, какая-то надстройка?


Алексей: это, так скажем, отдельная служба, отдельный процесс, который работает на хосте с базой данных. И он следит за состоянием постргесового кластера. Тут преследуется две цели — автофейловер и управление кластером. Но мы же получаем в этом случае распределенный кластер, у нас же неслколько узлов в кластере, мастер и несколько реплик. Соответственно нужно постоянно отслеживать состояние кластера, постоянно смотреть, жив ли мастер. Если он вдруг умер — нужно переключить на роль "мастер" другой сервер. И для этого используется, вообще есть два подхода, как поддерживать этот кластер view, представление в кластере, как он должен жить в текущий момент. Есть вариант, когда каждая из нод кластера — они проверяют друг друга. А можно хранить снаружи этот стейт, т.е. вне посгресового кластера. И вот как раз Патрони использует этот подход, он берет и хранит состояние кластера в третьей системе. Это как правило DCS какой-то (система распределенного хранения конфигурации). Это может быть etcd, consul, либо это может быть куберенетесовский etcd. Т.е. в зависимости от того, что в инфраструктуре есть. Ну и соответственно Patroni просто сохраняет стейт кластера в этой системе DCS и его обновляет.


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


Антон: А если сеть мигнула между Patroni и базой?


Алексей: Ну смотри, есть база данных, это либо какой-то сервер, либо это, допустим, в кубернетесе это может быть какой-то под. Рассмотрим простой случай, допустим, это сервер. На этом же сервер у нас запущена база, и на этом же сервере мы запускаем агента Patroni. Это легковесный процесс, они работают на одном хосте и общаются условно говоря по локалхосту. У нас может сеть мигнуть между хранилищем DCS и узлом, где работают база и Patroni.


Тут разные могут быть варианты. В зависимости от того, насколько тяжелое это сетевое моргание происходит. Бывает, что, если это был мастер, и он оказался изолированным, то остальные узлы обнаружат, что мастер пропал. Они просто выберут нового мастера, а старый мастер он увидит, что он изолирован, и Patroni перезапустит его в режиме read only. Ну, чтобы не было сплит-брейна. Плохо, если у нас приложение будет писать в два узла одновременно. Потом разработчикам придется данные разгребать, а это очень тяжелая такая работа — чтобы в консистентный вид эти данные собрать. Поэтому патрони просто перезапускает узел в read only и всё, и он работает. Как только сеть восстановится, Patroni сможет достучаться до DCS, они уже там дальше согласуют cluster view и прийдут к какому-то согласованному решению. Скорее всего этот изолированный узел, который был старым мастером, он подключится в качестве реплики к новому мастеру...


Антон. Ну ладно, а на практике как это работает? Есть ли какие-то проблемы, подводные камни. Чтобы вот Олег взял и внедрил у себя, например, Patroni, ему надо принять для этого решение.


Олег. Да, прям сразу


Алексей. Ну смотри, мы используем Patroni у клиентов начиная с прошлого года. У нас первый клиент появился по-моему в ноябре 2018-го. И мы в то время не очень хорошо представляли как с этим работать, но за год мы поработали, в принципе нас все устраивает. Мы научились его готовить. В принципе, чтоб довести его до ума, в общем-то не очень нужно много шагов, буквально два-три действия со стороны постгреса, со стороны конфигов патрони, и все это работает довольно-таки хорошо.


Штука надежная. Она во-первых простая, она написана на Питоне, она ест мало памяти и работает в принципе надежно. Единственное, что в инфраструктуре должна быть эта DCS. Но как правило это надо либо Consul либо etcd. Но у многих компаний эта штука уже используется для всяких разных service discovery, поэтому с этим проблем, как правило, нет.


А какие проблемы возникают: самая основная проблема, про которую не сразу народ вчухивает — то, что при автофейловере мы можем потерять какую-то часть данных


Олег: из-за лага репликации?


Алексей: представим себе ситуацию, когда автофейловер происходит при репликации, старый мастер ушел в оффлайн, но какую-то часть данных мы в него все равно при этом записали. Допустим был какой-то лаг репликации, происходит выбор нового мастера среди других реплик. Поднимается новый мастер и если у нас Патрони настроен таким образом, чтобы упавший узел автоматически включать в кластер, допустим, автозапуск сервисов включен, то когда старый мастер поднимется, он увидит, что он уже не мастер, он отстает, он попытается подключиться к новому мастеру и стать его репликой. И в этот момент он запускает команду pg_rewind.


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


Ну то есть в Патрони есть механизмы, которые позволяют не терять данные, но риск есть, поэтому надо аккуратно


Антон: а если синхронную репликацию включить?


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


Антон: слушай, сразу два сервера чтобы отвалились — это как предусматривать нашествие инопланетян


Алексей: и на старуху бывает проруха


Олег: ты вспомни как раз-таки звонок в пять утра Леше в последний раз, с чем оно было интересно связано, Антон, а не то, что у нас сразу две базы упали?


Антон: это был человеческий фактор. Ну да, такое бывает.


Алексей: я кстати не помню причину звонка


Антон: мы там переносили два сервера, они работали параллельно, записывали данные, не важно. А систем могла и на одном работать, но один перевезли в другой дата-центр, включили. Второй пока перевозили, и там какой-то проводок задели в момент установки, и старый тоже вырубился — что-то перепутали. В общем у нас два сервера упало, стали подниматься, а так как они были жестко настроены на запись, у них чекпоинты редкие были очень или что-то такое. Он долго запускался, мы не понимали, что происходит


Олег: сто гигов wal-логов


Антон: мы не понимали, что происходит, почему не запускается и в итоге пришлось звонить. Ну собственно там особо ничего и не сделать было...


Алексей: ну там единственное, что мы наверно подключились, посмотрели что все в порядке


Олег: подтвердили смерть пациента


Антон: по сути надо было только ждать, по большому счету.


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


Но вообще если вспоминать этот ночной звонок, нас на практике редко звонят по ночам, у нас настрена автоматика специальная — дежурные, всё как полагается, выбираются по специальному графику. Так вот, если вспоминать, то ну может раз в полгода кто-нибудь позвонит


Олег: всё с нашей компании наверно


Алексей: нет, разные


Антон: Олег, звони чаще


Олег: мы сегодня свитчовер будем делать, как раз звонить видимо буду


Алексей: у нас парни есть, у них вечернее время перекрывается, они как раз будут работать


Антон: слушай, Леха, ты говорил, что у Патрони есть какие-то аналоги. Чем они отличаются, какие бывают


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


И там автофейловера из коробки нет, repmgr изначально заточен именно на управление кластером и на ручное переключение, на свитчовер. А если хочется прямо автофейловер, то там нужно отдельный поставить демонок repmgrd, и, получается, автофейловер у нас заводится. Штука удобная, хорошая, но да — автофейловера из коробки у нас нет. Нужно отдельно его ставить. Вообще штука хорошая, удобная, в том плане, что она хорошо конфигурируется, удобно кластеры посгресовые поддерживать. Она такая гибкая, кастомизируемая. Реплики можно наливать самыми разными способами. Из бекапов, из реплик наливать других, из мастера. Короче, такая гибкая штука, потому что 10 лет. И в нее очень много фич разных натолкали, она очень хорошая.


А другой вариант — это Stolon. Он появился примерно в то же время, когда и Patroni, чуть позже. Написан он на Go.


Но у него более развесистая архитектура. Если открыть сайт проекта, там будут картинки, и сам Stolon состоит из нескольких компонентов. У него есть keeper узлы, которые работают с БД, которые поднимают Постргес. Потом есть так называемые Sentinel узлы. Они отслеживают состояние кластера, проеверют его доступность, проверяют, что ноды живы или не живы. Управляют они состоянием кластера и переконфигурируют его в случае чего.


И есть так называемые прокси-узлы, через них идет весь трафик. Приложение клиентское работает именно с проксями. И как раз-таки, если какой-то из узлов сваливается, прокси перераспределяют поток трафика на другие узлы. Т.е. это по сути балансировщики. И также, как и патрони, Stolon хранит конфиграцию в системе DCS, это может быть consul, etcd. И как-то вот он так работает на развесистой архитектуре.


Мне он нравится меньше, потому что в нем как раз-таки много компонентов, и если на bare metal это развертывать, то получается, что тебе все эти компоненты надо где-то размещать, отдельные серверочки держать. А для Кубернетеса это подходит гораздо лучше. Потому что мы можем все эти компоненты ( они легковесные довольно-таки) запустить в отдельных подах, и они будут в отдельных подах работать, и это больше подходит под архитектуру Кубера.


Но если сравнивать его с патрони, он по фичам гораздо беднее. Он не поддерживает гибкое конфигурирование узлов. Например, с помощью Патрони мы можем разную конфигурацию иметь для разных Посгресов. Допустим, мы можем иметь аналитическую реплику с одним набором настроек. И можем иметь для oltp-нагрузки отдельную реплику с другим набором настроек. А в Stolon как ты определил конфигурацию, и эта конфигурация будет для всех узлов.


И там есть некоторые настройки, штук 6 или 8, их вообще нельзя переопределить. Они зашиты в исходниках Столона, при установке они устанавливаются, и всё. Они нечастно нужны, но есть одна настройка — wal_keep_segments — она чисто дба-шная штука, очень часто бывает, что ее нужно подкрутить, поменять. И Столон не позволяет ее регулировать, меня этот момент довольно-таки сильно смущает. Плюс, у Столона ограниченный функционал по созданию новых реплик. Он новую реплику создает всегда с мастера. Т.е. нельзя новую реплику создать на основе другой реплики, чтобы не грузить мастер. Или, допустим, налить ее с бекапа. Такое не поддерживается, там создание новой реплики — это всегда нагрузка на мастер. Но это не очень удобно бывает.


Олег: кстати, работал, слышал ли что-нибудь про Citus? Если не ошибаюсь, с кластеризацией тоже связано.


Алексей: Citus — там есть два момента. Citus недавно приобрели Майкрософтовцы, они делали колоночную базу баднных CitusDB, по-моему. По сути это тот же самый посгрес, но у него есть отдельное расширение, которое добавляет колоночный формат хранения, который для аналитических ворклоадов


Антон: типа кликхауса?


Алексей: ну да, типа того, но на основе Постгреса. Со всеми его плюсами и минусами. Но они как бы в мае этого года выпустили такую штуку, называется pg autofailover. Изначально это тоже был экстеншн к посгресу, он позволял организовывать автофейловер в кластере. Потом они пошли дальше, в конце лета они его допилили, появился отдельный демон. Ну, вокруг этого экстеншена появилась дополнительная инфраструктура, И засчет этой инфраструктуры можно городить всякие автофейловеры. Но я честно скажу, я не пробовал, не смотрел. Потому что штука молодая, там наверняка еще куча багов всяких есть, а у нас уже есть хорошо работающий Патрони. Т.е. смысла на него пока обращать внимания не особо много.


Олег: про Citus. Если я правильно понял, он под капотом держит тоже несколько постгресов, и он даже может джойны по всем этим нодам прогонять. Там фишка — это большие джойны, и он там побежал...


Алексей: ну, да, да


Олег: интересно, этот инструмент и подобные инструментарии, они спокойно выкатываются на продакшен или там надо с нуля пересобирать, грубо говоря, схемы там допиливать, таблички


Алексей: я думаю, что можно просто взять его, поставить отдельно и начать его использовать. А так, чтобы поверх посгреса, я думаю, что мало вероятно. Но мы с ним "in the wild" не ставились. Погонять его в тестовой лабе в принципе можно, но в целях ознакомления.


Продолжение расшифровки выпуска будет выложено на Хабр в ближайшее время, а пока что подписывайтесь на подкаст "Цинковый прод", впереди много интересного!