208 208.fi

Korkeaa saatavuutta hajauttamalla

Palvelun monistamisen käytännön rajat


Korkea saatavuus on sitä, että palvelu on todennäköisesti saatavilla. Kun palvelu on jaettu usealle toisistaan riippumattomalle laitteelle, yksittäiselle laitteelle jää vähemmän pyyntöjä vastattaviksi. Näin saavutetaan paitsi parempi suorituskyky tai vasteaika myös parempi vikasietoisuus. Jos esimerkiksi yhden nimipalvelimistamme toiminta hidastuisi tai estyisi, palvelu jatkuisi toisen nimipalvelimen ansiosta.

Teoreettisessa tarkastelussa sillä, mistä laitteen toimintahäiriö johtuu, ei oikeastaan ole merkitystä. Ylivoimaisesti todennäköisin nimipalvelintemme häiriö lienee palvelukonttien ja sisällön säännöllinen päivittäminen, joka poistaa käytöstä yhden palvelimen kerrallaan lyhyeksi ajaksi. Koska päivitetyn palvelun toimivuus tarkistetaan ennen seuraavaan siirtymistä, päivitys voi pilata enintään yhden laitteen, joka voidaan tarvittaessa palauttaa päivitystä edeltävään tilanteeseen. Sinä aikana muut palvelimet pitävät palvelun saatavilla. Meillä tämä kaikki tapahtuu automaattisesti GitLab-pohjaisessa toiminnanohjausjärjestelmässämme.

Saatavuuden matematiikkaa

Palvelun saatavuutta voidaan kuvata sillä todennäköisyydellä, että palvelu on mielivaltaisella ajanhetkellä käytettävissä. Jos palvelu on monistettu n laitteelle, jotka vikaantuvat toisistaan riippumatta siten, että jollakin ajanhetkellä laitteen toimimattomuuden todennäköisyys on p, sen todennäköisyys, että palvelu on vikaantunut eli yksikään laite ei vastaa, on pⁿ.

Esimerkiksi saatavuustavoite 99,9999 % eli pⁿ=10⁻⁶ antaa palvelun olla vuorokaudessa (86 400 sekunnissa) saavuttamattomissa enintään 86,4 millisekunnin ajan.

Kahdennetulla järjestelmällä kyseinen saatavuustavoite saavutetaan, kun yksittäisen järjestelmän vikaantumistodennäköisyys on p=10⁻³ eli järjestelmä on enintään 86,4 sekuntia vuorokaudesta poissa käytöstä. Se riittää tavoitteeseen, jos pahin vika on alle minuutin kestävä verkkoyhteyden häiriö tai järjestelmän suunniteltu päivittäminen enintään kerran päivässä.

Kolmen järjestelmän ryppäässä saatavuustavoitteeseen päästään, kun p=10⁻² eli yksittäisen laitteen muista riippumattomat katkokset kestävät enintään 14 minuuttia ja 24 sekuntia vuorokaudessa.

Entäpä suuremmat viat, joiden korjaaminen vie tunteja tai päiviä? Jos oletetaan, että ne ovat niin epätodennäköisiä, ettei niitä voi sattua kuin yksi tai kaksi samanaikaisesti, voidaan yksinkertaisesti lisätä vastaava määrä riippumattomia varalaitteita.

Suuret viat, kuten runkoverkkoyhteyden katkeaminen tai konesalin tulipalo, korjataan ottamalla käyttöön korvaava palvelin toisesta konesalista, mikä vaatii ihmistyötä. Tällaisen vian sattuessa yksittäisen laitteen saatavuus on enintään luokkaa p=10⁻¹ (2,4 tuntia vuorokaudesta poissa) ja saatavuustavoite edellyttäisi oikeastaan vähintään n=6 palvelimen asentamista toisistaan riippumattomiin konesaleihin.

Helppoa hajautusta keskitetysti ohjaamalla

Palvelu on helppo monistaa silloin, kun se perustuu harvoin muutettavaan sisältöön. Esimerkiksi nimipalvelimemme ohjelmisto ja varmenteet päivittyvät muutaman päivän välein. Lisäksi itse sisältöä voidaan muuttaa tarvittaessa, yleensä harvemmin.

Samaan tapaan voidaan monistaa varmenteiden sulkupalvelu tai vaikka staattista sisältöä tarjoava web-palvelin. Mutta entä palvelut, joiden sisältö muuttuu käytön aikana?

Muutosten monistaminen käytön aikana

Sähköpostipalvelussa sisältö (käyttäjien sähköpostilaatikot) muuttuu käytön aikana. SMTP-palvelimet perustuvat kuitenkin viestijonoihin, jotka on periaattessa suunniteltu vikasietoisiksi. Saapuvat viestit voitaisiin monistaa useammalle palvelimelle jo ennen kuin lähettäjän annetaan sulkea SMTP-yhteys. Jokaisella viestillä on yksilöllinen tunniste Message-Id. Tavanomaisesti postilaatikot ovat henkilökohtaisia eikä yksittäistä laatikkoa muokata samanaikaisesti monella eri laitteella. Eri palvelimille monistetut sähköpostilaatikot voisi pitää keskenään ajan tasalla lukkojen ja lokitietueiden avulla, siis toteuttamalla yksinkertaisen hajautetun tietokantajärjestelmän. Hallinta on varsin helppoa, jos yksittäiseen postilaatikkoon sallitaan muutoksia enintään yhdeltä palvelimelta tai päätelaitteelta kerrallaan.

Verkkokauppapaikassa tai varausjärjestelmässä käyttäjät tarkastelevat ja muokkaavat jaettua sisältöä samanaikaisesti. Jos ämpäreitä, harrastevuoroja tai istumapaikkoja on tarjolla rajallinen määrä, käyttäjien kuuluu nähdä kulloinenkin tilanne ja voida varata valintansa, kunnes transaktio mahdollisine maksutapahtumineen on vahvistettu tai peruutettu. Tällaisen sovelluksen aivot on usein tietokantajärjestelmä, joka huolehtii transaktioista ja lukituksesta.

Keskitettyä tietokantaa käyttävän sovelluksen voi muuttaa hajautetuksi vaihtamalla tietokantajärjestelmän hajautetuksi. Hyvin kirjoitetussa sovelluksessa varaudutaan transaktion peruutukseen johtaviin virhetilanteisiin, kuten lukkiumiin tai lukituksen aikakatkaisuun.

Hajautettu monen kirjoittajan järjestelmä

Keskitetty järjestelmä, jossa kaikki muutokset tehdään yhteen pääjärjestelmään, joka monistaa muutokset pelkkiä lukupyyntöjä palveleviin varajärjestelmiin, on vielä kohtalaisen yksinkertainen toteuttaa ja ylläpitää.

Varajärjestelmän automaattinen korottaminen pääjärjestelmäksi ei ole yksinkertaista. Mitä, jos pääjärjestelmä pysyykin osittain saavutettavissa ja osa käyttäjistä jatkaa sen käyttämistä samalla, kun osa käyttäjistä on siirtynyt varajärjestelmästä korotettuun pääjärjestelmään?

Hajautettu järjestelmä ei saa milloinkaan joutua halkaistujen aivojen tilanteeseen, jossa pääpalvelimia onkin useita ja kaikilla käyttäjillä ei olekaan sama tilannekuva. Jos hajautettu tietokantajärjestelmä odottaa jokaiseen toimintoon kuittausta kaikilta palvelimilta, hitaimmat yhteydet määräävät nopeuden. Hyvä suorituskyky edellyttää muutosten puskurointia ja enemmistöpäätöksiä sekä nopeaa reagointia häiriöihin.

Todellinen hajautettu järjestelmä, jossa ryppään palvelimet voivat nopeasti vaihtaa rooliaan, edellyttää hajautettua algoritmia johtajan äänestämiseksi, tehokasta hajautettua lukkojen hallintaa ja toipumismekanismia. Kun entinen johtaja palauttaa yhteytensä ryppääseen ja saa tiedon syrjäytetyksi tullemisestaan, sen on joko peruttava muilta puuttuvat paikalliset muutoksensa tai yritettävä monistaa ne monistettuaan ensin muiden sillä välin tekemät muutokset. Johtajanvaihdoksia voi tapahtua tiheäänkin, ja häiriöitä voi tapahtua kesken äänestyksenkin.

Hajautetussa järjestelmässä asioita voi tapahtua hyvin monessa eri järjestyksessä tai oikeastaan osittaisjärjestyksessä, sillä eri osat, joilla kaikilla on oma kellonsa, voivat havaita tapahtumat eri järjestyksessä. Lisäksi järjestelmän päivitys mutkistuu huomattavasti, sillä päivityksen aikana eri osat väkisin tulevat ajaneeksi eri ohjelmistoversiota.

Luotettavien hajautettujen algoritmien kehittäminen ja toteuttaminen edellyttää formaalien menetelmien käyttämistä, kuten oikeaksi todistamista sekä verifiointia mallintarkastuksen ja saavutettavuusanalyysin avulla. Tilaräjähdyksen hallitsemiseksi on löydettävä sopiva abstraktiotaso. On meillä sitäkin osaamista väitöstutkimuksen verran.

Tällä hetkellä arvioimme GitLab-toiminnanohjausjärjestelmämme ytimessä minkäänlaisen hajautuksen toteuttamisen vaivan siitä saatavaa hyötyä suuremmaksi. Mieluummin teemme hieman enemmän käsityötä järjestelmän mahdollisesti vikaantuessa kuin otamme sen riskin, että erittäin harvoin tarvittu automaattinen varajärjestelmän hallinta pettää jollain tavalla. Häiriön hallinta on helpompaa, kun maailma on pysäytetty. Näkyvä maailma eli tuottamamme palvelut eivät tietenkään pysähdy, sillä ne ajetaan kerroksittaisen tietoturva-arkkitehtuurimme mukaisesti täysin erillisissä ympäristöissä.

Yksittäisen laitteen vikaantumisen ennustamiseksi ja ehkäisemiseksi käytämme automaattista seurantaa, joka tuottaa toimenpide-ehdotuksia.

CC BY 4.0