Предлагам да се запознаете с разширената версия на доклада от началото на 2020 г. на Георгий Рылов "WAL-G: нови възможности и разширяване на общността"
При поддържачите на open-source възникват много проблеми с нарастващото натоварване. Как да пишем все повече изисквани функционалности, да оправяме все повече проблеми и да разглеждаме все повече pull request-ове? На примера на WAL-G (инструмент за резервни копия за PostgreSQL) ще разкажа как разрешихме тези проблеми, като стартирахме курс по Open-source разработка в университета, какво постигнахме и какво следва.

Здравейте отново! Аз съм разработчик в Яндекс от Екатеринбург. Днес ще ви разкажа за WAL-G.
В заглавието на доклада не беше посочено, че става въпрос за резервни копия. Някой не знае какво е WAL-G? Или всички знаят? Повдигнете ръка, ако не знаете. Невероятно, вие дойдохте на доклада и не знаете за какво става дума.
Нека ви разкажа какво ще се случи днес. Случи се така, че нашият екип отдавна се занимава с резервни копия. И това е още един доклад в серия, в която разказваме как съхраняваме данни безопасно, надеждно, удобно и ефективно.

В предишни серии имаше много доклади на Андрей Бородин, Владимир Лесков. Бяхме много. И всички ние разказвахме за WAL-G повече от години.
clck.ru/F8ioz —
clck.ru/Ln8Qw —
Този доклад ще се различава малко от останалите, тъй като те бяха в по-голямата си част относно техническата част, а тук ще говоря как се сблъскахме с проблеми, свързани с растежа на общността. И как измислихме малка идея, която ни помага да се справим с това.

Преди няколко години WAL-G беше доста малък проект, който получихме от Citus Data. И ние просто го поехме. И той се разработваше от един човек.
И само в WAL-G не беше налично:
- Резервно копие от реплика.
- Нямаше инкрементални резервни копия.
- Нямаше WAL-Delta резервни копия.
- И още много неща липсваха.
През тези години WAL-G значително нарасна.

И към 2020 г. всичко изброено по-горе вече беше налично. И добавено на всичкото отгоре, сега разполагаме с:
- Над 1000 звездички в GitHub.
- 150 форка.
- Около 15 отворени PR.
- И още много контрибутори.
- И постоянно отворени проблеми. И то в контекста, че ние влизаме там буквално всеки ден, правим нещо по този повод.

И стигнахме до извода, че този проект изисква повече внимание, дори когато нямаме нужда от реализация за нашия серivс Managed Databases в Яндекс.
И през есента на 2018 година ни дойде идея. Обикновено екипът има няколко начина да разработи нови функции или да поправи бъгове, когато липсват ръце. Например, може да наемете още един разработчик и да му плащате. Или можете да вземете стажант за известно време и също да му плащате заплата. Но има и доста голямо количество хора, част от които вече наистина умеят да пишат код. Просто не винаги знаете какво качество е този код.
Помислихме и решихме да опитаме да привлечем студенти. Но студентите няма да участват във всичко. Те ще извършват само определена част от работата. Например, могат да пишат тестове, да поправят бъгове, да реализират функции, които не засягат основната функционалност. Основната функционалност е създаването на резервни копия и възстановяването на резервни копия. Ако допуснем бъг при създаването на резервно копие, ще загубим данни. И никой, разбира се, не иска това. Всички искат всичко да бъде много надеждно. Затова кодът, на който ние не вярваме толкова, колкото на собствения си, определено не искаме да пускаме там. Т.е. всякакъв некритичен код – това е, което бихме искали да получим от нашите допълнителни работни ръце.
При какви условия се приема PR от студента
- Те са задължени да покриват кода си с тестове. Всичко трябва да преминава в CI.
- Също така преминаваме през 2 ревюта. Едно от Андрей Бородин и едно от мен.
- Освен това, за да проверя дали това няма да счупи нещо в нашия сервис, отделно качвам сборка с този комит. И проверяваме в end-to-end тестовете, че нищо не се разваля.
Специален курс по Open Source

Няколко думи за това, защо е необходимо и защо ми се струва готина идея.
Профитът за нас е очевиден:
- Получаваме допълнителни ръце.
- И търсим кандидати за екипа сред способни студенти, които пишат добър код.
Каква е ползата за студентите?
Тя може да не е толкова очевидна, тъй като студентите, поне, не получават пари за кода, който пишат, а само оценки в зачетната книга.
Попитах ги за това. И от техните думи:
- Опит като контрибютор в Open Source.
- Получаване на ред в CV.
- Да се проявят и да преминат интервю в Яндекс.
- Да станат участници в GSoC.
- +1 специален курс за тези, които искат да пишат код.
Няма да говоря за това как беше организиран курсът. Само ще спомена, че WAL-G беше основният проект. Освен това, в този курс включихме проекти като Odyssey, PostgreSQL и ClickHouse.
И предоставяхме задачи не само по време на курса, а също така издадохме дипломи и курсови проекти.
А каква е ползата за потребителите?
Сега да преминем към частта, която вероятно ви интересува. Каква е ползата от всичко това? Ползата е, че студентите поправиха много бъгове. И направиха заявки за функции, които ни молихте да реализираме.
И нека да разкажа за неща, които отдавна желаете и които бяха реализирани.

Поддръжка на tablespaces. Поддръжката на tablespaces в WAL-G се очакваше вероятно от момента на пускането на WAL-G, тъй като WAL-G е наследник на друг инструмент за резервно копиране WAL-E, където беше поддържано резервното копиране на бази данни с tablespaces.
Накратко, ще напомня какво е това и защо е нужно. Обикновено, всички данни на Postgres заемат една директория в файловата система, която се нарича основна. И в тази директория вече се съдържат всички файлове и поддиректории, необходими на Postgres.
Tablespaces са директории, в които се намират данни на Postgres, но те не са разположени извън основната директория. На слайда е видно, че tablespaces са извън основната директория.

Как изглежда това за самия Postgres? В основната директория има отделна поддиректория pg_tblspc. И в нея има симлинкове към директориите, в които всъщност се съхраняват данните на Postgres извън основната директория.

Когато ползвате всичко това, за вас тези команди могат да изглеждат по следния начин. Т.е. създавате таблица в указан tablespace и гледате къде точно се намира сега. Ето тези две последни реда, две последно извикани команди. И там е видно, че има някакъв път. Но всъщност – това не е истинският път. Това е път с префикс от основната директория към tablespace. И оттам е свързан със симлинк, който води към вашите реални данни.
В нашия екип това всичко не се използва, но беше използвано от много други потребители на WAL-E, които ни пишеха, че искат да преминат на WAL-G, но това им пречеше. Сега това е поддържано.

Друга функция, която нашият спецкурс ни донесе, е catchup. За catchup знаят хората, които вероятно са работили повече с Oracle, отколкото с Postgres.
Кратко за това какво е. Така може обикновено да изглежда топологията на клъстера в нашия сервис. Имаме мастер. Има реплика, която стриймва от него write-ahead лог. Репликата съобщава на мастера на кой LSN се намира в момента. И някъде паралелно с това може да се архивира журнала. Освен архивирането на журнала, се изпращат и бекъпи в облака. И се изпращат дельта-бекъпи.
Какъв може да бъде проблемът? Когато имате доста голяма база, може да се случи репликата да започне да изостава сериозно от мастера. И тя изостава толкова много, че вече никога не може да го настигне. Тази проблема обикновено трябва да се реши.
И най-простият начин е да премахнете репликата и да я налеете отново, защото тя никога няма да настигне, а с проблема трябва да се справим. Но това е доста продължително, тъй като възстановяването на цял бекъп на база от 10 TB е много- много дълго. И искаме да го направим възможно най-бързо, ако се появят такива проблеми. И именно за това е предназначен catchup.
Catchup позволява да се използват дельта-бекъпи, които се запазват в облака по този начин. Вие казвате на кой LSN е в момента изоставащата реплика и го посочвате в командата catchup, за да създадете дельта-бекъп между този LSN и LSN, на който в момента се намира вашият клъстер. И след това възстановявате този бекъп на репликата, която е изоставала.
Други бази
Още студенти донесоха много функции. Тъй като в Yandex разработваме не само Postgres, имаме и MySQL, MongoDB, Redis, ClickHouse, в определен момент ни стана необходимо да можем да правим бекъпи с точков-рековъри за MySQL и да имаме възможност да ги зареждаме в облака.
Искахме да го правим по подобен начин, по който го прави WAL-G. И решихме да експериментираме и да видим как всичко ще изглежда.
В началото, без да разделяме тази логика, написахме кода в fork. Видяхме, че имаме работна модел и това може да заработи. След това помислихме, че нашата основна общност са postgres-истите, които използват WAL-G. И затова трябваше да разделим тези части. Т.е. когато поправяме кода за Postgres, ние не ще развалим MySQL, а когато поправяме MySQL, не трябва да разваляме Postgres.

Първата идея за това как да се разделят беше да се използва същият подход, който се използва в разширенията на PostgreSQL. И всъщност, за да направите бекъп на MySQL, трябваше да инсталирате някаква динамична библиотека.
Но веднага личи асиметрията на този подход. Когато правите бекъп на Postgres, поставяте нормалната бекъп система за Postgres и всичко е наред. А за MySQL се оказва, че поставяте бекъп система за Postgres и след това инсталирате динамичната библиотека за MySQL. Звучи някак странно. И ние също така помислихме и решихме, че това не е решението, което ни трябва.
Различни пакети за Postgres, MySQL, MongoDB, Redis
Но това ни позволи, както смятаме, да достигнем до правилното решение – да изолираме различни пакети за различни бази данни. Това позволява да изолираме логиката, свързана с бекъпите на различни бази данни, които ще използват общ API, предоставен от WAL-G.

Това е частта, която написахме сами – преди да предоставим задачи на студентите. Т.е. това е точно онази част, където те можеха да направят нещо неправилно, затова решихме, че е по-добре ние да направим нещо правилно и всичко ще бъде наред.

След това предоставихме задачите. Те бяха веднага разпределени. От студентите се изискваше да поддържат три бази данни.
Това е MySQL, която бекъпваме с помощта на WAL-G по този начин вече повече от година.
И сега MongoDB наближава до продукция, там я усъвършенстват с помощта на фини настройки. По същество, ние написахме основата за всичко това. След това студентите написаха някакви работещи неща. А ние ги допълваме до състояние, което можем да приемем в продукция.
Тези задачи не изглеждаха така, че на студентите да им е нужно да напишат цели инструменти за бекъп за всяка от тези бази. Нямаше такава задача. Нашият проблем беше, че искахме възстановяване на определен момент и искахме да бекъпваме в облака. И помолихме студентите да напишат някакъв код, който да реши това. Студентите използваха вече съществуващи инструменти за бекъп, които по някакъв начин правят бекъпи, а след това вече ги свързваха с WAL-G, който прехвърляше всичко в облака. И също така добавяха възстановяване на определен момент.

Какво още донесоха студентите? Те донесоха в WAL-G поддръжка на шифроване с Libsodium.
Също така имаме полиси за съхранение на бекъпи. Сега бекъпите могат да бъдат отбелязвани като постоянни. И по някакъв начин е по-удобно за услугата ви да автоматизира процеса на тяхното съхранение.

Какви са резултатите от този експеримент?
Първоначално над 100 души се записаха на курса. В началото не споменах, че университетът в Екатеринбург е Уралският федерален университет. Там обявихме всичко. 100 души се записаха. Всъщност много по-малко започнаха да работят, около 30 души.
Още по-малко хора завършиха курса, защото трябваше да напишат тестове към вече наличния код. Също така, да поправят някаква грешка или да разработят някаква функция. И част от студентите все пак завършиха курса.
В момента студентите по този курс поправиха около 14 issues, направиха 10 функции с различен обхват. И, мисля, че това е пълноценна замяна на един-двама разработчици.
Освен всичко друго, ние издадохме дипломи и курсови работи. 12 взеха дипломи. 6 от тях вече защитиха с оценки "5". Останалите още не са защитавали, но мисля, че и при тях всичко ще бъде наред.
Планове за бъдещето
Какви са плановете ни за бъдещето?
Най-малкото, фичи-заявки, които вече чухме от потребителите и искаме да реализираме. Това е:
- Проследяване на коректността на проследяването на времевата линия в архива на бекъпите на HA клъстера. С помощта на WAL-G това може да бъде направено. И, мисля, че ще намерим студенти, които да се заемат с това.
- Вече имаме отговорен човек за преноса на бекъпи и WAL между облаците.
- Съвсем наскоро публикувахме идеята, че можем да ускорим WAL-G още повече с помощта на разархивиране на инкрементални бекъпи без презапис на страници и оптимизация на архивите, които изпращаме там.
Можете да ги споделите тук
Каква беше целта на тази презентация? Че сега, освен нас четиримата, които поддържат този проект, имаме допълнителни ръце, които са доста много. Особено, ако им пишете на лично. И ако правите бекъп на данните си и използвате WAL-G или искате да преминете на WAL-G, можем да вземем предвид вашите желания доста лесно.

Това е qr-код и линк. Можете да ги използвате, за да напишете всичките си желания. Например, ако не поправяме даден бъг. Или ако много искате някоя функция, но заради нещо тя все още не е включена в нито един бекъп, включително и в нашия. Обязательно напишете за това.

Въпроси
Здравейте! Благодаря за доклада! Въпрос относно WAL-G, но не за Postgres. WAL-G архивира MySQL и активира екстра-архивиране. Ако вземем съвременните инсталации на CentOS и направите yum install MySQL, тогава ще се инсталира MariDB. От версия 10.3 екстра-архивирането не се поддържа, поддържа се архивация на MariDB. Как стои при вас ситуацията с това?
В момента не сме опитвали да архивираме MariDB. Имахме запитвания за поддръжка на FoundationDB, но всъщност, ако има такова запитване, можем да намерим хора, които да го направят. Това не е толкова дълго и сложно, колкото ми се струва.
Добър ден! Благодаря за доклада! Въпрос относно потенциално новите функции. Готови ли сте да накарате WAL-G да работи с ленти, за да може да се правят архиви на ленти?
Предполагам, че става дума за архивирането на лентово хранилище?
Да.
Там е Андрей Боридън, който може да отговори на този въпрос по-добре от мен.
(Андрей) Да, благодаря за въпроса! Имахме запитване за прехвърляне на архив на лента от облачно хранилище. И за това прехвърляне между облаците. Защото прехвърлянето между облаците е някаква обобщена версия на прехвърляне на лента. Освен това имаме разширяема архитектура в частта на хранилищата. Между другото, много от хранилищата са написани от студенти. И ако напишете хранилище за лента, то разбира се ще бъде поддържано. Готови сме да разглеждаме pull request. Трябва да запишете файл, да прочетете файл. Ако тези неща се направят на Go, обикновено излизат около 50 реда код. И тогава в WAL-G ще бъде поддържана лента.
Благодаря за доклада! Интересен процес на разработка. Архивирането е сериозна част от функционалността, която трябва да бъде добре покрита с тестове. Когато реализирахте функционалността за нови бази, тестовете също ли бяха написани от студенти или вие самите написахте тестовете, а след това дадохте реализацията на студентите?
Тестовете също бяха написани от студенти. Но студентите пишеха повече за такива функции, като нови бази. Те писаха интеграционни тестове. И те писаха unit-тестове. Ако интеграционните минават, т.е. в момента – това е сценарият, който изпълнявате на ръка или ви го прави cron, например. Т.е. там сценарият е много ясен.
Студентите нямат много опит. Колко време отнема ревюто?
Да, на ревюто отнема доста време. Тоест, обикновено, когато дойдат няколко комитера и кажат, че съм направил това или онова, трябва да се помисли и да се отдели половин ден, за да се разбере какво точно са написали. Защото кодът трябва да се чете внимателно. Те не са преминали интервю. Ние не ги познаваме много добре, затова това отнема значително време.
Благодаря за доклада! По-рано Андрей Бородин заяви, че archive_command в WAL-G трябва да се извиква директно. Но в случая на някакъв патронен клъстер, ни е необходима допълнителна логика за определяне на възел, от който да изпращаме валовете. Как решавате този проблем при вас?
Къде точно имате проблем? Например, имате ли синхронна реплика, от която правите бекъп? Или какво?
(Андрей) Става въпрос, че действително WAL-G предполага използване без обвързване със shell-скриптове. Ако нещо липсва, нека допишем логиката, която трябва да бъде вътре в WAL-G. Що се отнася до това откъде трябва да бъде архивирането, смятаме, че архивирането трябва да бъде от текущия мастер в клъстера. Архивиране от реплика е лоша идея. Там могат да възникнат различни сценарии с проблеми. По-специално проблеми с архивирането на таймлайн и всякаква допълнителна информация. Благодаря за въпроса!
(Уточнение: От обвързването със shell-скриптове се отказахме) )
Добър вечер! Благодаря за доклада! Заинтригува ме функцията catchup, за която разказахте. Столкнали ли сте се с ситуация, в която репликата изоставаше и не можа да настигне? И в WAL-G не открих описание на тази функция в документацията.
Catchup се появи буквално в края на януари 2020 година. С документацията може би си заслужава да се поработи повече. Ние сами я пишем и не я пишем супер-отлично. И от студентите може би трябва да се изисква да я пишат.
Вече ли е в релийз?
Pull request вече е помержен, тоест, проверих го. Опитах го на тестов клъстер. Все още нямаме ситуация, при която да можем да го проверим в реална среда.
Кога можем да очакваме?
Не знам. Изчакайте месец, ще проверим.
Източник: habr.com
