Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

въведение

Преди известно време ми беше дадена задача да разработя failover cluster за PostgreSQL, работещи в няколко центъра за данни, свързани с оптични влакна в рамките на един и същ град, и способни да издържат на повреда (например спиране на тока) на един център за данни. Като софтуер, който отговаря за устойчивостта на грешки, избрах пейсмейкър, тъй като това е официалното решение от RedHat за създаване на отказоустойчиви клъстери. Добре е, защото RedHat осигурява поддръжка за него и защото това решение е универсално (модулно). С негова помощ ще бъде възможно да се осигури устойчивост на грешки не само за PostgreSQL, но и за други услуги, като се използват стандартни модули или се създават за специфични нужди.

При това решение възникна разумен въпрос: колко устойчив на грешки ще бъде отказоустойчивият клъстер? За да проуча това, разработих тестов стенд, който симулира различни повреди на възлите на клъстера, изчаква възстановяване, възстановява неуспешния възел и продължава тестването в цикъл. Първоначално този проект се казваше hapgsql, но с времето ми омръзна името, което има само една гласна. Затова започнах да наименувам устойчиви на грешки бази данни (и плаващи IP адреси, сочещи към тях) кроган (персонаж от компютърна игра, в която се дублират всички важни органи), а възлите, клъстерите и самия проект са тучанка (планетата, където живеят кроганите).

Ръководството вече е одобрено отворете проект за общността с отворен код под лиценза на MIT. README скоро ще бъде преведен на английски (защото се очаква разработчиците на Pacemaker и PostgreSQL да бъдат основните потребители) и реших да издам старата руска версия на README (частично) под формата на тази статия.

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Клъстерите се разполагат на виртуални машини VirtualBox. Общо ще бъдат разположени 12 виртуални машини (общо 36GiB), които образуват 4 отказоустойчиви клъстера (различни опции). Първите два клъстера се състоят от два PostgreSQL сървъра, разположени в различни центрове за данни и общ сървър Свидетел c устройство за кворум (хостван на евтина виртуална машина в трети център за данни), който разрешава несигурността 50% / 50%като даде своя глас. Третият клъстер в три центъра за данни: един главен, два подчинени, не устройство за кворум. Четвъртият клъстер се състои от четири PostgreSQL сървъра, по два на център за данни: един главен, останалите са реплики и също използва Свидетел c устройство за кворум. Четвъртият оцелява при отказ на два сървъра или един център за данни. Това решение може да бъде увеличено до повече реплики, ако е необходимо.

Времево обслужване ntpd също е преконфигуриран за толерантност към грешки, но използва метода на ntpd (режим на сирак). Споделен сървър Свидетел действа като централен NTP сървър, разпределяйки времето си към всички клъстери, като по този начин синхронизира всички сървъри един с друг. Ако Свидетел не успее или се окаже изолиран, тогава един от сървърите на клъстера (в рамките на клъстера) ще започне да разпределя времето си. Спомагателно кеширане HTTP прокси също повдигнат до Свидетел, с негова помощ други виртуални машини имат достъп до Yum хранилища. В действителност услуги като точно време и прокси най-вероятно ще бъдат хоствани на специални сървъри, а в кабината, на която се хостват Свидетел само за да спестите броя на виртуалните машини и пространството.

версии

v0. Работи с CentOS 7 и PostgreSQL 11 на VirtualBox 6.1.

Клъстерна структура

Всички клъстери са проектирани да бъдат разположени в няколко центъра за данни, обединени в една плоска мрежа и трябва да издържат на отказ или мрежова изолация на един център за данни. Ето защо е невъзможно използвайте за защита срещу раздвоен мозък стандартна технология за пейсмейкър, наречена STONITH (Застреляй другия възел в главата) или фехтовка. Неговата същност: ако възлите в клъстера започнат да подозират, че нещо не е наред с даден възел, той не реагира или се държи неправилно, тогава те принудително го изключват чрез „външни“ устройства, например контролна карта IPMI или UPS. Но това ще работи само в случаите, когато при единична повреда на IPMI сървъра или UPS те продължават да работят. Той също така планира да защити срещу много по-катастрофална повреда, когато целият център за данни се повреди (например, е без ток). И с такъв отказ всичко камък-устройства (IPMI, UPS и др.) също няма да работят.

Вместо това системата се основава на идеята за кворум. Всички възли имат глас и само тези, които виждат повече от половината от всички възли, могат да работят. Това число "половина + 1" се нарича кворум. Ако кворумът не е достигнат, тогава възелът решава, че е в мрежова изолация и трябва да изключи ресурсите си, т.е. това е така защита от раздвоен мозък. Ако софтуерът, който е отговорен за това поведение, не работи, тогава куче-пазач, например, базирано на IPMI, трябва да работи.

Ако броят на възлите е четен (клъстер в два центъра за данни), тогава може да възникне така наречената несигурност 50% / 50% (петдесет на петдесет), когато изолацията на мрежата разделя клъстера точно наполовина. Следователно, за четен брой възли, той се добавя устройство за кворум - неизискващ демон, който може да се стартира на най-евтината виртуална машина в третия център за данни. Той дава гласа си на един от сегментите (който вижда) и по този начин разрешава несигурността от 50%/50%. Обадих се на сървъра, на който ще работи кворумното устройство Свидетел (терминология от repmgr, хареса ми).

Ресурсите могат да се преместват от място на място, например от дефектни сървъри към работещи, или по команда на системните администратори. За да могат клиентите да знаят къде се намират необходимите им ресурси (къде да се свържат?), плаващ IP (плаващ IP). Това са IP адресите, които Pacemaker може да мести около възлите (всичко е в плоска мрежа). Всеки от тях символизира ресурс (услуга) и ще бъде разположен там, където трябва да се свържете, за да получите достъп до тази услуга (в нашия случай базата данни).

Tuchanka1 (компресирана схема)

Структура

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Идеята беше, че имаме много малки бази данни с ниско натоварване, за които е нерентабилно да поддържаме специален подчинен сървър в горещ режим на готовност за транзакции само за четене (няма нужда от такава загуба на ресурси).

Всеки център за данни има един сървър. Всеки сървър има две инстанции на PostgreSQL (в терминологията на PostgreSQL те се наричат ​​клъстери, но за да избегна объркване, ще ги наричам инстанции (по аналогия с други бази данни), а клъстерите на Pacemaker ще наричам само клъстери). Един екземпляр работи в главен режим и само той предоставя услуги (до него води само float IP). Вторият екземпляр работи като подчинен за втория център за данни и ще предоставя услуги само ако неговият главен се повреди. Тъй като през повечето време само един от двата екземпляра (главният) ще предоставя услуги (изпълнява заявки), всички сървърни ресурси са оптимизирани за главния (паметта е разпределена за кеша shared_buffers и т.н.), но така че вторият екземпляр също има достатъчно ресурси (макар и за неоптимална работа през кеша на файловата система) в случай, че някой от центровете за данни откаже. Подчиненото устройство не предоставя услуги (не изпълнява заявки само за четене) по време на нормална работа на клъстера, така че да няма война за ресурси с главния на същата машина.

В случай на два възела толерантността към грешки е възможна само при асинхронна репликация, тъй като при синхронна репликация повредата на подчинения ще доведе до спиране на главния.

липса на свидетелство

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

липса на свидетелство (устройство за кворум) Ще разгледам само за клъстера Tuchanka1, същата история ще бъде и с всички останали. Ако свидетелят се провали, нищо няма да се промени в структурата на клъстера, всичко ще продължи да работи по същия начин, както е работило. Но кворумът ще стане 2 от 3 и следователно всеки следващ провал ще бъде фатален за клъстера. Все още трябва да се направи спешно.

Отказ Тучанка1

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Повреда на един от центровете за данни за Tuchanka1. В такъв случай Свидетел гласува на втория възел във втория център за данни. Там бившият роб се превръща в главен, в резултат на което и двата главни работят на един и същи сървър и двата им плаващи IP-та сочат към тях.

Тучанка2 (класическа)

Структура

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Класическата схема на два възела. Господарят работи върху едното, робът работи върху второто. И двата могат да изпълняват заявки (подчиненият е само за четене), така че и двата се сочат от float IP: krogan2 е главният, krogan2s1 е подчиненият. И главният, и подчиненият ще имат толерантност към грешки.

В случай на два възела толерантността към грешки е възможна само при асинхронна репликация, тъй като при синхронна репликация повредата на подчинения ще доведе до спиране на главния.

Отказ Тучанка2

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Ако един от центровете за данни се повреди Свидетел гласувайте за второто. В единствения работещ център за данни главният ще бъде повдигнат и двата плаващи IP адреса ще сочат към него: главен и подчинен. Разбира се, екземплярът трябва да бъде конфигуриран по такъв начин, че да има достатъчно ресурси (ограничения на връзката и т.н.), за да приеме едновременно всички връзки и заявки от главния и подчинения плаващ IP. Тоест, по време на нормална работа, той трябва да има достатъчен резерв за ограничения.

Tuchanka4 (много роби)

Структура

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Вече друга крайност. Има бази данни, които имат много заявки само за четене (типичен случай на силно натоварен сайт). Tuchanka4 е ситуация, в която може да има три или повече роби, които да обработват такива заявки, но все пак не са твърде много. При много голям брой роби ще е необходимо да се изобрети йерархична система за репликация. В минималния случай (на снимката), всеки от двата центъра за данни има два сървъра, всеки от които има PostgreSQL инстанция.

Друга особеност на тази схема е, че тук вече е възможно да се организира една синхронна репликация. Той е конфигуриран да репликира, ако е възможно, към друг център за данни, а не към реплика в същия център за данни като главния. Главният и всеки подчинен се обозначават с плаващ IP. За добро между робите ще е необходимо да се направи някакъв вид балансиране на заявките sql прокси, например от страна на клиента. Различните типове клиенти може да изискват различни видове sql прокси, и само клиентските разработчици знаят кой от коя се нуждае. Тази функционалност може да бъде реализирана или от външен демон, или от клиентска библиотека (пул за свързване) и т.н. Всичко това е извън обхвата на фаилоувър клъстера на базата данни (failover SQL прокси може да се внедри независимо, заедно с клиентски отказ).

Отказ Тучанка4

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Ако един център за данни (т.е. два сървъра) се повреди, свидетелят гласува за втория. В резултат на това във втория център за данни работят два сървъра: главният работи на един, а главният плаващ IP сочи към него (за получаване на заявки за четене и запис); и подчинен сървър със синхронна репликация работи на втория сървър и един от подчинените плаващи IP адреси сочи към него (за заявки само за четене).

Първото нещо, което трябва да отбележите: не всички подчинени плаващи IP адреси ще работят, а само един. И за да работим правилно с него, ще е необходимо това sql прокси пренасочи всички заявки към единствения оставащ плаващ IP; и ако sql прокси не, можете да изброите всички плаващи IP подчинени устройства, разделени със запетаи в URL адреса на връзката. В такъв случай с libpq връзката ще бъде към първия работещ IP, както се прави в системата за автоматично тестване. Може би в други библиотеки, например JDBC, това няма да работи и е необходимо sql прокси. Това се прави, защото плаващият IP адрес за подчинени е забранено да се издига едновременно на един сървър, така че те да бъдат равномерно разпределени между подчинени сървъри, ако има няколко от тях.

Второ: дори в случай на повреда в центъра за данни, синхронната репликация ще се поддържа. И дори ако възникне вторична повреда, т.е. един от двата сървъра се повреди в оставащия център за данни, клъстерът, въпреки че спира да предоставя услуги, все пак ще запази информация за всички извършени транзакции, за които е потвърдил поемането (ще да няма загуба на информация при вторична повреда).

Tuchanka3 (3 центъра за данни)

Структура

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Това е клъстер за ситуация, при която има три напълно функциониращи центъра за данни, всеки от които има напълно функциониращ сървър на база данни. В такъв случай устройство за кворум не е необходимо. Главен работи в един център за данни, а подчинени работят в другите два. Репликацията е синхронна, тип ANY (slave1, slave2), тоест клиентът ще получи потвърждение за ангажиране, когато някой от подчинените е първият, който отговори, че е приел ангажимента. Ресурсите се посочват от един плаващ IP за главен и два за подчинени. За разлика от Tuchanka4, и трите плаващи IP са устойчиви на грешки. За да балансирате SQL заявките само за четене, можете да използвате sql прокси (с отделна толерантност към грешки) или задайте един подчинен IP float на половината от клиентите, а вторият на другата половина.

Отказ Тучанка3

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Ако един от центровете за данни се повреди, остават два. В единия главният и плаващият IP от главния се повдигат, във втория, подчинените и двата подчинени плаващи IP адреси (екземплярът трябва да има двоен запас от ресурси, за да приеме всички връзки от двата подчинени плаващи IP адреси). Синхронна репликация между главни и подчинени. Също така клъстерът ще запазва информация за извършени и потвърдени транзакции (няма да има загуба на информация) в случай на унищожаване на два центъра за данни (ако не бъдат унищожени едновременно).

Реших да не включвам подробно описание на файловата структура и внедряването. Ако искате да си поиграете, можете да прочетете всичко това в README. Давам само описание на автоматичното тестване.

Автоматична система за тестване

За да се провери устойчивостта на грешки на клъстери с имитация на различни грешки, беше създадена система за автоматично тестване. Стартира се от скрипт test/failure. Скриптът може да приеме като параметри броя на клъстерите, които искате да тествате. Например тази команда:

test/failure 2 3

ще тества само втория и третия клъстер. Ако параметрите не са посочени, всички клъстери ще бъдат тествани. Всички клъстери се тестват паралелно и резултатът се показва в панела tmux. Tmux използва специален tmux сървър, така че скриптът може да се изпълнява от подразбиращия се tmux, което води до вложен tmux. Препоръчвам да използвате терминала в голям прозорец и с малък шрифт. Преди да започне тестването, всички виртуални машини се връщат към моментна снимка в момента, в който скриптът приключи setup.

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Терминалът е разделен на колони според броя на тестваните клъстери, като по подразбиране (на екранната снимка) има четири от тях. Ще опиша съдържанието на колоните като използвам Tuchanka2 като пример. Панелите в екранната снимка са номерирани:

  1. Това е мястото, където се показват статистическите данни за теста. Говорители:
    • провал — името на теста (функция в скрипта), който емулира грешката.
    • реакция — средноаритметичното време в секунди, за което клъстерът е възстановил работата си. Измерва се от началото на скрипта, който емулира грешката, и до момента, в който клъстерът възстанови здравето си и е в състояние да продължи да предоставя услуги. Ако времето е много кратко, например шест секунди (това се случва в клъстери с няколко подчинени устройства (Tuchanka3 и Tuchanka4)), това означава, че неизправността е стигнала до асинхронно подчинено устройство и не е повлияла на производителността по никакъв начин, не е имало превключватели на състоянието на клъстера.
    • отклонение - показва разпространението (точността) на стойността реакция по метода на стандартното отклонение.
    • броя Колко пъти е проведен този тест.
  2. Кратък дневник ви позволява да оцените какво прави клъстерът в момента. Показват се номерът на итерацията (теста), клеймото за време и името на операцията. Твърде дългото изпълнение (> 5 минути) показва някакъв проблем.
  3. сърце (сърце) е текущото време. За визуална оценка на ефективността майстори текущото време се записва постоянно в неговата таблица, като се използва float IP на главния. При успех резултатът се показва в този панел.
  4. бия (пулс) - "текущо време", което е било предварително записано от скрипта сърце за овладяване, сега прочетете от роб чрез неговото плаващо IP. Позволява ви визуално да оцените производителността на роб и репликация. Няма подчинени устройства с плаващ IP в Tuchanka1 (няма подчинени устройства, предоставящи услуги), но има два екземпляра (DB), така че няма да се показва тук бияИ сърце втора инстанция.
  5. Мониторинг на състоянието на клъстера с помощта на помощната програма pcs mon. Показва структурата, разпределението на ресурсите по възли и друга полезна информация.
  6. Той показва мониторинг на системата от всяка клъстерна виртуална машина. Може да има повече такива панели - колко виртуални машини има клъстерът. Две графики Натоварване на процесора (два процесора във виртуални машини), име на виртуална машина, Зареждане на системата (наречен Средно зареждане, защото е средно за 5, 10 и 15 минути), данни за процеса и разпределение на паметта.
  7. Проследяване на скрипта, който изпълнява тестовете. В случай на неизправност - внезапно прекъсване на работата или безкраен цикъл на изчакване - тук можете да видите причината за това поведение.

Тестването се извършва на два етапа. Първо, скриптът преминава през всички видове тестове, като произволно избира виртуална машина, към която се прилага този тест. След това се извършва безкраен цикъл на тестване, виртуални машини и неизправност се избират на случаен принцип всеки път. Внезапно прекратяване на тестовия скрипт (долния панел) или безкраен цикъл на изчакване за нещо (> 5 минути време за завършване на една операция, това може да се види в трасирането) показва, че някои от тестовете на този клъстер са се провалили.

Всеки тест се състои от следните операции:

  1. Стартиране на функция, която емулира грешка.
  2. Готов? - изчакване за възстановяване на здравето на клъстера (когато всички услуги са предоставени).
  3. Показано е времето за изчакване за възстановяване на клъстера (реакция).
  4. Фиксирайте - клъстерът е "ремонтиран". След което трябва да се върне в напълно работоспособно състояние и да е готов за следващата неизправност.

Ето списък с тестове с описание на това, което правят:

  • Forkbomb: Създава "Out of memory" с бомба с вилица.
  • OutOfSpace: твърдият диск е пълен. Но тестът е по-скоро символичен, с незначителното натоварване, което се създава по време на тестването, когато твърдият диск препълни, PostgreSQL обикновено не се проваля.
  • Postgres-УБИЙ: убива PostgreSQL с командата killall -KILL postgres.
  • postgres-STOP: окачва PostgreSQL с командата killall -STOP postgres.
  • Изключване: "деактивира" виртуалната машина с командата VBoxManage controlvm "виртуалка" poweroff.
  • Нулиране: презарежда виртуалната машина с командата VBoxManage controlvm "виртуалка" reset.
  • SBD СТОП: спира SBD демона с командата killall -STOP sbd.
  • Изключвам: чрез SSH изпраща команда до виртуалната машина systemctl poweroff, системата се изключва плавно.
  • прекратете връзката: изолация на мрежата, команда VBoxManage controlvm "виртуалка" setlinkstate1 off.

Завършете тестването със стандартната tmux команда "kill-window" ctrl-b&, или чрез командата "detach-client" ctrl-bd: в същото време тестването е завършено, tmux е затворен, виртуалните машини са изключени.

Проблеми, идентифицирани по време на тестване

  • В този момент пазач демон sbd управлява спирането на наблюдаваните демони, но не ги замразява. И в резултат на това неизправностите се отчитат неправилно, което води само до замръзване Corosync и пейсмейкър, но не виси SBD... За проверка Corosync вече имам PR#83 (в GitHub на SBD), приети във филиала майстор. Обещаха (в PR#83), че ще има нещо подобно за Pacemaker, надявам се до Червена шапка 8 ще го направя. Но такива „неизправности“ са спекулативни, лесно се имитират изкуствено, като се използват, например, killall -STOP corosyncно никога не се срещат в реалния живот.

  • У пейсмейкър във версия за CentOS 7 неправилно настроен време за изчакване на синхронизиране у устройство за кворум, като резултат ако един възел се повреди, вторият възел се рестартира с известна вероятност, в който е трябвало да се премести майсторът. Излекуван чрез увеличение време за изчакване на синхронизиране у устройство за кворум по време на внедряване (в скрипт setup/setup1). Това изменение не беше прието от разработчиците пейсмейкър, вместо това те обещаха да преработят инфраструктурата по такъв начин (в някакво неопределено бъдеще), че това време за изчакване да се изчислява автоматично.

  • Ако сте посочили по време на конфигурацията на базата данни, че LC_MESSAGES (текстови съобщения) Unicode може да се използва, например, ru_RU.UTF-8, след това при стартиране Postgres в среда, където локалът не е UTF-8, да речем, в празна среда (тук пейсмейкър+pgsqlms(paf) започва Postgres) тогава в дневника вместо UTF-8 букви ще има въпросителни знаци. Разработчиците на PostgreSQL никога не са се съгласили какво да правят в този случай. Струва, трябва да поставите LC_MESSAGES=en_US.UTF-8 при конфигуриране (създаване) на екземпляр на DB.

  • Ако е зададен wal_receiver_timeout (по подразбиране е 60s), тогава при тестване на PostgreSQL-STOP на главния в тучанка3 и тучанка4 клъстери Репликацията не се свързва отново с нов главен. Репликацията там е синхронна, така че спира не само slave, но и новият master. Получава чрез настройка на wal_receiver_timeout=0 при конфигуриране на PostgreSQL.

  • От време на време наблюдавах репликация на PostgreSQL да виси в теста ForkBomb (препълване на паметта). След ForkBomb понякога подчинените устройства може да не се свържат отново с новия главен. Виждал съм това само в клъстери tuchanka3 и tuchanka4, където поради факта, че репликацията е синхронна, главният увисна. Проблемът изчезна сам след известно време (около два часа). Необходими са повече изследвания, за да се коригира това. Симптомите са подобни на предишната грешка, която е причинена от различна причина, но със същите последствия.

Снимката на Krogan е направена от девиантно изкуство с разрешението на автора:

Моделиране на отказоустойчиви клъстери, базирани на PostgreSQL и Pacemaker

Източник: www.habr.com

Добавяне на нов коментар