Cloister → простае кіраванне кластарам OTP

Практычна кожнае паспяховае бізнес-дадатак рана ці позна ўступае ў фазу, калі патрабуецца гарызантальнае маштабаванне. У шматлікіх выпадках можна проста запусціць новы асобнік і паменшыць сярэднюю нагрузку. Але бываюць і меней трывіяльныя выпадкі, калі мы павінны забяспечыць, каб розныя ноды ведалі сябар пра сябра і акуратна размяркоўвалі працоўную нагрузку.

Cloister → простае кіраванне кластарам OTP

Так удала атрымалася, што эрланг, які мы выбралі за прыемны сінтаксіс і хайп вакол, мае першакласную падтрымку для размеркаваных сістэм. У тэорыі гэта гучыць увогуле трывіяльна:

Перадача паведамленняў паміж працэсамі на розных вузлах, а таксама паміж спасылкамі і маніторамі празрыстая […]

На практыцы ўсё крыху больш складана. Размеркаваны эрланг быў распрацаваны, калі «кантэйнер» азначаў такую ​​вялікую жалезную скрыню для перавозкі, а «докер» быў проста сінонімам партовага грузчыка. У IP4 было шмат незанятых адрасоў, у сеткавых парывах - былі, як правіла, вінаватыя перагрызлыя кабель пацукі, а сярэдні час безадмоўнай працы вытворчай сістэмы вымяралася дзесяцігоддзямі.

Цяпер мы ўсе няўяўна самадастатковыя, спакаваныя, і запускаем размеркаваны эрланг у асяроддзі, дзе дынамічныя IP-адрасы раздаюцца па прынцыпе вялікай выпадковасці, а вузлы могуць з'яўляцца і знікаць па жаданні левай пяткі планавальніка. Каб пазбегнуць кучы шаблоннага кода ў кожным праекце, які запускае размеркаваны эрланг, для барацьбы з варожым асяроддзем, патрабуецца дапамога.

Заўвага: я ў курсе што ёсць libcluster. Ён сапраўды круты, у яго больш за тысячу зорак, аўтар - вядомы ў супольнасці, і ўсё такое. Калі вам дастаткова прапанаваных гэтым пакетам спосабаў стварэння і падтрымкі кластара - я рады за вас. Мне, нажаль, трэба значна больш. Я хачу кіраваць настройкай у дэталях і не быць пабочным гледачом у тэатры перафарміравання кластара.

Патрабаванні

Што было патрэбна асабіста мне, дык гэта бібліятэка, якая возьме на сябе кіраванне кластарам і будзе валодаць наступнымі ўласцівасцямі:

  • празрыстая праца як з жорстка закадаваным спісам вузлоў, так і з дынамічным выяўленнем праз сэрвісы эрланг;
  • поўнафункцыянальны колбэк пры кожнай змене тапалогіі (вузел туды, вузел сюды, нестабільнасць сеткі, спліты);
  • празрысты інтэрфейс для запуску кластара з доўгімі і кароткімі імёнамі, як і з :nonode@nohost;
  • падтрымка докера са скрынкі, без неабходнасці пісаць інфраструктурны код.

Апошняе азначае, што пасля таго, як я пратэставаў прыкладанне лакальна ў :nonode@nohost, або ў штучна-размеркаваным асяроддзі пры дапамозе test_cluster_task, я хачу проста запусціць docker-compose up --scale my_app=3 і ўбачыць, як яно выконвае тры асобнікі ў докеру без якіх-небудзь змяненняў кода. Я таксама хачу, каб залежныя прыкладанні, напрыклад mnesia - калі тапалогія змяняецца, за кулісамі перабудоўвалі кластар нажывую без якога-небудзь дадатковага выспятка з боку прыкладання.

Кляштар не задумваўся як бібліятэка, здольная на ўсё: ад падтрымкі кластара да гатавання кавы. Гэта не сярэбраная куля, якая імкнецца ахапіць усе магчымыя выпадкі, ці быць акадэмічна поўным рашэннем у тым сэнсе, які тэарэтыкі ад CS укладваюць у гэты тэрмін. Гэта бібліятэка заклікана служыць вельмі дакладнай мэты, але выконваць свой не занадта вялікі аб'ём работ ідэальна. Гэтая мэта будзе заключацца ў забеспячэнні поўнай празрыстасці паміж лакальным асяроддзем распрацоўкі і размеркаваным эластычным асяроддзем, поўнай варожых кантэйнераў.

Абраны падыход

Кляштар мяркуецца запускаць як дадатак, хоць дасведчаныя карыстачы могуць працаваць са зборкай і падтрымкай (assembly and maintainance) кластара ўручную, непасрэдна запусціўшы Cloister.Manager у дрэве супервізораў мэтавага прыкладання.

Пры запуску ў якасці дадатку, бібліятэка належым на config, адкуль вычытвае наступныя асноўныя значэнні:

config :cloister,
  otp_app: :my_app,
  sentry: :"cloister.local", # or ~w|n1@foo n2@bar|a
  consensus: 3,              # number of nodes to consider
                             #    the cluster is up
  listener: MyApp.Listener   # listener to be called when
                             #    the ring has changed

Параметры вышэй азначае даслоўна наступнае: Кляштар выкарыстоўваецца для OTP прыкладання :my_app, выкарыстоўвае erlang service discovery для падлучэння вузлоў, трох па меншай меры, і MyApp.Listener модуль (імплементуючы @behaviour Cloister.Listener) настроены атрымліваць апавяшчэнні аб зменах тапалогіі. Падрабязнае апісанне поўнай канфігурацыі можна знайсці ў дакументацыі.

Пры такой канфігурацыі, дадатак Кляштар будзе запускацца паэтапна, адкладаючы працэс старту галоўнага прыкладання да дасягнення кансэнсусу (тры вузла падлучаныя і злучаныя, як у прыведзеным вышэй прыкладзе.) Гэта дае галоўнаму з дадаткам магчымасць выказаць здагадку, што калі яно запусцілася, кластар ужо даступны. Пры кожнай змене тапалогіі (іх будзе шмат, таму што вузлы запускаюцца не цалкам сінхронна), будзе выкліканы апрацоўшчык MyApp.Listener.on_state_change/2. У большасці выпадкаў мы выконваем дзеянне, калі атрымліваем паведамленне са станам %Cloister.Monitor{status: :up}, што азначае: "алё, кластар сабраны".

У большасці выпадкаў усталёўка consensus: 3 з'яўляецца аптымальнай, таму што нават калі мы чакаем, што падключыцца больш вузлоў, зваротны выклік будзе праходзіць праз status: :rehashingstatus: :up на любым новым дададзеным ці выдаленым вузле.

Пры запуску ў рэжыме распрацоўкі, дастаткова проста выставіць consensus: 1 и Кляштар радасна праскочыць чаканне зборкі кластара, убачыўшы :nonode@nohost, Або :node@host, Або :[email protected] - у залежнасці ад таго, як быў наладжаны вузел (:none | :shortnames | :longnames).

Упраўленне размеркаванымі праграмамі

Размеркаваныя прыкладанні не ў вакууме звычайна ўключаюць размеркаваныя ж залежнасці, тыпу mnesia. Нам лёгка апрацоўваць іх пераканфігурацыю з таго ж зваротнага выкліку. on_state_change/2. Вось, напрыклад, падрабязнае апісанне таго, як пераналадзіць mnesia на лета ў дакументацыі Кляштар.

Галоўнай перавагай выкарыстання Кляштар з'яўляецца тое, што ён выконвае ўсе неабходныя аперацыі па перабудове кластара пасля змены тапалогіі пад капотам. Дадатак проста запускаецца ва ўжо падрыхтаваным размеркаваным асяроддзі, з усімі падлучанымі вузламі, незалежна ад таго, ці ведаем мы IP-адрасы і, такім чынам, імёны вузлоў загадзя, ці яны былі дынамічна прызначаны/зменены. Гэта патрабуе роўна ніякіх спецыяльных налад канфігурацыі докера і з пункту гледжання распрацоўшчыка прыкладанняў, няма ніякай розніцы паміж запускам у размеркаваным асяроддзі або ў лакальнай на :nonode@nohost. Падрабязней пра гэта можна пачытаць у дакументацыі.

Нягледзячы на ​​тое, што складаная апрацоўка змен тапалогіі магчымая праз уласную рэалізацыю MyApp.Listener, заўсёды могуць быць памежныя выпадкі, калі гэтыя абмежаванні бібліятэкі і прадузяты падыход да канфігурацыі апынуцца краевугольным каменем на шляху ўкаранення. Гэта нармальна, проста вазьміце вышэйзгаданы libcluster, Які з'яўляецца больш універсальным, ці нават апрацуйце кластар нізкага ўзроўню самастойна. Мэта гэтай бібліятэкі кода складаецца не ў тым, каб ахапіць усе магчымыя сцэнары, а ў тым, каб выкарыстоўваць найболей распаўсюджаны сцэнар без непатрэбнага болю і грувасткіх копі-пастоў.

Заўвага: на гэтым месцы ў арыгінале была фраза «Happy clustering!», і Яндэкс, якім я перакладаю (не самому ж па слоўніках лазіць), прапанаваў мне варыянт «Шчаслівага збору!». Лепшага перакладу, мабыць, асабліва ў святле бягучай геапалітычнай сітуацыі - і ўявіць немагчыма.

Крыніца: habr.com

Дадаць каментар