Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

У чланку ћу вам рећи како смо приступили питању толеранције грешака ПостгреСКЛ-а, зашто нам је то постало важно и шта се на крају догодило.

Имамо веома оптерећену услугу: 2,5 милиона корисника широм света, 50К+ активних корисника сваког дана. Сервери се налазе у Амазонеу у једном региону Ирске: 100+ различитих сервера стално ради, од којих је скоро 50 са базама података.

Целокупна позадина је велика монолитна Јава апликација са стањем која одржава сталну вебсоцкет везу са клијентом. Када неколико корисника истовремено ради на истој табли, сви они виде промене у реалном времену, јер сваку промену уписујемо у базу података. Имамо око 10 захтева у секунди у наше базе података. При врхунском оптерећењу у Редис-у пишемо 80-100 захтева у секунди.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Зашто смо прешли са Редис-а на ПостгреСКЛ

У почетку је наша услуга радила са Редис-ом, складиштем кључ/вредност које чува све податке у РАМ-у сервера.

Предности Редис-а:

  1. Велика брзина одзива, јер све се чува у меморији;
  2. Једноставност прављења резервних копија и репликације.

Недостаци Редиса за нас:

  1. Нема правих трансакција. Покушали смо да их симулирамо на нивоу наше апликације. Нажалост, ово није увек добро функционисало и захтевало је писање веома сложеног кода.
  2. Количина података је ограничена количином меморије. Како се количина података повећава, меморија ће расти, и на крају ћемо наићи на карактеристике изабране инстанце, што у АВС-у захтева заустављање наше услуге да бисмо променили тип инстанце.
  3. Неопходно је стално одржавати низак ниво латенције, јер. имамо веома велики број захтева. Оптимални ниво кашњења за нас је 17-20 мс. На нивоу од 30-40 мс добијамо дуге одговоре на захтеве наше апликације и деградацију услуге. Нажалост, ово нам се догодило у септембру 2018. године, када је једна од инстанци са Редис-ом из неког разлога имала кашњење 2 пута више него иначе. Да бисмо решили проблем, зауставили смо услугу средином дана због непланираног одржавања и заменили проблематичну Редис инстанцу.
  4. Лако је добити недоследност података чак и са мањим грешкама у коду, а затим потрошити доста времена на писање кода да бисте исправили ове податке.

Узели смо у обзир недостатке и схватили да морамо да пређемо на нешто погодније, са нормалним трансакцијама и мање зависности од кашњења. Спровео истраживање, анализирао многе опције и изабрао ПостгреСКЛ.

Већ 1,5 годину прелазимо на нову базу података и преместили смо само мали део података, тако да сада радимо истовремено са Редис-ом и ПостгреСКЛ-ом. Више информација о фазама премештања и пребацивања података између база података је написано чланак мог колеге.

Када смо први пут почели да се крећемо, наша апликација је радила директно са базом података и приступала главном Редис-у и ПостгреСКЛ-у. ПостгреСКЛ кластер се састојао од мастера и реплике са асинхроном репликацијом. Овако је изгледала шема базе података:
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Имплементација ПгБоунцер-а

Док смо се кретали, развијао се и производ: повећао се број корисника и број сервера који су радили са ПостгреСКЛ-ом, а почеле су нам недостајати везе. ПостгреСКЛ креира посебан процес за сваку везу и троши ресурсе. Можете повећати број веза до одређене тачке, иначе постоји шанса да добијете неоптималне перформансе базе података. Идеална опција у таквој ситуацији била би одабир менаџера везе који ће стајати испред базе.

Имали смо две опције за менаџер везе: Пгпоол и ПгБоунцер. Али први не подржава трансакциони начин рада са базом података, па смо изабрали ПгБоунцер.

Поставили смо следећу шему рада: наша апликација приступа једном ПгБоунцер-у иза којег се налазе ПостгреСКЛ мастери, а иза сваког мастера је по једна реплика са асинхроном репликацијом.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Истовремено, нисмо могли да ускладиштимо целу количину података у ПостгреСКЛ-у и брзина рада са базом података нам је била важна, па смо почели да делимо ПостгреСКЛ на нивоу апликације. Горе описана шема је релативно згодна за ово: приликом додавања новог ПостгреСКЛ шарда, довољно је ажурирати конфигурацију ПгБоунцер-а и апликација може одмах да ради са новим шардом.

ПгБоунцер фаиловер

Ова шема је радила до тренутка када је једина инстанца ПгБоунцер умрла. Налазимо се у АВС-у, где се све инстанце покрећу на хардверу који повремено умире. У таквим случајевима, инстанца једноставно прелази на нови хардвер и поново ради. Ово се десило са ПгБоунцер-ом, али је постао недоступан. Резултат овог пада била је недоступност наше услуге 25 минута. АВС препоручује коришћење редундансе на страни корисника за такве ситуације, што у то време није било примењено у нашој земљи.

После тога смо озбиљно размишљали о толеранцији грешака ПгБоунцер и ПостгреСКЛ кластера, јер би се слична ситуација могла десити са било којом инстанцом на нашем АВС налогу.

Направили смо ПгБоунцер шему толеранције грешака на следећи начин: сви сервери апликација приступају Нетворк Лоад Баланцер-у, иза којег се налазе два ПгБоунцер-а. Сваки ПгБоунцер гледа на исти ПостгреСКЛ мастер сваког шарда. Ако поново дође до пада АВС инстанце, сав саобраћај се преусмерава преко другог ПгБоунцер-а. Мрежни балансер оптерећења обезбеђује АВС.

Ова шема олакшава додавање нових ПгБоунцер сервера.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Направите ПостгреСКЛ Фаиловер Цлустер

Приликом решавања овог проблема, разматрали смо различите опције: само-написани прелазак на грешку, репмгр, АВС РДС, Патрони.

Самонаписане скрипте

Они могу да прате рад мастера и, ако не успе, да промовишу реплику у мастер и ажурирају конфигурацију ПгБоунцер-а.

Предности овог приступа су максимална једноставност, јер сами пишете скрипте и разумете како тачно функционишу.

Против:

  • Мастер можда није умро, већ је можда дошло до квара на мрежи. Фаиловер, несвестан тога, промовисаће реплику мајстору, док ће стари мајстор наставити да ради. Као резултат тога, добићемо два сервера у улози мастера и нећемо знати који од њих има најновије ажурне податке. Ова ситуација се такође назива сплит-браин;
  • Остали смо без одговора. У нашој конфигурацији, мастер и једна реплика, након пребацивања, реплика се помера на мастер и више немамо реплике, тако да морамо ручно да додамо нову реплику;
  • Потребан нам је додатни надзор операције преласка на грешку, док имамо 12 ПостгреСКЛ шарда, што значи да морамо да надгледамо 12 кластера. Са повећањем броја фрагмената, такође морате запамтити да ажурирате прелазак на грешку.

Самонаписани прелазак на грешку изгледа веома компликовано и захтева нетривијалну подршку. Са једним ПостгреСКЛ кластером, ово би била најлакша опција, али се не скалира, тако да није погодна за нас.

Репмгр

Менаџер репликације за ПостгреСКЛ кластере, који може да управља радом ПостгреСКЛ кластера. У исто време, нема аутоматски прелазак на грешку из кутије, тако да ћете за рад морати да напишете сопствени „омот“ на врху готовог решења. Дакле, све може да испадне још компликованије него са скриптама које су сами написали, тако да Репмгр нисмо ни пробали.

АВС РДС

Подржава све што нам је потребно, зна како да прави резервне копије и одржава скуп веза. Има аутоматско пребацивање: када мастер умре, реплика постаје нови мастер, а АВС мења днс запис у нови мастер, док се реплике могу налазити у различитим АЗ-овима.

Недостаци укључују недостатак финих подешавања. Као пример финог подешавања: наше инстанце имају ограничења за тцп везе, што се, нажалост, не може урадити у РДС-у:

net.ipv4.tcp_keepalive_time=10
net.ipv4.tcp_keepalive_intvl=1
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_retries2=3

Поред тога, АВС РДС је скоро дупло скупљи од цене регуларне инстанце, што је и био главни разлог одустајања од овог решења.

покровитељ

Ово је питхон шаблон за управљање ПостгреСКЛ-ом са добром документацијом, аутоматским преласком на грешку и изворним кодом на гитхуб-у.

Предности Патронија:

  • Сваки конфигурациони параметар је описан, јасно је како функционише;
  • Аутоматско пребацивање на грешку ради без употребе;
  • Написано на Питхон-у, а пошто и сами доста пишемо на Питхон-у, биће нам лакше да се носимо са проблемима и, можда, чак и помогнемо развоју пројекта;
  • У потпуности управља ПостгреСКЛ-ом, омогућава вам да промените конфигурацију на свим чворовима кластера одједном, а ако кластер треба поново да се покрене да би се применила нова конфигурација, то се може поново урадити помоћу Патронија.

Против:

  • Из документације није јасно како правилно радити са ПгБоунцер-ом. Иако је то тешко назвати минусом, јер је Патронијев задатак да управља ПостгреСКЛ-ом, а како ће ићи везе са Патронијем је већ наш проблем;
  • Мало је примера имплементације Патронија у великим количинама, док има много примера имплементације од нуле.

Као резултат тога, изабрали смо Патрони да креирамо кластер за превазилажење грешке.

Патрони процес имплементације

Пре Патронија, имали смо 12 ПостгреСКЛ шардова у конфигурацији од једног мастера и једне реплике са асинхроном репликацијом. Апликациони сервери су приступили базама података преко Нетворк Лоад Баланцер-а, иза којег су биле две инстанце са ПгБоунцер-ом, а иза њих су били сви ПостгреСКЛ сервери.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Да бисмо имплементирали Патрони, морали смо да изаберемо конфигурацију дистрибуираног складишног кластера. Патрони ради са системима за складиштење дистрибуираних конфигурација као што су етцд, Зоокеепер, Цонсул. Имамо само пуноправни Цонсул кластер на тржишту, који ради заједно са Ваулт-ом и више га не користимо. Одличан разлог да почнете да користите Цонсул за његову намену.

Како Патрони ради са Конзулом

Имамо Цонсул кластер, који се састоји од три чвора, и Патрони кластер, који се састоји од лидера и реплике (у Патрони, мастер се зове вођа кластера, а робови се називају реплике). Свака инстанца кластера Патрони константно шаље информације о стању кластера Конзулу. Стога, од Конзула увек можете сазнати тренутну конфигурацију кластера Патрони и ко је тренутно лидер.

Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Да бисте повезали Патрони са Цонсулом, довољно је проучити званичну документацију у којој пише да је потребно да наведете хост у хттп или хттпс формату, у зависности од тога како радимо са Цонсулом, и шему повезивања, опционо:

host: the host:port for the Consul endpoint, in format: http(s)://host:port
scheme: (optional) http or https, defaults to http

Изгледа једноставно, али овде почињу замке. Са Цонсул-ом радимо преко безбедне везе преко хттпс и наша конфигурација везе ће изгледати овако:

consul:
  host: https://server.production.consul:8080 
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

Али то не ради. Приликом покретања, Патрони не може да се повеже са Цонсул-ом, јер ионако покушава да прође кроз хттп.

Изворни код Патронија је помогао да се реши проблем. Добро је што је написано на Питхон-у. Испоставило се да параметар хоста није рашчлањен ни на који начин, а протокол мора бити наведен у шеми. Овако за нас изгледа радни конфигурациони блок за рад са Консулом:

consul:
  host: server.production.consul:8080
  scheme: https
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

конзул-шаблон

Дакле, изабрали смо складиште за конфигурацију. Сада морамо да разумемо како ће ПгБоунцер променити своју конфигурацију када промени лидера у Патрони кластеру. На ово питање у документацији нема одговора, јер. тамо, у принципу, рад са ПгБоунцер-ом није описан.

У потрази за решењем пронашли смо чланак (нажалост не сећам се наслова) где је писало да је Цонсул-темплате много помогао у упаривању ПгБоунцер-а и Патронија. То нас је навело да истражимо како Цонсул-темплате функционише.

Испоставило се да Цонсул-темплате стално прати конфигурацију ПостгреСКЛ кластера у Цонсул-у. Када се вођа промени, ажурира конфигурацију ПгБоунцер-а и шаље команду за поновно учитавање.

Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Велики плус шаблона је што се чува као код, тако да је приликом додавања новог шарда довољно да направите нови урезивање и аутоматски ажурирате шаблон, подржавајући принцип Инфраструктура као код.

Нова архитектура са Патронијем

Као резултат, добили смо следећу шему рада:
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Сви сервери апликација приступају балансеру → иза њега стоје две инстанце ПгБоунцер-а → на свакој инстанци се покреће Цонсул-темплате, који прати статус сваког Патрони кластера и прати релевантност ПгБоунцер конфигурације, која шаље захтеве тренутном лидеру сваког кластера.

Ручно тестирање

Покренули смо ову шему пре него што смо је покренули у малом тестном окружењу и проверили рад аутоматског пребацивања. Отворили су таблу, померили налепницу и у том тренутку „убили” вођу кластера. У АВС-у, ово је једноставно као искључивање инстанце преко конзоле.

Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Налепница се вратила у року од 10-20 секунди, а затим је поново почела да се креће нормално. То значи да је Патрони кластер функционисао исправно: променио је вођу, послао информације Консулу, а Цонсул-темплате је одмах покупио ове информације, заменио конфигурацију ПгБоунцер-а и послао команду за поновно учитавање.

Како преживети под великим оптерећењем и задржати застоје на минимуму?

Све ради савршено! Али постоје нова питања: како ће функционисати под великим оптерећењем? Како брзо и безбедно све покренути у производњи?

Тестно окружење у којем спроводимо тестирање оптерећења помаже нам да одговоримо на прво питање. Потпуно је идентичан производњи у смислу архитектуре и генерисао је тестне податке који су по обиму приближно једнаки производњи. Одлучујемо да само „убијемо“ једног од ПостгреСКЛ мастера током теста и видимо шта ће се десити. Али пре тога, важно је проверити аутоматско роловање, јер у овом окружењу имамо неколико ПостгреСКЛ шардова, тако да ћемо добити одлично тестирање конфигурационих скрипти пре производње.

Оба задатка изгледају амбициозно, али имамо ПостгреСКЛ 9.6. Можемо ли одмах надоградити на 11.2?

Одлучили смо да то урадимо у 2 корака: прво надоградимо на 11.2, а затим покренемо Патрони.

ПостгреСКЛ ажурирање

Да бисте брзо ажурирали верзију ПостгреСКЛ-а, користите опцију -k, у којој се праве везе на диску и нема потребе за копирањем ваших података. На бази од 300-400 ГБ, ажурирање траје 1 секунду.

Имамо много фрагмената, тако да ажурирање треба да се обави аутоматски. Да бисмо то урадили, написали смо Ансибле плаибоок који управља читавим процесом ажурирања за нас:

/usr/lib/postgresql/11/bin/pg_upgrade 
<b>--link </b>
--old-datadir='' --new-datadir='' 
 --old-bindir=''  --new-bindir='' 
 --old-options=' -c config_file=' 
 --new-options=' -c config_file='

Овде је важно напоменути да пре него што започнете надоградњу, морате је извршити са параметром --провераватида бисте били сигурни да можете надоградити. Наша скрипта такође врши замену конфигурација за време трајања надоградње. Наш сценарио је завршен за 30 секунди, што је одличан резултат.

Покрените Патрони

Да бисте решили други проблем, само погледајте Патрони конфигурацију. Званично спремиште има пример конфигурације са инитдб, који је одговоран за иницијализацију нове базе података када први пут покренете Патрони. Али пошто већ имамо готову базу података, једноставно смо уклонили овај одељак из конфигурације.

Када смо почели да инсталирамо Патрони на већ постојећи ПостгреСКЛ кластер и покрећемо га, наишли смо на нови проблем: оба сервера су почела као водећи. Патрони не зна ништа о раном стању кластера и покушава да покрене оба сервера као два одвојена кластера са истим именом. Да бисте решили овај проблем, потребно је да избришете директоријум са подацима на славе-у:

rm -rf /var/lib/postgresql/

Ово треба да се уради само на робу!

Када је чиста реплика повезана, Патрони прави вођу базе резервне копије и враћа је у реплику, а затим сустиже тренутно стање према евиденцији зида.

Још једна потешкоћа на коју смо наишли је да се сви ПостгреСКЛ кластери подразумевано називају главним. Када сваки кластер не зна ништа о другом, то је нормално. Али када желите да користите Патрони, онда сви кластери морају имати јединствено име. Решење је да промените име кластера у ПостгреСКЛ конфигурацији.

тест оптерећења

Покренули смо тест који симулира корисничко искуство на плочама. Када је оптерећење достигло нашу просечну дневну вредност, поновили смо потпуно исти тест, искључили смо једну инстанцу са ПостгреСКЛ лидером. Аутоматско пребацивање на грешку је функционисало како смо очекивали: Патрони је променио вођу, Цонсул-темплате је ажурирао конфигурацију ПгБоунцер-а и послао команду за поновно учитавање. Према нашим графиконима у Графани, било је јасно да постоје кашњења од 20-30 секунди и мала количина грешака са сервера повезаних са везом са базом података. Ово је нормална ситуација, такве вредности су прихватљиве за наш прелазак на грешку и дефинитивно су боље од времена застоја услуге.

Довођење Патронија у производњу

Као резултат тога, дошли смо до следећег плана:

  • Поставите Цонсул-темплате на ПгБоунцер сервере и покрените;
  • ПостгреСКЛ ажурирања на верзију 11.2;
  • Промените име кластера;
  • Покретање кластера Патрони.

У исто време, наша шема нам омогућава да направимо прву тачку скоро у било ком тренутку, можемо да уклонимо сваки ПгБоунцер са посла заузврат и да применимо и покренемо цонсул-темплате на њему. Тако смо и урадили.

За брзу имплементацију користили смо Ансибле, пошто смо већ тестирали све плаибоок-ове у тестном окружењу, а време извршавања пуне скрипте је било од 1,5 до 2 минута за сваки шард. Могли бисмо све редом да избацимо на сваки шард без заустављања наше услуге, али бисмо морали да искључимо сваки ПостгреСКЛ на неколико минута. У овом случају, корисници чији се подаци налазе на овом шарду у овом тренутку нису могли у потпуности да раде, а то је за нас неприхватљиво.

Излаз из ове ситуације било је планирано одржавање, које се одвија свака 3 месеца. Ово је прозор за планирани рад, када потпуно гасимо нашу услугу и надоградимо инстанце базе података. До следећег прозора остало је још недељу дана, а ми смо одлучили да само сачекамо и даље се припремамо. Током чекања додатно смо се обезбедили: за сваки ПостгреСКЛ шард подигли смо резервну реплику у случају неуспеха чувања најновијих података и додали нову инстанцу за сваки шард, која би требало да постане нова реплика у Патрони кластеру, како не би извршио команду за брисање података . Све ово је помогло да се ризик од грешке минимизира.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Поново смо покренули наш сервис, све је радило како треба, корисници су наставили да раде, али на графиконима смо приметили ненормално велико оптерећење на серверима Цонсул.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Зашто ово нисмо видели у тестном окружењу? Овај проблем веома добро илуструје да је неопходно пратити принцип Инфраструктура као код и усавршити целокупну инфраструктуру, од тест окружења до продукције. Иначе, врло је лако добити проблем који имамо. Шта се десило? Цонсул се прво појавио у продукцијском, а затим у тест окружењима, као резултат тога, на тестним окружењима, верзија Цонсул-а је била виша него у производњи. Само у једном од издања, цурење ЦПУ-а је решено када се ради са цонсул-темплате-ом. Стога смо једноставно ажурирали Цонсул и тако решили проблем.

Поново покрените Патрони кластер

Међутим, добили смо нови проблем за који нисмо ни слутили. Када ажурирамо Цонсул, једноставно уклањамо Цонсул чвор из кластера помоћу команде цонсул леаве → Патрони се повезује на други Цонсул сервер → све ради. Али када смо стигли до последње инстанце Цонсул кластера и послали му команду за напуштање конзула, сви Патрони кластери су се једноставно поново покренули и у евиденцији смо видели следећу грешку:

ERROR: get_cluster
Traceback (most recent call last):
...
RetryFailedError: 'Exceeded retry deadline'
ERROR: Error communicating with DCS
<b>LOG: database system is shut down</b>

Патрони кластер није успео да преузме информације о свом кластеру и поново је покренут.

Да бисмо пронашли решење, контактирали смо Патрони ауторе преко проблема на гитхуб-у. Предложили су побољшања наших конфигурационих датотека:

consul:
 consul.checks: []
bootstrap:
 dcs:
   retry_timeout: 8

Успели смо да поновимо проблем у тестном окружењу и тамо тестирали ове опције, али нажалост нису функционисале.

Проблем и даље остаје нерешен. Планирамо да испробамо следећа решења:

  • Користите Цонсул-агент на свакој инстанци кластера Патрони;
  • Решите проблем у коду.

Разумемо где је дошло до грешке: проблем је вероватно у коришћењу подразумеваног временског ограничења, које се не поништава кроз конфигурациону датотеку. Када се последњи Цонсул сервер уклони из кластера, цео Цонсул кластер виси дуже од секунде, због чега Патрони не може да добије статус кластера и потпуно рестартује цео кластер.

На срећу, више нисмо наишли на грешке.

Резултати коришћења Патрони

Након успешног лансирања Патронија, додали смо додатну реплику у сваки кластер. Сада у сваком кластеру постоји привид кворума: један вођа и две реплике, за сигурносну мрежу у случају поделе мозга приликом пребацивања.
Фаиловер Цлустер ПостгреСКЛ + Патрони. Искуство имплементације

Патрони ради на производњи више од три месеца. За то време је већ успео да нам помогне. Недавно је вођа једног од кластера умро у АВС-у, аутоматски прелазак на грешку је функционисао и корисници су наставили да раде. Патрони је испунио свој главни задатак.

Мали резиме употребе Патронија:

  • Лакоћа промена конфигурације. Довољно је променити конфигурацију на једној инстанци и она ће се повући на цео кластер. Ако је потребно поновно покретање да би се применила нова конфигурација, Патрони ће вас обавестити. Патрони може поново покренути цео кластер са једном командом, што је такође веома згодно.
  • Аутоматско пребацивање на грешку функционише и већ нам је успело да нам помогне.
  • ПостгреСКЛ ажурирање без застоја апликације. Прво морате ажурирати реплике на нову верзију, затим променити лидера у Патрони кластеру и ажурирати стару вођу. У овом случају долази до неопходног тестирања аутоматског преласка на грешку.

Извор: ввв.хабр.цом

Додај коментар