WAL-G: новые возможности и расширение сообщества. Георгий Рылов
Предлагаю ознакомиться с расшифровкой доклада начала 2020 года Георгия Рылова «WAL-G: новые возможности и расширение сообщества»
У меинтейнеров open-source возникает множество проблем по мере их роста. Как писать все больше требуемых фич, чинить все больше issues’ов и успевать смотреть все больше pull request’ов? На примере WAL-G (backup-tool for PostgreSQL) расскажу про то, как мы решали эти проблемы, запустив курс по Open-source разработке в университете, чего мы добились и куда будем двигаться дальше.
Всем еще раз привет! Я разработчик в Яндексе из Екатеринбурга. И сегодня я расскажу про WAL-G.
В названии доклада не было сказано, что это что-то про бэкапы. Кто-нибудь не знает, что такое WAL-G? Или все знают? Поднимите руку, кто не знает. Офигеть, вы пришли на доклад и не знаете, о чем он.
Давайте я расскажу, что сегодня будет. Так получилось, что наша команда довольно давно занимается бэкапом. И это еще один доклад в серии, где мы рассказываем о том, как мы храним данные безопасно, надежно, удобно и эффективно.
В предыдущих сериях было много докладов Андрея Бородина, Владимира Лескова. Нас было много. И мы все рассказывали про WAL-G уже много лет.
clck.ru/F8ioz — https://www.highload.ru/moscow/2018/abstracts/3964
clck.ru/Ln8Qw — https://www.highload.ru/moscow/2019/abstracts/5981
Этот доклад будет немножко отличаться от остальных тем, что там было в большей степени про техническую часть, а здесь я расскажу про то, как мы столкнулись с проблемами, связанными с ростом сообщества. И как придумали небольшую идею, которая нам помогает с этим справляться.
Несколько лет назад WAL-G был довольно небольшим проектом, который нам достался от Citus Data. И мы только его взяли. И его разрабатывал один человек.
И только в WAL-G не было:
- Бэкапа с реплики.
- Не было инкрементальных бэкапов.
- Не было WAL-Delta бэкапов.
- И еще кучи всего не было.
За эти несколько лет WAL-G сильно вырос.
И к 2020-ому году все вышеперечисленное уже появилось. И к этому еще добавилось то, что у нас теперь:
- Больше 1 000 звездочек на GitHub.
- 150 форков.
- Около 15 открытых PR.
- И еще много контрибьюторов.
- И открытых issues постоянно. И это при том, что мы туда буквально каждый день заходим, что-то с этим делаем.
И мы пришли к выводу, что этот проект требует больше нашего внимания, даже тогда, когда нам самим не требуется что-то реализовать для нашего сервиса Managed Databases в Яндексе.
И где-то осенью 2018-го года нам в голову пришла идея. Обычно у команды есть несколько способов, как пилить какие-то фичи, чинить баги, если у вас не хватает рук. Например, можно нанять еще одного разработчика и платить ему деньги. Или можно взять стажера на какое-то время и тоже платить ему какую-то зарплату. Но есть еще довольно большой пласт людей, часть из которых уже реально умеет писать код. Просто вы не всегда знаете, какого качества этот код.
Мы подумали и решили попробовать привлечь студентов. Но студенты будут участвовать у нас не во всем. Они будет делать только какую-то часть работы. И будут они, например, писать тесты, чинить баги, реализовывать фичи, которые не затрагивают основную функциональность. Основная функциональность — это создание бэкапов и восстановление бэкапов. Если допустить баг в создании бэкапа, то мы получим потерю данных. И никто этого, конечно, не хочет. Все хотят, чтобы все было очень надежно. Поэтому код, которому мы доверяем меньше, чем своему собственному, мы, конечно, туда пускать не хотим. Т. е. любой некритический код — это то, что мы бы хотели получить от наших дополнительных рабочих рук.
При каких условиях принимается PR студента
- Они обязаны покрывать свой код тестами. Все должно проходить в CI.
- И также проходим 2 ревью. Одно Андрея Бородина и одно мое.
- И дополнительно, чтобы проверить, что это не сломает ничего в нашем сервисе, я отдельно заливаю сборку с этим коммитом. И мы проверяем в end-to-end тестах, что у нас ничего не валится.
Спецкурс по Open Source
Чуть-чуть про то, зачем это нужно и почему это, мне кажется, клевой идеей.
Для нас профит очевиден:
- Мы получаем дополнительные руки.
- И ищем кандидатов в команду среди толковых студентов, которые пишут толковый код.
Какой профит для студентов?
Они могут быть менее очевидные, потому что студенты, как минимум, не получают деньги за тот код, который пишут, а получают только оценки в зачетку.
Я их спросил об этом. И с их слов:
- Опыт контрибьютора в Open Source.
- Получить строчку в CV.
- Проявить себя и пройти собеседование в Яндекс.
- Стать участником GSoC.
- +1 спецкурс для тех, кто хочет писать код.
Я не буду рассказывать про то, как курс был устроен. Я только скажу, что WAL-G был основным проектом. А еще мы в этот курс включили такие проекты как Odyssey, PostgreSQL и ClickHouse.
И давали задачки не только на этом курсе, а еще выдавали дипломы и курсовые работы.
А профит для пользователей?
Теперь перейдем к части, которая интересует, скорее, вас. Какой вам от этого толк? Толк в том, что студенты починили много багов. И сделали фичи request, которые вы просили нас сделать.
И давайте я расскажу про вещи, которые вы давно хотели и которые были реализованы.
Поддержка tablespaces. Tablespaces в WAL-G ожидались, наверное, с момента релиза WAL-G, потому что WAL-G является приемником другого инструмента резервного копирования WAL-E, где были поддержаны бэкапы баз данных с tablespaces.
Вкратце напомню, что это такое и зачем это все нужно. Как правило, у вас все данные Postgres занимают одну директорию на файловой системе, которая называется базовой. И эта директория уже содержит все файлы и поддиректории, необходимые Postgres.
Tablespaces являются директориями, в которых лежат данные Postgres, но они не лежат вне базовой директории. На слайде видно, что tablespac«ы находятся вне базовой директории.
Как это выглядит для самого Postgres? В базовой директории есть отдельная поддиректория pg_tblspc. И в ней лежат симлинки на директории, в которых реально лежат данные Postgres вне базовой директории.
Когда вы всем этим пользуетесь, то для вас эти команды могут выглядеть как-то так. Т. е. вы создаете табличку в каком-то указанном tablespace и смотрите, где она у вас сейчас лежит. Вот эти две последние строчки, две последние вызванные команды. И там видно, что есть какой-то путь. Но на самом деле — это не настоящий путь. Это путь с префиксом из базовой директории к tablespace. И оттуда он сматчен симлинком, который ведет к вашим реальным данным.
У нас это все не используется в нашей команде, зато использовалось у многих других пользователей WAL-E, которые писали нам, что они хотят переехать на WAL-G, но это им мешало. Теперь это поддерживается.
Другая фича, которую нам принес наш спецкурс, это catchup. Про catchup знают люди, которые, наверное, больше работали с Oracle, чем с Postgres.
Вкратце о том, что это такое. Как-то так может обычно выглядеть топология кластера в нашем сервисе. У нас есть мастер. Есть реплика, которая стримит с него write-ahead log. И реплика говорит мастеру на каком LSN она сейчас находится. И где-то параллельно с этим может архивироваться журнал. И кроме архивации журнала еще в облако оправляются бэкапы. И отправляются дельта-бэкапы.
Какая может быть проблема? Когда у вас довольно большая база, у вас может получится так, что у вас реплика начинает сильно отставать от мастера. И она отстает так сильно, что догнать она его уже никогда не может. Эту проблему обычно нужно как-то решать.
И самый простой способ — это убрать реплику и переналить ее заново, потому что она уже никогда не догонит, а с проблемой надо разобраться. Но это довольно долго, потому что восстанавливать целый бэкап базы в 10 TB — это очень-очень долго. И нам хочется делать это все как можно быстрее, если такие проблемы возникают. И именно для этого предназначен catchup.
Catchup позволяет использовать дельта-бэкапы, которые сохраняются в облаке таким образом. Вы говорите на каком LSN находится сейчас отстающая реплика и указываете его в команде catchup для того, чтобы создать дельта-бэкап между тем LSN и LSN, на котором сейчас находится ваш кластер. И после этого восстанавливаете этот бэкап на реплику, которая отставала.
Другие базы
Еще нам студенты принесли сразу много фич. Т. к. мы в Yandex варим не только Postgres, у нас еще есть MySQL, MongoDB, Redis, ClickHouse, то в какой-то момент нам понадобилось, чтобы мы могли делать бэкапы с point-in-time recovery для MySQL, и чтобы была возможность загрузить их в облако.
И хотели мы это делать каким-то похожим образом, которым делает WAL-G. И решили поэкспериментировать и посмотреть, как это все будет выглядеть.
И вначале никак не разделяя эту логику в форке написали код. Увидели, что у нас есть какая-то рабочая модель и это может полететь. Потом подумали, что наше основное сообщество — это postgres«исты, они используют WAL-G. И поэтому нужно как-то эти части разделить. Т. е. когда правится код для Postgres мы не ломаем MySQL, когда правим MySQL, мы не ломаем Postgres.
Первой идеей о том, как это разделять, была идея использовать тот же подход, что используется в extensions PostgreSQL. И, по сути, чтобы сделать бэкап MySQL вы должны были поставить какую-то динамическую библиотеку.
Но здесь сразу видна несимметричность этого подхода. Когда вы бэкапите Postgres, то вы ставите на него нормальную бэкапелку для Postgres и все отлично. А для MySQL получается, что вы ставите бэкапелку для Postgres и еще для нее ставите динамическую библиотеку для MySQL. Звучит как-то странно. Мы тоже так подумали и решили, что это не то решение, что нам нужно.
Разные сборки для Postgres, MySQL, MongoDB, Redis
Но это позволило нам, как нам кажется, прийти к правильному решению — выделить разные сборки для разных баз. Это позволяло изолировать логику, завязанную на бэкапах различных баз данных, которые будут обращаться к общему API, которые реализует WAL-G.
Это та часть, которую мы написали сами — перед тем, как дать студентам задачки. Т. е. это как раз та часть, где они могли сделать что-нибудь не так, поэтому мы решили, что лучше мы сделаем что-нибудь так и все будет отлично.
После этого мы выдали задачки. Их сразу разобрали. От студентов требовалось поддержать три базы.
Это MySQL, которую мы бэкапим с помощью WAL-G таким способом уже больше года.
И сейчас уже MongoDB приближается к production, там его напильником допиливают. По сути, каркас для всего этого написали мы. Потом студенты написали какие-то работающие вещи. И потом мы их доводим до такого состояния, которое можем принять у себя в production.
Эти задачки не выглядели так, что студентам нужно было написать цельные backup tools для каждой из этих баз. У нас такой проблемы не стояло. Наша проблема была в том, что мы хотели point-in-time recovery и мы хотели бэкапить в облако. И попросили студентов написать какой-то код, который будет это решать. Студенты воспользовались уже существующими backup tools, которые как-то снимают бэкапы, а потом уже склеивали все это с WAL-G, что переправляло это все в облако. И также к этому добавляли point-in-time recovery.
Что еще приносили студенты? Они принесли в WAL-G поддержку шифрования Libsodium.
Также у нас появились политики хранения бэкапов. Теперь бэкапы можно помечать перманентными. И как-то более удобно для вашего сервиса автоматизировать процесс их хранения.
Что по итогам этого эксперимента получилось?
На курс изначально зарегистрировалось больше 100 человек. Я вначале не сказал, что университет в Екатеринбурге — это Уральский федеральный университет. Там мы все анонсировали. 100 человек зарегистрировалось. Реально что-то начало делать гораздо меньше, примерно 30 человек.
Закрыло курс еще меньше человек, потому что там нужно было написать тесты к тем кодам, которые уже есть. А также починить какой-то баг или сделать какую-то фичу. И часть студентов все же закрыли курс.
На текущий момент за этот курс студенты починили около 14 issues, сделали 10 фич разного размера. И, как мне кажется, это полноценная замена одного-двух разработчиков.
Кроме всего прочего мы выдавали дипломы и курсовые работы. И 12 взяли дипломы. 6 из них уже защитились на »5». У оставшихся еще защиты не было, но я думаю, что у них тоже все будет хорошо.
Планы на будущее
Какие у нас есть планы на будущее?
По крайней мере те фичи-requests, которые мы уже от пользователей слышали и хотим их сделать. Это:
- Отслеживание корректности отслеживания таймлайна в архиве бэкапов HA-кластера. С помощью WAL-G это делать можно. И, я думаю, у нас найдутся студенты, которые за это дело возьмутся.
- За перенос бэкапов и WAL«а между облаками у нас уже есть ответственный человек.
- И мы недавно публиковали идею о том, что мы можем ускорить WAL-G еще больше с помощью распаковки инкрементальных бэкапов без перезаписи страниц и оптимизации архивов, которые мы туда отправляем.
Можете поделиться ими здесь
К чему был этот доклад? К тому, что сейчас, кроме нас 4-х человек, которые поддерживают этот проект, у нас есть дополнительные руки, которых довольно много. Особенно, если им писать в личку. И если вы бэкапите свои данные и делаете это с помощью WAL-G или хотели бы на WAL-G переехать, то ваши желания мы можем довольно легко учесть.
Это qr-код и ссылка. Вы можете по ним перейти и написать все ваши хотелки. Например, мы какой-то баг не чиним. Или какую-то фичу вы очень хотите, но почему-то ее нет еще ни в одной бэкапелке, в том числе и в наше. Обязательно об этом напишите.
Вопросы
Здравствуйте! Спасибо за доклад! Вопрос про WAL-G, но не про Postgres. WAL-G бэкапит MySQL и вызывает экстра-бэкап. Если брать современные инсталляции на CentOS и если вы сделаете yum install MySQL, то установится MariDB. С версии 10.3 экстра-бэкап не поддерживается, поддерживается MariDB-бэкап. Как у вас с этим дела?
На данный момент мы не пытались бэкапить MariDB. У нас были запросы на поддержку FoundationDB, но в целом, если такой запрос есть, то мы можем найти людей, которые это сделают. Это не так долго и не так сложно, как мне кажется.
Добрый день! Спасибо за доклад! Вопрос про потенциально новые фичи. Готовы ли вы заставить работать WAL-G с лентами, чтобы можно было делать бэкап на ленты?
Бэкап на ленточном хранилище видимо имеется в виду?
Да.
Там есть Андрей Бородин, который на этот вопрос может лучше меня ответить.
(Андрей) Да, спасибо за вопрос! У нас был запрос на перенос бэкапа на ленту из облачного хранилища. И для этого пилится перенос между облаками. Потому что перенос между облаками — это некоторая обобщенная версия переноса на ленту. Кроме того, у нас расширяемая архитектура в части Storages. Кстати, многие Storoges были студентами написаны. И если вы напишете Storage для ленты, то он, конечно, будет поддержан. Мы готовы рассматривать pull request. Там надо записать файл, прочитать файл. Если эти штуки сделать на Go, то обычно получается 50 строчек кода. И тогда в WAL-G будет поддержана лента.
Спасибо за доклад! Интересный процесс разработки. Бэкап — это серьезная часть функциональности, которая должна хорошо быть покрыта тестами. Вы, когда для новых баз реализовывали функциональность, тесты писали тоже студенты или вы сами написали тесты, а потом отдали реализацию студентам?
Тесты писали тоже студенты. Но студенты писали больше для таких фич, как новые базы. Они писали интеграционные тесты. И они писали unit-тесты. Если интеграционные проходят, т. е. на данный момент — это сценарий, который вы исполняете руками или у вас это делает cron, например. Т. е. там сценарий очень даже понятный.
У студентов не очень много опыта. Много ли времени на ревью уходит?
Да, на ревью уходит довольно много времени. Т. е. обычно, когда приходят сразу несколько коммитеров и говорят, что я сделал то, я сделал се, то нужно подумать и выделить где-то полдня на то, чтобы разобраться с тем, что они там написали. Потому что код надо читать тщательно. Они же не проходили собеседование. Мы их не очень хорошо знаем, поэтому это занимает существенное время.
Спасибо за доклад! Ранее Андрей Бородин заявлял, что archive_command в WAL-G должен вызываться напрямую. Но в случае какого-нибудь патрон кластера, нам нужна дополнительная логика для определения ноды, с которой слать валы. Как вы у себя решаете эту проблему?
В чем у вас здесь возникает проблема? допустим, у вас есть синхронная реплика, с которой вы снимаете бэкап? Или что?
(Андрей) Дело в том, что действительно WAL-G предполагает использование без обвязки shell-скриптами. Если чего-то не хватает, то давайте допишем логику, которая должна быть внутри WAL-G. Касается того, откуда должна быть архивация, то мы считаем, что архивация должна быть с текущего мастера в кластере. Архивация с реплики — это плохая идея. Там возможны различные сценарии с проблемами. В частности, проблемы с архивацией таймлайнов и всякой дополнительной информации. Спасибо за вопрос!
(Уточнение: От обвязки shell-скриптами избавились в этом issue https://github.com/wal-g/wal-g/issues/549)
Добрый вечер! Спасибо за доклад! Заинтересовала фича catchup, про которую вы рассказали. Сталкивались с ситуацией отставания реплики, которая никак не могла догнать. И я в WAL-G не нашел описания в документах этой фичи.
Catchup появился буквально в 20-х числах января 2020 года. С документацией, возможно, стоит поработать получше. Мы сами ее пишем и пишем не то, чтобы супер-отлично. И от студентов, возможно, стоит начать требовать, чтобы они ее писали.
Она уже в релизе?
Pull request уже помержен, т. е. я его проверил. Я пробовал это на тестовом кластере. Пока у нас не было ситуации, когда мы могли бы проверить это на боевом примере.
Когда ожидать?
Я не знаю. Месяц подождите, точно проверим.