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.