2014-04-05 Лекция “Single points of failure и избягването им” от RogueConf 2014
by Vasil KolevТова ми е в общи линии лекцията от rogueconf, презентацията може да се свали от тук, записът от тук. Има прилични разлики в това, което говорих, и реално ми се искаше да наблегна много повече на дистрибутирането, но нямах време да се подготвя и да го събера в нормалното време.
(и определено можеше да е по-добре, не става добре да говоря на конференции, където имам занимания и с организацията)
Single points of failure
[за какво става въпрос]
Single point of failure е единичен компонент от система, при чиито отказ цялата система спира да работи.
В системите, които правим/ползваме и са повече от един сървър, на който ни е всичко (т.е. един гигантски SPOF) такива неща пак се срещат доста често.
[авиационен модел]
Това е мечтания модел, който даже съществува в реалния свят. Това е напълно подсигурена система, при която имате главен компютър с един софтуер и един хардуер, backup компютри с два различни хардуера и един софтуер, който е различен от главния, и система за следене и кворум. В самолета освен това има и двама пилоти и всякакви резервни варианти.
[авиационен модел 2]
Това е скъпо. Толкова скъпо, че го правят само за случаи, при които умират хора (т.е. дори и в медицинската апаратура не се стига до такива подсигурявания).
Също така системите стават твърде усложнени, като пример – A380, който е наистина подсигурена система, има в себе си 530км кабели. Цената да се изгради и да се поддържа такава система не е по силите на някой друг.
[три неща]
И три неща, за които няма да говоря подробно.
[Софтуерни]
Софтуерните SPOF-ове никой не се опитва да ги заобикаля, или поне не сериозно. Правенето на няколко независими реализации на дадено нещо рядко е оправдано, отнема двойно повече усилия и се дебъгват два пъти подобни проблеми без да може кой-знае колко да се приложат знанията от едното в другото. Поддръжката на две различни системи за същото нещо и комуникацията между тях правят цялото нещо повече от два пъти по-скъпо и сложно.
А проблемите, които се получават от тях са доста по-неприятни, понеже са лавинообразни – ако на няколко места имате същия софтуер, може да очаквате, че ще се чупи по същия начин и в същото време.
[Meatware]
Човешките SPOF-ове са още по-гадна работа. Известни са още като “Bus factor”, т.е. колко човека трябва да ги блъсне автобус, за да спре да работи даден проект (и в много случаи факторът е 1).
В по-големите фирми се правят опити да се реши тоя проблем чрез взимане на повече хора, които да могат да поемат работата един на друг, но синхронизацията м/у хора се оказва още по-сложен проблем и не подлежащ на автоматизация.
Метод за омекотяване е писането на документация, което па всички го мразят.
[цена]
Оценката кога си струва да се вложат средства, за да се избегне SPOF не винаги е тривиална и е за друг вид лекция. Има неща като risk assessment, гадаене по черва на гълъби, хвърляне на зарчета и статистически анализи, които се използват за целта, но много често и хората, които ги предлагат ги объркват…
(който се интересува от проблемите на анализа на риска, може да зачете Насим Талеб)
Като едно лично правило, гледам системите да нямат в себе си нещо, което е наистина трудно за дистрибутиране, или ако го има, да е максимално подсигурено (хубав хардуер, monitoring, резервни части, някакъв вариант да се реагира).
[state]
И нека се хванем с основния проблем във всички тези неща – състоянието, или state, както му викаме.
От машините на Тюринг насам състоянието е нещо основно в това, което правим. Няма система без някакъв state, и съответно една голяма част от решаването на проблемите със SPOF-овете идват от там (иначе просто щяхме да хвърляме хардуер, докато нещата почнат да изглеждат добре).
Искам да го повторя и да покажа, не съществуват stateless системи.
[примерна не-stateless система]
Ето един често срещан пример – смята се, че ако имаме такава схема, то web сървърите ни са stateless, понеже реално са взаимозаменяеми.
От гледна точка на системата те имат два вида state. По-маловажният са заявките, които се обработват в момента (които не се смятат за важни и съответно дори да се загубят, се смята, че може да се повторят. Важният state е един бит, който казва дали този сървър е активен или не, и дали може да обработва заявки.
Съответно цялата система трябва да е сравнително сихронизирана за този един бит, за да може да работи правилно (т.е. ок е сървърът да работи, и системата да не смята така, не е ок да не работи и системата да се опитва да го ползва).
[решения]
Ето няколкото типа решения на проблема.
[do nothing]
Това е стандартния план – повчето хора не очакват, че нещо лошо ще се случи, носят розови очила и не бива да бъдат допускани да мислят системи.
[backup plan]
Може да не е толкова безсмислен като тоя от слайда :)
Тук решението е да знаем какво правим, ако нещо се счупи. За някои по-малко важни системи например backup plan-а може да е “машината е в гаранция, ако се счупи нещо, обаждаме се на тия от които сме я взели и така”, или “обаждаме се на другарче”.
[cold spare]
Това вече влиза в категорията на решения, които уважаващ себе си админ би приложил. В реалния свят това е да имате резервна гума, някъде в шкафа резервни електрически крушки, или при системите – една готова цяла машина, която може да замести останалите, дискове или някакви други резервни части, за офис – втора internet връзка през някое 3g, която може да се ползва временно, ако наоколо са прекопали някой кабел.
Това е и едно от най-често срещаните решения, понеже доста лесно се прави. От друга страна може да предизвика прилично количество donwtime, докато се “стопли” резервата.
(някъде тук на лекцията се оказа, че има хора, които не държат резервни крушки у тях…)
[hot spare]
Това е също доста често срещано – имате готов топъл spare, който във всеки един момент е синхронизиран с това, което прикрива и при нужда автоматично може да поеме работата на изгорелия компонент.
Това много често се изполва в setup-и с бази данни или подобни неща, при които чистото дистрибутиране (за което ще говоря по-нататък) не може да стане заради CAP теоремата.
(ще намразите cap теоремата след малко)
Тук има един специфичен момент, т.нар. fencing – ако втората система поема работата на главната, трябва по някакъв начин да се гарантира, че главната е спряла и не прави нищо, за да не се стигне до омазване на shared state или нещо такова. За целта има няколко типа решения, някои от които просто спират тока на главната :)
[CAP теорема]
И така, преди да си говорим за най-хубавия начин – да имате N на брой машини, те да вършат едновременно работа и хем да се scale-вате, хем да сте защитени от сривове, да кажа защо това е непостижима мечта…
Теоремата е съвсем проста и гласи следното: една дистрибутирана система може да има най-много две от следните три свойства: Консистентна, винаги достъпна, издържаща разделение.
Консистентна значи, че във всеки един момент една заявка към нея ще даде същия отговор, без значение към коя част от нея се обръщаме, т.е. ако питаме базата “колко реда има в таблица X”, всичките и сървъри ще кажат същото нещо.
Винаги достъпна значи, че дори да са отпаднали някакви компоненти, тя все пак ще продължи да ни отговаря.
Издръжливостта на разделение значи, че не може да се достигне т.нар. split brain ситуация – ако системата се раздели на две части, не може двете да мажат в/у данните и да се получи при тях различна версия.
Това например значи, че не може по някакъв елементарен начин да си направите master-master репликация на базата данни.
[дистрибутиране]
И да си поговорим за мечтата, всичко да е дистрибутирано. Винаги ми се е искало да мога просто да добавям нов хардуер и нещата да работят и на него. Дори за някои неща това сме го постигали …
Това е постижимо, с някои ограничения. Понеже не ми хрумна по-добър начин, ще ви дам няколко примерни системи, които почти успяват да решат проблема :)
[load ballancers + web]
Това е един доста класически случай за повечето сайтове, на които не им се иска да имат downtime. Слагате отпред два load ballancer-а, които знаят кой от web сървърите отзад работи и балансират м/у тях заявките. Това работи много добре, сравнително стандартизирано е и сглабянето му не отнема особено много време. Достатъчно стандартно е, че amazon да предлагат компонентите му като някакъв service.
При отпадане на компоненти системата го усеща и спира да му подава трафик.
RAID масивите са доста близки като идея до това.
[синхронни бази]
По принцип повечето ACID бази данни използват сихнронна репликация, т.е. всяка заявка за писане се счита за завършена (т.е. се казва на клиента) когато всички компоненти от системата са я потвърдили. Това е почти същото като предния вариант.
[hack-ът за eventual consistency]
И има една добавка, като удобен hack при системи, при които има случаи, в които може да се прочетат стари данни, т.нар. eventual consistency.
В общи линии това представлява система, за която операциите за писане са приключили при запис в X компонента, като обикновено X=N/2 + 1. Тогава имаме inconstent четене, което може да чете от 1 компонент, и ако ни трябва консистентно, четем от N-X+1 компонента. Това се използва основно за системи, при които консистетният read е рядка операция.
[sharding + replication]
Това е текущият метод за репликиране на база данни. В общи линии умножавате факторите за на колко искате да разделите данните (за performance) и за redundancy и получавате колко железа ви трябват (в случая са 2X2).
Това обаче върши работа основно за прости заявки. В момента, в който трябва да съберете данни от две машини, за да направите join или нещо такова, нещата започват да се объркват.
April 7th, 2014 at 03:12
Стига да не обижда религиозни чувства:
REAP Principles (Redundancy, Entanglement, Awareness and Persistence)
http://blogs.technet.com/b/josebda/archive/2013/02/28/increasing-availability-the-reap-principles-redundancy-entanglement-awareness-and-persistence.aspx