Исторически така се е случило, че IT индустрията бива разделяна на два условни лагера: тези, които са "за", и тези, които са "против". Темата на споровете може да бъде абсолютно произволна. Коя операционна система е по-добра: Windows или Linux? На смартфона Android или iOS? Да съхраняваме всичко в облака или да качваме на студени RAID хранилища и да прибираме дисковете в сейфа? Имат ли правото PHP разработчиците да се наричат програмисти? Тези спорове понякога носят изключително екзистенциален характер и нямат под себе си никаква друга база, освен спортния интерес.
Както се случи, с появата на контейнери и цялата тази любимата ни кухня с Docker и условното Kubernetes започнаха и споровете "за" и "против" използването на новите възможности в различни сфери на бекенда. (По-рано уточняваме, че макар в тази дискусия като оркестратор най-често да се посочва Kubernetes, изборът именно на този инструмент няма принципиално значение. Вместо него може да бъде поставен който и да е друг, който ви се струва най-удобен и познат.)
И, изглежда, би било просто спор между две страни на една монета. Такъв, колкото и безсмислен и безпощаден, както вечната конфронтация Windows срещу Linux, в която адекватни хора съществуват някъде по средата. Но в случая на контейнеризацията нещата не са толкова лесни. Обикновено в такива спорове няма правилна страна, но в случая "да се прилагат" или "да не се прилагат" контейнери за съхранение на бази данни всичко се обръща с краката нагоре. Защото в определен смисъл и привържениците, и противниците на подобен подход имат своите аргументи.
Светлата страна
Краткото описание на аргументацията на Светлата страна може да се изрази с една фраза: “Ало, 2019 е навън!” Звучи като популизъм, без съмнение, но ако се задълбочим в ситуацията, там действително има свои плюсове. Тях сега ще разгледаме.
Да предположим, че имате голям уеб проект. Той може да е бил изграден първоначално на базата на микросервисен подход или през определен период е стигнал до него по еволюционен път — всъщност това не е толкова важно. Разпределили сте проекта си на отделни микросервизи, настроили сте оркестрация, балансиране на натоварването и мащабиране. И сега с чиста съвест пиете мохито в хамак вместо да повдигате падналите сървъри. Но във всичките действия трябва да бъдете последователни. Много често се контейнеризира само самото приложение — кода. А какво още имаме освен кода?
Правилно, данните. Сърцето на всеки проект са неговите данни: това може да бъде както типична СУБД — MySQL, Postgre, MongoDB, така и хранилища, използвани за търсене (ElasticSearch), key-value хранилища за кеширане — например, redis и т.н. Сега няма да говорим за криви варианти на реализация на бекенда, когато БД пада заради лошо написани заявки, а вместо това ще говорим за осигуряване на отказоустойчивост на тази БД под клиентското натоварване. Нали, когато контейнеризираме приложението си и му позволяваме да се мащабира свободно за обработка на всякакво количество входящи заявки, това закономерно увеличава и натоварването на базата данни.
Всъщност, каналът за достъп до базата данни и сървърът, на който тя работи, стават игленото ухо в нашия прекрасен контейнеризиран бекенд. При това основната мотивация за контейнерната виртуализация е подвижността и пластичността на структурата, позволяваща да организираме разпределението на пиковото натоварване по цялата налична инфраструктура максимално ефективно. Тоест, ако не контейнеризираме и не разпръскваме по клъстера всички налични елементи на системата — допускаме много сериозна грешка.
Много по-логично е да кластеризираш не само самото приложение, но и услугите, отговарящи за съхранение на данни. При кластеризация и разгръщане на независими уеб сървъри, разпределящи натоварването помежду си в k8s, вече решаваме проблема със синхронизацията на данните — например коментарите към постовете, ако вземем за пример медийна платформа или блог. Във всеки случай въвеждаме вътрикластерно, макар и виртуално, представяне на БД като ExternalService. Въпросът е, че самата БД все още не е кластеризирана — разгръщащите се уеб сървъри извличат информация за промените от нашата статична работна база, която работи отделно.
Чувствате ли уловка? Използваме k8s или Swarm за разпределяне на натоварването и избягване на срив на основната система, веб-сервера, но не го правим за БД. Но ако посочи, че БД-то падне, то в цялата ни кластеризирана инфраструктура няма смисъл — каква полза имаме от празни уеб страници, които връщат грешка при достъп до базата данни?
Точно затова е необходимо да кластеризираме не само уеб сървърите, както обикновено се прави, но и инфраструктурата на базата данни. Само по този начин можем да осигурим напълно функционираща в една впряга, но независима една от друга структура. Дори и ако половината от нашия бекенд „срути“ под натоварване — останалото ще оцелее, а системата за синхронизация на БД между себе си в рамките на клъстера и възможността за безкрайно мащабиране и разгръщане на нови клъстери ще помогнат бързо да достигнем необходимите мощности — стига да имаме стойки в дата центъра.
Освен това, разпределената в клъстери модел на БД позволява да се пренесе самата БД там, където е необходима; ако говорим за глобален сервис, е доста нелогично да работи уеб клъстера някъде близо до Сан Франциско и в същото време да се пренасят пакети при достъпа до базата данни в Подмосковието и обратно.
Също така, контейнеризацията на БД позволява изграждането на всички елементи на системата на едно ниво на абстракция. Което, от своя страна, прави възможно управлението на системата директно от кода, от разработчиците, без активно привличане на администратори. Разработчиците си помислиха, че им е нужна отделна СУБД за новия подпроект — лесно! написахме yaml файл, качихме го в клъстера и готово.
И естественно, вътрешната експлоатация значително се опростява. Кажете, колко пъти сте присвивали очи в моментите, когато нов член на екипа пуска ръцете си в продуктивната база данни? Която, по същество, е единствена и в момента работи? Разбира се, всички ние сме възрастни хора тук и имаме някъде свежо копие на резервно копие, а още по-надолу — зад рафта с бабиния лук и старите ски — още едно резервно копие, възможно дори на студен хранилище, защото веднъж офисът ви вече горя. Но все пак, всяко въвеждане на нов член на екипа с достъп до продуктивната инфраструктура и, разбира се, до продуктивната база данни — това е кофа с валидол за всички около вас. Кой знае този начинаещ? Може би е лошо сръчен? Страшно е, признайте.
Контейнеризацията и всъщност разпределената физическа топология на базата данни на вашия проект помагат да избегнете подобни валидолни моменти. Не доверявате ли се на начинаещия? Окей! Нека му направим собствен клъстър за работа и да го изключим от другите кластери на базата данни — синхронизация само по ръчно натискане и синхронно завъртане на два ключа (един за ръководителя на екипа, вторият за администратора). И всички са щастливи.
Сега дойде време да преминем в противниците на кластеризацията на бази данни.
Тъмната страна
Разсъждавайки защо не трябва да контейнеризираме базата данни и да продължаваме да я въртим на един централен сървър, няма да се опускаме до риториката на ортодоксите и твърденията от типа на «дядовците въртяха бази данни на хардуер, така че и ние ще!» Вместо това да опитаме да измислим ситуация, в която контейнеризацията наистина би носила осезаеми дивиденти.
Съгласете се, проектите, на които наистина им е нужна база в контейнер, могат да се преброят на пръстите на една ръка на не най-добрия фрезист. В повечето случаи дори самото използване на k8s или Docker Swarm е излишно — доста често прибягват до тези инструменти заради общата популяреност на технологиите и инсталациите «всевишни» в лицето на генерирането да накарат всичко да бъде в облаците и контейнерите. Ами, защото сега е модерно и всички така правят.
В минимум половината от случаите използването на Kubernetes или просто Docker в проектите е излишно. Проблемът е, че не всички екипи или аутсорсинг компании, наети да обслужват инфраструктурата на клиента, осъзнават това. По-лошо — когато контейнерите се налагат, защото това струва определено количество пари на клиента.
Всъщност битува мнението, че Docker/кубик мафията просто подминава клиентите, които предават инфраструктурните си въпроси на аутсорс. И все пак, за да работите с клъстери, са нужни инженери, които разбират архитектурата на внедреното решение. Някога описахме нашия случай с изданието Republic — там обучихме екипа на клиента да работи в условията на Kubernetes, и всички останаха доволни. И това беше и доста. Често „внедрителите“ на k8s взимат инфраструктурата на клиента в заложници — сега само те разбират как всичко работи, а от страна на клиента специалисти няма.
А сега си представете, че по този начин даваме не само уеб-серверната част на аутсорс, но и обслужването на базата данни. Казахме, че базата данни е сърцето, а загубата на сърцето е фатална за всяка жива организация. Сигурно, перспективите не са най-добрите. Така че вместо хайпового Kubernetes, много проекти би трябвало просто да не пестят на нормален тариф на AWS, който да реши всички проблеми с натоварването на техния сайт/проект. Но AWS вече не е модерен, а мода е по-скъпа от парите — за съжаление, и в IT-средата също.
Окей. Възможно е, че кластеризацията на проекта наистина е необходима, но ако с бездържавните приложения всичко е ясно, как тогава да организираме достойно осигуряване на мрежовата свързаност на кластеризирана база данни?
Ако говорим за безшевно инженерно решение, което представлява преминаването на k8s, основната ни грижа е репликацията на данните в клъстеризирана база данни. Някои СУБД по принцип реагират доста лоялно на разпределението на данните между отделни свои екземпляри. Много други обаче не са толкова приветливи. И доста често основният аргумент при избора на СУБД за нашия проект е не способността да се репликира с минимални ресурси и инженерни разходи. Особено ако проектът първоначално не е планиран като микросервисен, а просто е еволюирал в тази посока.
Не мисля, че е нужно да обясняваме за скоростта на работа на мрежовите дискове — те са бавни. Т.е. реална възможност, в случай на нужда, да се презапусне екземпляр на СУБД някъде, където имаме повече, например, процесорна мощ или свободна оперативна памет, нямаме. Много бързо ще се сблъскаме с производителността на виртуализираната дискова подсистема. Съответно, СУБД трябва да бъде привързана към собствен персонален набор от машини, намиращи се в непосредствена близост. Или трябва по някакъв начин да се осигури достатъчно бърза синхронизация на данните на предвидените резерви.
Продължавайки темата за виртуални файлови системи: Docker Volumes, за съжаление, не са безпроблемни. При дългосрочно надеждно съхранение на данни, би било желателно да се избегнат максимално сложните технически схеми. Добавянето на нов слой абстракция от файловата система на контейнера към файловата система на родителския хост — самото по себе си представлява риск. Но когато добавително възникват затруднения в работата на системата за контейнеризация с транслацията на данни между тези слоеве, тогава положението става наистина тежко. Към момента повечето известни проблеми, които човечеството е срещнало, изглежда са преодолени. Но сами разбирате, колкото по-сложен е механизмът, толкова по-лесно се счупва.
В контекста на всичките тези "приключения" е много по-изгодно и просто да се държи базата данни на едно място. Дори ако се наложи контейнеризация на приложението — нека то работи само по себе си и чрез разпределителен шлюз да получава едновременно свързване с базата данни, която ще се чете и пише само веднъж и на едно място. Такъв подход намалява вероятността за грешки и разсинхронизации до минимални стойности.
Идеята е такава: контейнеризацията на базата данни е уместна там, където наистина има необходимост. Не може да накарате базата с фулл-апп да работи, сякаш имате два десетина микросервиза — това не работи. И е важно да го разберете точно.
Вместо изход
Ако очаквате ясен извод "да се виртуализира ли базата данни или не", ще се разочаровате: такъв тук няма. Защото при създаването на всяко инфраструктурно решение е нужно да се ръководите не от мода и напредък, а преди всичко от разум.
Съществуват проекти, на които принципите и инструментите, идващи с Kubernetes, пасват перфектно, и в такива проекти настъпва мир, поне в бекенд-областта. А има и проекти, на които не им е нужна контейнеризация, а нормална сървърна инфраструктура, тъй като принципно не могат да се пренастроят под микросервизна кластерна модел, иначе ще се провалят.
Източник: habr.com
