Ohjelmistoliiketoiminta. Ohjelmistokehitys. Ohjelmistotuotanto. Näissä aiheissa liikkuu Codenton blogi.

Lue Codenton asiantuntijoiden kommentteja ajankohtaisiin aiheisiin.

Kertakäyttökoodista

Kirjoittanut Teemu Kalvas, 8.3.2010 - 10:13

Ohjelmoijien kansanperinteeseen kuuluu erottelu kertakäyttökoodiin ja tuotantokoodiin. Tuotantokoodin erilaisia laatutasojakin nähdään yleensä olevan ainakin muutamia. Haluan kuitenkin tarkastella kertakäyttökoodin käsitettä.

Koska koodi kuitenkin jää olemaan, ja on riski sen uudelleenkäytöstä, pitäisi tunnustaa tosiasiat, eikä elää valheessa. Kaikki koodi pitäisi kirjoittaa vähintään minimaalisella tuotantokoodin tasolla: kehittäjän itsensä pitää ymmärtää se myös puolen vuoden päästä.

Ohjelmoijan tapa käyttää tietokonetta on kuitenkin sellainen, jossa on epäselvää missä vaiheessa siirrytään komentorivien kirjoittamisesta ohjelmointiin. “ls -lt | head” ei varmaankaan vielä ole ohjelmointia. Onko “awk -f ‘{x+=$3} END {print x}’”? Raja on epäselvä.

Ohjelmoinniksi pitäisikin varmaan alkaa kutsua komentorivejä, jotka ovat paisuneet niin hankaliksi, ettei niiden lukeminen enää ole suoraviivaista. Tässä vaiheessa niistä pitäisi tehdä minimissäänkin shelliscripti ja antaa sille kuvaava nimi. Rakenteellisen ohjelmoinnin käytäntöihin siirtyminen ei myöskään ole pahitteeksi.

Kertakäyttökoodia on olemassa vain teoriassa, koska kaikesta koodista jää jäljet. Koodi pitäisi aktiivisesti hävittää saman tien, että se voisi jäädä kertakäyttöiseksi.

Toisaalta komentorivien tallennus on äärimmäisen hyödyllistä minkään järjellisen työtehon säilyttämisen kannalta. Tässä on selvästi ristiriitaiset tavoitteet. Säilyttäminen parantaa työtehoa lyhytaikaisesti, mutta hävittäminen vähentää ylläpitokuormaa pitkällä aikavälillä. Ideaalitilanteessa komentorivikieli olisi itsedokumentoivampi kuin nykyiset melko hirveät kissanoksennukset.

Mobile Dev Camp 2010

Kirjoittanut Markus Holmberg, 5.3.2010 - 15:40

Lauantaina tuli käytyä Mobile Dev Camp -tapahtumassa Helsingissä: luvassa oli eriaiheisia mobiilikehitykseen liittyviä esityksiä ja paneelikeskustelua.

Esitykset olivat keskimäärin kiinnostavia ja liittyivät kattavasti useampiin suosittuihin alustoihin, kuin Nokian Qt, Windows Phone 7 Series ja iPhone -ympäristöt. Windows Phone 7 Seriesin teknisistä yksityiskohdista esittäjä ei tosiaan voinut kertoa paljon, koska virallinen julkaisu on tulossa vasta lähitulevaisuudessa.

Paneelikeskustelut koskivat muun muassa cross platform -kehityksen, eli saman sovelluksen tuominen useammalle alustalle, haasteita. Paneelista löytyi runsaasti kokemusta aiheesta, ja monet näyttivät suunnittelevan tuotteensa usealle alustalle heti alusta. Yleisesti cross platform -kehitys kuulosti olevan kannatava hanke, jonka haasteille löytyy ratkaisuja ja neuvoja muiden kokemuksista.

Toinen paneelikeskustelu koski kysymystä natiivisovellusten olemisesta vastaan websovellukset. Tässä keskustelussa korostui käytettävyys- ja maksukysymykset. Natiivisovelluksilla on paremmat mahdollisuudet sulattua ympäristöönsä ja suorittaa hyvin, sekä hyödyntää myyntiä helpottavia sovelluskauppoja. Websovellusten lyhyempi kehitysaika ja siirrettävyys houkuttaa, mutta vaikeus periä maksuja webissä on edelleen haaste.

Mobile Dev Camp näyttää olevan hyödyllinen tapahtuma kaikille mobiilikehityksestä kiinnostuineille. Palaan mielellä seuraavana vuonna.

EC2-instanssit 30 sekunnissa

Kirjoittanut Santeri Paavolainen, 4.3.2010 - 19:51

Totesin ykskantaan viime joulukuun aamiaistilaisuudessamme, että EC2-instanssin saa provisioitua 30 sekunnissa. Eli sekuntikello naputtaa vain 30 sekuntia siitä, kun lähetän “run instance” pyynnön AWS:ään siihen kun se on provisioitu ja siirtyy “running” tilaan eli virrat ovat päällä ja käyttöjärjestelmä alkaa boottaamaan.

Kiva tulos, mutta jäi kaivelemaan. Kourallisesta mittauksia ei voi tehdä tilastollisesti päteviä johtopäätöksiä.

  • Onko 30 sekuntia yleispätevä, vai oliko se sattuma? Onko oikea keskiarvo isompi vai pienempi?
  • Miten iso on pyyntöjen vaihteluväli? Mitä hyötyä pilvestä on, jos sen saatavuuden latenssista ei voi sanoa mitään luotettavaa?
  • Onko tuloksissa päivittäistä tai viikottaista vaihtelua, tai pitkän aikavälin trendejä?

Joulukuun jälkeen olen tehnyt jonkin verran lisää mittauksia. Aika monta itseasiassa, yhteensä 316 kappaletta. Alla on kaksi kuvaajaa tästä datasta, ensimmäisessä on puhdas provisiointiin mennyt aika, vaaka-akselina on pyynnön aika (päivinä ensimmäisestä), ja toisessa tasoitettu jakauma.

Punainen viiva ensimmäisessä kuvassa on lineaarinen regressio – melkein vaakasuora ja tilastollisesti merkityksetön. Käytettävissä olevalla datalla ei pysty siis päättelemään onko AWS:n EC2-instanssin käyttöönoton nopeus muuttunut käytössä olevan datan 83 päivän aikana.

Toinen kuvaaja onkin mielenkiintoisempi. Silmämääräisesti katsottuna – en ole jaksanut tehdä tilastollista testiä – se näyttää Erlang/Poisson -jakaumalta. Jos näin on, sillä on omat seuraukset palvelun saatavuuden ja nopeuden odotusarvoille.

No, mutta eipä murehdita sitä vaan katsotaan mitä data kertoo. Tässä datajoukossa on siis 316 mittausta, joiden keskiarvo on 31 sekuntia ja odotusarvo 29 sekuntia, vaihteluväli 18-99 sekuntia ja 95% tuloksista on 47 sekuntia tai alle. Ja tuo 99 sekunnin tulos voi olla oma virheeni mittauksissa – outlier se ainakin on.

Eli mainostamani “30 sekuntia” on näiden tulosten mukaan ihan totta.

Älä kuitenkaan ota tätä liian vakavasti – olen testannut vain eu-west-1 regionia ja m1.small -instansseja aina samalla levykuvalla (AMI). Toisilla asetuksilla tulokset saattavat olla ihan jotain muuta.

Mutta minä voi nyt nukkua yöni rauhassa, en ole mennyt puhumaan läpiä päähäni :-)

Tämä kirjoitus on kolmas osa kirjoitussarjassa – aiemmat osat: yksi ja kaksi.

Tästä lähtien ei enää sanaakaan komponenttien tehostamisesta eikä vertikaalisesta skaalautumisesta. Jatkossa kaikki mitä tehdään, liittyy joko uusien skaalautuvien rakenteiden, komponenttien tai käytettävien koneiden määrän kasvattamiseen.

ABC

Edellisessä osassa annoin jo viitteitä siitä, että monet skaalautuvuutta ja sitä kautta suorituskykyä parantavat toimenpiteet eivät ole yhtä haastavia. Jatkossa jaan nämä keinotekoisesti ja varsin hatusta vedettynä  kolmeen eri luokkaan eli A-, B- ja C-luokkiin pohjautuen niihin kuuluvien ratkaisujen haastavuuteen ja arkkitehtuurillisiin vaikutuksiin. Skaalautuvuutta kasvattaessa on järkevää aloittaa helpommista toimenpiteistä ja edetä haastavampiin vasta tarpeiden kasvaessa – tästä siis nyrkkisäännöksi, että ensin A, sitten B ja vasta lopulta C.

Huomaa tosin, ettei osajärjestelmistä ja komponenteista koostuvassa kokonaisuudessa ole välttämätöntä skaalata kaikkia osia samaan tahtiin. Tarve ratkaisee.

  • A-luokka lähtee liikkeelle järjestelmän roolien jakamisesta eri koneisiin – tämä sisältää myös kokonaan uusia komponentteja – mutta ei vielä yksittäisten komponenttien monistamista. Eli mikään yksittäinen järjestelmän osa ei vielä skaalaudu, vaikka järjestelmä jo kokonaisuutena alkaa skaalautumaan. A-luokan toimenpiteisiin kuuluu esimerkiksi tietokantojen siirto omiin koneisiin, esitys- ja taustakerrosten erottaminen, käyttäjä- ja datajoukkojen triviaali segmentointi sekä monta muuta.
  • B-luokka sisältää ne toimenpiteet joissa järjestelmää skaalataan lisäämällä koneita. Tämä toimenpiteiden joukko on laaja alkaen komponenttien sisäänrakennettujen skaalautumisominaisuuksien hyödyntämisestä (esimerkiksi tietokantojen klusterointi) päätyen aina järjestelmän arkkitehtuurin läpikotaiseen uusimiseen. Kuitenkin kaikki B-luokan toimenpiteet seuraavat vakiintuneita käytäntöjä ja kaavoja (“scalability patterns”, sekä sisältävät todellista komponenttitason skaalautumista.
  • C-luokassa siirrytään olemassaolevien kaavojen ja komponenttien ulkopuolelle. Käytännössä tällä alueella on kaikki mikä edellyttää kokonaan uusien osajärjestelmien toteuttamista alusta asti  ja siihen liittyvää (tieteellistäkin) tutkimustyötä. Esimerkkejä yrityksistä ja palveluista jotka ovat tällä alueella ovat Google, Amazon, Yahoo, Twitter ja Facebook. Monet näiden yritysten kehittämät järjestelmät ja käytännöt ovat siirtyneet joko sellaisenaan käyttöön muualle tai ainakin toimineet malleina myöhemmälle kehitykselle.

Tässä kirjoituksessa aloitan A-luokan toimenpiteillä. B- ja C-luokkiin pääsemme myöhemmin.

Lähden liikkeelle LöydäSukkasi.com-palvelun kanssa tilanteesta, jossa järjestelmän tehostustoimenpiteet on tehty ja vanha nuhapumppukone on vaihdettu moderniin (katso edellinen osa). Järjestelmän suorituskyky yhdellä koneella on nyt 100 000 sukkaparia. Järjestelmä koostuu tällä hetkellä seuraavista selkeästi erotettavista osista:

  • Webipalvelimesta, joka tarjoaa käyttäjille mahdollisuuden seurata sukkiensa tilannetta, lisätä uusia ja niin edelleen. Palvelun käyttö edellyttää sisäänkirjautumista.
  • Sukkien sijaintikannan päivittäjästä, joka vastaanottaa tilapäivityksiä RFID-lukijoilta  ja vie ne kantaan. Oletamme RFID-lukijoiden olevan varsin älykkäitä ja verkotettuja, ja ne lähettävät itsenäisesti tiedot luetuista RFID-tunnisteista seurantajärjestelmälle.
  • Tietokannasta jonne on talletettu käyttäjätiedot, tiedot sukista ja sukkien sijaintitiedot.

Tietokannan erottelu

Tämä kaikki toimii aluksi yhdessä tietokoneessa. Aivan ensimmäinen tehtävä asia on siirtää tietokanta omaan koneeseensa (kuvissa uudet tai merkittävästi muuttuneet osat on merkitty magentalla, lisäksi nuolet esittävät kontrollin eivätkä datan siirtymistä – palvelin ottaa yhteyden tietokantaan eikä toisinpäin):

Tietokanta erotettuna muusta palvelusta omalle koneelleen. Katkoviiva esittää "verkon reunaa" eli kuvaan on tuotu "sisäisen verkon" käsite.

Roolien lisäerottaminen

Jatko riippuu paljon siitä, miten ja millaisin rajapinnoin järjestelmän eri osat on toteutettu. Esimerkissämme RFID-päivityksiä vastaanottava osa kirjoittaa päivitykset tietokantaan eikä sillä ole suoria riippuvuuksia web-käyttöliittymään. Toiminnallisuuden jako vastaa tässä hyvin ajatusta kerrostuneista verkkopalveluista joissa on loogisesti vähintään kolme kerrosta:

  • Front-end eli FE, joka hoitaa liittymät ulkopuolisiin järjestelmiin kuten käyttäjille.
  • Back-end eli BE, joka toteuttaa “bisneslogiikan” mutta ei keskustele suoraan käyttäjien kanssa. Laajemmasti voidaan tulkita, ettei back-endin tulisi keskustella minkään ulkopuolisen järjestelmän kanssa, mutta rajanveto on tällöin helpompaa. Helpointa on sanoa, ettei back-end keskustele suoraan käyttäjien kanssa ja tulkita muut ulkopuoliset yhteydet tapauskohtaisesti.
  • Tietokanta tai muu tietovarasto joka voi olla myös levyjärjestelmä.

Tästä huomaamme, että RFID-päivitysten käsittelijä on erillinen webiliittymästä ja voimme sijoittaa sen erilliseen tietokoneeseen:

RFID-tilapäivitysten ja käyttäjien palvelu erotetaan eri koneille.

Nyt käytössä on kolme konetta. Pikaisesti voisi kuvitella tästä saavutettavan suoraan 3× suorituskyvyn kasvun, mutta todellisuudessa siitä saa helposti enemmän, eli suorituskyvyn. Tähän on kaksi syytä:

  • Eri palvelut eivät joudu jakamaan toisten kanssa samoja resursseja. Tämä parantaa prosessorin, L1/L2-cachen, levyn ja muistin käyttöä.
  • Eri komponenttien koneiden investoinnit voidaan suhteuttaa niiden kuormituksen mukaan, jolloin järjestelmä on myös paremmin tasapainossa eli kaikki osat ovat suhteellisesti yhtä kuormitettuja suhteessa käytössä oleviin resursseihin. Jos tietokanta kantaa 50% kuormasta, FE 35% ja BE 15%, lienee selkeää että tietokantakoneeseen kannattaa laittaa enemmän rahaa.

Staattinen data

Voimme myös lisätä järjestelmään joitain uusia komponentteja. LöydäSukkasi.com -palvelussa on jokaisesta sukasta kuva (miten muuten erottaisit nalle- ja prinsessasukat toisistaan?) joita esitellään palvelussa monissa paikoissa. Nämä kuvat ovat varsin isoja ja niitä on paljon, josta aiheutuu kaksi ongelmaa: 1) niiden näyttäminen käyttäjälle kuormittaa webipalvelinta ja 2) koko sivun lataus hidastuu, koska kaikki kuvat tulevat samasta osoitteesta.

Tarvitaan vähän tarkempaa järjestelmän tuijotusta jotta pystymme näkemään tämän eron, eli on olemassa erityyppistä dataa, joita käyttävät palvelun eri roolit. Tällä hetkellä FE hoitaa siis kaksi eri roolia yhdessä komponentissa ja koneessa – voimme siirtää toisen roolin (eli staattisen datan palvelemisen) toiseen komponenttiin ja saman tien tuon komponentin toiseen koneeseen.

Sekä tietokannasta tulevien sukkakuvien että muun staattisen datan välittäminen siirretään omalle palvelimelleen.

Oletan tässä, että kuvat on tallennettu tietokantaan eli tietorakenne on täysin normalisoitu. Denormalisointi – kuten kuvien siirto levylle – on B-luokan toimenpiteitä joten siitä ei tässä. Toinen tarpeellinen huomautus on, että selainten rinnakkaisten yhteyksien rajoituksia voidaan helposti kiertää CNAME-aliaksien käytöllä – mutta kirjoitan koetun suorituskyvyn parantamisesta myöhemmin,  joten ei siitä tässä tämän enempää.

Välimuistit

Webipalveluissa tehdään monesti toistuvia tietokantakyseljä. Joukossa on tavallisesti paljon kyselyitä joiden tulokset eivät muutu kovinkaan usein. Lisäksi palveluissa on monenlaista tilatietoa jonka häviäminen ei ole maailmaloppu, joten niitä oikeasti tarvitse tallettaa tietokantaan, kunhan ne eivät katoa ihan seuraavalla sekunnillakaan. Näihin molempiin käytetään cache- eli välimuistiratkaisuja.

Välimuistiratkaisuja voidaan käyttää sekä komponentin tehostamiseen (no, tulihan se sana sittenkin esille) jolloin se on A-luokan toimenpide, tai mahdollistamassa skaalautuvan järjestelmän toteutusta jolloin se kuuluu B-luokkaan. Nyt käsiteltävässä tapauksessa puhun nimenomaan ensimmäisestä käyttötarpeesta, eli cachea käytetään komponentin suorituskyvyn nostamiseen, eikä yksittäistä cachea siis jaeta muiden komponenttien kanssa. (Oleellinen ero on “local cache” vs. “shared” tai “distributed cache.”)

Voimme ottaa välimuistin käyttöön kolmessa paikassa:

  • Webikäyttäjien istuntotietoja ei talleteta tietokantaan. (Mikään pakkauksesta otettu web-palvelun kehitysympäristö ei oletuksena talleta istuntotietoja tietokantaan, joten tämä ongelma tulee harvoin vastaan. Varoituksena kuitenkin, ettei istuntotietoja pitäisi tallettaa tietokantaan ilman todella hyviä perusteluita.)
  • Käyttäjäpalvelun tekemiä tietokantakyselyjä voidaan cacheta. Yleensä löytyy monia vähemmän aikakriittisiä asioita joita haetaan jatkuvasti. Nämä ovat helposti laitettavissa välimuistiin.
  • Koska oletimme normalisoidun skeeman jossa myös sukkien kuvat ovat kannassa, voimme vähentää tietokantakyselyjä tallentamalla tietokannasta haetut kuvat välimuistiin staattisen datan palvelimessa.

Cache eli välimuisti on lisätty istuntotietojen, tietokantakyselyjen ja kuvien tilapäiseen tallentamiseen. Yhtenäinen viiva kuvaa yhden tietokoneen sisäisiä komponentteja. (Otso Kivekäs ehdotti juustoa kuvaamaan välimuistia - "cache" on myös eläinten ruokapiilo.)

Välimuisturatkaisuja on monia. Kaikissa webiohjelmointiin käytetyistä kielistä löytyy valmiit kirjastot ainakin paikallisen välimuistin käyttöön. Paikallinen välimuisti voi olla levy- tai muistipohjainen. Myöhemmin B-luokan toimenpiteissä keskustelemme lisää jaetuista sekä hajautetuista välimuisteista. Tämän hetken tarkasteluun liittyen riittää, että LöydäSukkasi.com-palvelun eri komponentit käyttävät paikallista tiedostopohjaista välimuistia.

Viestijonot

Viimeisenä – jo vähän B-luokkaa liippaavasti – huomaamme että RFID-käsittelijä toteuttaa itseasiassa kahta eri tehtävää: se sekä vastaanottaa päivitykset että käsittelee ne.

Erotamme päivitysten vastaanoton ja niiden käsittelyn laittamalla näiden väliin jonotusmekanismin. Tällöin RFID-muutosten vastaanottajan tehtävä on suoraviivainen: hyväksy yhteys, lue päivitystiedot, laita tiedot jonoon, kuittaa päivitys vastaanotetuksi ja sulje yhteys. RFID-viestien dekoodaus ja tietokannan päivitys tapahtuu eri komponentissa, joka purkaa viestijonoa ja käsittelee viestejä muuten samalla tavalla kuin ennenkin – vastaanottomekanismi on vain vaihtunut.

Lisäämällä jono RFID-päivitysten vastaanoton ja käsittelyn väliin saadaan viestin vastaanotto riippumattomaksi tietokannan nopeudesta.

Jonotusjärjestelmissä on paljon vaihtoehtoja. Yksinkertainen tapa on tehdä ad hoc jono laittamalla tiedot joko levylle tai tietokantaan. En kuitenkaan suosittele renkaan uudelleen keksimistä, vaan kannattaa ennemmin käyttää olemassaolevia jonotusjärjestelmätoteutuksia (“message queue”.)

Mitä tämä hyödyttää? Aiempi RFID-päivitysten synkroninen käsittely on muutettu asynkroniseksi. Aiemmassa synkronisessa käsittelyssä oli tilanteita, jossa tuotaessa laitospesulaan kärrykaupalla sukkia lukijan päivitysten käsittely kesti kauemmin kuin mikä oli suurin sallittu viive. Tällöin hukattiin sukkien sijaintipäivityksiä. Irrottamalla viestin nopea vastaanotto ja hitaampi käsittely toisistaan voidaan tämä tilanne välttää.

Suorituskyvyn arviointi

Millainen järjestelmä meillä nyt sitten on?

Ensinnäkin, järjestelmän suorituskykyä ei pysty mittaamaan enää yhdellä luvulla. Olen vähän huijannut viittaamalla sukkien määrään. Todellisuudessa emme niinkään voi puhua palvelun suorituskyvystä, vaan erilaisista suorituskykyarvoista jotka riippuvat siitä, miten sitä kuormitetaan.

Seuraavassa lasken muutamia suorituskykyarvoja sukkapalvelulle. Aivan ensimmäiseksi joudun kuitenkin määrittelemään kuormitusprofiilin joihin laskelmat perustan.

Ensin oletukset:

  • Yhdellä “taloudella” (oli se sairaala, sinkkutalous tai jotain siltä väliltä) on keskimäärin 100 seurattavaa sukkaparia.
  • Kullakin “taloudella” on yksi käyttäjä ja käyttäjätunnus.
  • Kukin talous käy kerran viikossa etsimässä kadonneita sukkiaan.
  • 10% koko sukkapareista käytetään päivittäin, eli niiden sijainti muuttuu tavalla joka aiheuttaa keskimäärin yhden RFID-tapahtuman.
  • Keskivertokäynti palvelussa aiheuttaa 100 sivulatausta ja 1000 sukkakuvan latausta.
  • Yksi kuva sukkaparista on 100 kilotavua.

Näiden oletusten pohjalta voimme laskea järjestelmän muut ominaisarvot vaikkapa 5 miljoonan sukkaparin tapaukselle:

  • Järjestelmässä on 50000 taloutta.
  • Sukista tulee 1 miljoonaa sijaintipäivitystä päivässä, eli keskimäärin 12 päivitystä sekunnissa.
  • Keskivertopäivänä verkkopalvelussa käy 7200 käyttäjää, joista tulee 8 sivulatausta sekunnissa ja 80 kuvalatausta sekunnissa.
  • Kuvalataukset vievät keskimäärin 8 megatavua verkkokaistaa sekunnissa pahimmassa tapauksessa, luottaen selaimen cacheukseen vain 0,8 Mt/s – todellisuudessa siltä väliltä.
  • Kirjautumisia palveluun tapahtuu 0,08 sekunnissa eli 5 kappaletta minuutissa.
  • Tietokannassa on 500 gigatavua kuvia sukista.

Huomaa, että “keskivertopäivä” tässä olettaa 24×7 -mallin, eli käyttö jakaantuu tasan jokaisen viikon päivän ja jokaisen päivän tunnin yli. Realistisempi malli olisi 12×5 eli kuorma jakaantuu viiden päivän yli (arkipäivät) joina kunakin 12 tunnin yli. Tämä tarkoittaisi 3× lisäystä yllä oleviin kuormalukuihin. Lisäksi todellisissa kuormahuipuissa voi olla aivan eri luvut – tosin eri asiakassegmenttien kuormahuiput voivat osua eri aikoihin. Teollisuuspesulassa tehtäneen töitä päivällä, kun taas (monissa) yksityistalouksissa pyykätään vasta töistä tultua.

Näillä oletuksilla kokemuksesta sanoa, että yllä oleva palvelu on enimmäkseen mahdollinen (“feasible”) annetuin oletuksin, mutta varsinkin jos huomioimme kuormahuiput olemme tuskallisen lähellä tai jo ylittäneet A-luokan operaatioiden tuoman suorituskyvyn ylärajan. Todellisuudessa järjestelmää pitäisi suorituskykytestata, mutta puhtaasti teoreettisena harjoituksena suosittelisin yllä olevalle palvelulle siirtymistä B-luokan skaalautumistoimenpiteisiin. (Tai vähentää tavoitettaan alle 1 miljoonan sukkaparin.)

Tietokannasta vielä: 10 miljoona riviä (eli sukkaa) ei ole rivimääränä merkittävä. Sensijaan puolta teratavua kuvadataa ei ole järkevää laittaa tietokantaan, koska se hidastaa merkittävästi vikatilanteista palautumista. Yksinkertainen denormalisointi eli kuvien siirto muualle kuin päätietokantaan on yksinkertaisin ratkaisu, mutta kuten aiemmin sanoin, se kuuluu B-luokan toimenpiteisiin joista lisää myöhemmin.

Lopuksi: Yllä olen kuvannut monia toimenpiteitä jotka olen listannut “A-luokkaan” kuuluviksi. Vaikka listasin ne eräänlaisessa loogisessa järjestyksessä, tulee jokaisen järjestelmäarkkitehdin itse arvioida aina eri menetelmien soveltuvuus ja järkevä vaiheistus juuri työn alla olevaan projektiin.

Sitten vielä vähän linkkejä:

Aikaisemmassa kirjoituksessa käsiteltiin tiedostojen synkronisointipalveluja hajautettujen järjestelmien näkökulmasta. Palveluita luokiteltiin CAP-käsitteen mukaan riippuen missä yhdistelmissä eri hajautettujen järjestelmien ominaisuuksia tuettiin.

Yksi kiinnostavimmista luokista on AP-palvelut, jotka uhraavat jatkuvan yhtäpitäväisyyden (C = engl. consistency) saavuttaakseen muita haluttuja ominaisuuksia (A = engl. availability, P = engl. partition-tolerance). Tähän luokkaan kuuluvat muuan muassa niin kutsutut “lopuksi yhtäpitävät” (engl. eventually consistent) palvelut. Lopuksi yhtäpitävä tarkoittaa tiedostojen synkronisointijärjestelmässä, että vaikka kahden tietokoneen tiedostot hetkellisesti voivat haarautua eri versioihin, erot ennen pitkää kuitenkin ratkaistaan järjestelmällisesti ja yhtenäistetään yhteen sovittuun versioon.

Kiinnostavaa näissä lopuksi yhtäpitävissä järjestelmissä on, mitä algoritmia käytetään erojen ratkaisemiseen. Hankalimmillekin tapauksille, kun esimerkiksi samaa tiedostoa on yhtäaikaisesti muokattu eri tavalla kahdella eri tietokoneella, pitäisi löytää tapa yhdistää haarautuneet versiot. Esimerkkejä lähestymistavoista ovat:

  • Jompikumpi versioista heitetään pois, esimerkiksi vanhempi
  • Molemmat säilytetään, mutta esim. vanhempi uudella nimellä
  • Kysytään käyttäjältä tapauskohtaisesti

Esimerkiksi Dropbox on valinnut ratkaisun jossa vanhempi versio tallennetaan järjestelmään kopiona nimellä, joka viittaa siihen että se on haarautunut versio. Applen iDisk toisaaltaan (tapauksessa jossa ollaan valittu nk. offline synchronization) kysyy käyttäjältä kumpi versio tulee säilyttää kun tiedosto on haarautunut.

Kun tiedostojen synkronisointipalvelujen käyttö yleistyy yhä enemmän, on hyvä ymmärtää niiden ominaisuudet. Mukaan lukien mitä tapahtuu tiedostoille kun haarautuneet versiot tiedostoista yhtenäistetään.

Codento on tänään torstaina virallisesti Amazon Web Services Solution Provider. Itseasiassa olemme ensimmäinen joka on suomessa tämän statuksen saanut. (Tässä kohtaa taputtelemme toisiamme iloisesti olalle.)

Mitä tämä käytännössä tarkoittaa Codentolle ja asiakkaillemme?

Asiakkaillemme tarjoamme myös tänään sitä samaa korkeatasoista arkkitehtuuriosaamista kuin eilenkin. Nyt siitä on vain yksi todiste lisää. Olemme jo pitkän aikaa nähneet pilviratkaisujen liiketaloudelliset ja teknologiahyödyt ja johdonmukaisesti tuoneet tasapuolisesti pilviteknologiat esille yhtenä mahdollisena osana erilaisten palvelujen ja ratkaisujen rakentamisessa.

Codentolle Solution Provider -statuksen saaminen on tietysti merkittävä etappi. Nyt voimme sanoa, etteivät puheemme omasta pilviosaamisestamme ole suinkaan tuulesta temmattuja.

Hyvä tiimi

Kirjoittanut Otso Kivekäs, 17.2.2010 - 09:51 - 4 vastausta

Kukapa ei haluaisi ohjelmistoprojektiinsa hyvää tiimiä. Mutta mistä sellaisen saa? Ja mikä erottaa hyvän tiimin keskinkertaisesta? katsotaanpa kahta selitystä, konventionaalista ja vähän yllättävämpää.

Selitys yksi: Hyvä tiimi koostuu hyvistä tyypeistä.

Kooderien tuottavuuserot ovat valtavia. Hyvä kooderi käyttää tehtävään viidesosan siitä ajasta joka keskiverrolta kuluu, ja lopputulos on silti monin tavoin parempi. Sama pätee moniin muihinkin ohjelmistotuotannon osiin: arkkitehtuurisuunnitteluun, käyttökokemussuunnitteluun ja myös laadunvarmistukseen. Tämä erottaa kaikki nämä ammatit vaikkapa heinänteosta tai T-fordien kokoamisesta liukuhihnalla.

Jos pääsee valitsemaan tiimiinsä parhaita mahdollisia ammattilaisia joka hommaan, saanee kasaan ainakin melko hyvän tiimin. Tämä on pelkkää tervettä järkeä. Mutta ei aina riitä. Eikä siihen aina ole mahdollisuutta.

Selitys kaksi: entä… jos sen voi luoda?

Ihan yksilöiden taitotasosta riippumatta, hyvän tiimin pitää toimia yhteen. Se myös tarvitsee kelvolliset tilat ja hyvät työkalut. Joel Spolsky tiivistää tarvittavat työkalut ja työolot 12 kohdan listaansa. Ainakin tämän verran ympäristöllä on väliä.

Parikin astetta pidemmälle ajatuksen vie Alan G. Carter luentosarjassaan Programmers’ stone. Jos lukee hyväntahtoisesti ja ohittaa omituisimmat kohdat, Carterin perusidea on, että hyvän tiimin erottaa huonosta se, että jäsenet löytävät oikeanlaisen keskittymisen ja yhteisymmärryksen, ja sitä kautta itse asiassa ymmärtävät mitä ovat tekemässä tavalla, joka on sitä kokemattomalle lähes käsittämätön.

Tälläisen “Kullatun tiimin” [sic] luomiseen tarvitaan tietysti Joelinkin käsittelemät järkevät tavoitteet, hyvät työkalut, rauhalliset työtilat, tiimin pysyvyys, jne, mutta ennen kaikkea mahdollisuus ylläpitää riittävän matalaa stressitasoa.

Carterin mukaan lähes kuka tahansa ohjelmoija voisi olla kymmenen kertaa normaalia tuottavampi, mutta tätä harvoin tapahtuu, koska normaalissa softafirmassa ei ole yksinkertaisesti mahdollista ylläpitää matalaa stressitasoa. Ainakaan kokonaisen tiimin. Lukekaa koko tarina jos haluatte kattavan selityksen.

Carter sortuu värillä hörhöilyn puolelle, ja vetää neurologian tuloksista melko suoraaviivaisia sosiaalisia johtopäätöksiä, mutta perusideassa on järkeä. Kaikista tuskin voi ikinä tulla super-ohjelmoijia, mutta hyvä ohjelmointikyky ei ole geneettinen ominaisuus, vaan jotakin, mitä voi oppia. Ei helposti, vaan vaikeasti. Eikä vain yksikseen, vaan helpommin oikeassa seurassa.

ps. Sen hyvän tiimin saa tietysti Codentolta :)

Tämä kirjoitus on toinen osa kirjoitussarjassa – aiemmin on ilmestynyt ensimmäisen osa.

Suorituskyvyn rajojen tunteminen on tärkeää suorituskyvyn kasvattamiseksi kustannustehokkaasti. Järjetelmien pullonkauloihin on ratkaisuja,  jotka lisäävät suorituskykyä ja/tai skaalautuvuutta monin eri tavoin.

Suorituskyky

Ensimmäinen pohtimisen aihe on siis järjestelmän suorituskyky sellaisena kuin se on nyt – joko tuotannossa tai kehityksen alla.

Onko järjestelmän suorituskyky hyväksyttävä suhteutettuna käytössä oleviin resursseihin? Tässä arvioinnissa suorituskykytestien tulokset ovat kullan arvoisia. Jos järjestelmä on vielä kehityksen alla eikä sitä voi testata kokonaisuutena, on tyydyttävä osajärjestelmien testeihin ja paikattava puutteet analyyttisillä malleilla.

Tässä pohdinnossa järjestelmän skaalautuminen ei vielä ole tärkeää. Skaalautuminen ei voi parantaa järjestelmän resurssien käytön tehokkuutta. Jos järjestelmä on tehoton, sitä pitää tehostaa ennen kuin suorituskykyä ryhdytään kasvattamaan skaalautumalla. Tehoton järjestelmä monistettuna tarkoittaa vain moninkertaisesti tehotonta järjestelmää.

Tämä voi tuntua itsestäänselvältä asialta, mutta se ei ole. Ensinnäkin monet tuotekehitysorganisaatiot ovat sokeita omien tuotoksiensa puutteille. Toiseksi, kaikilla ei ole eikä voi olla kokemusta vastaavista järjestelmistä jotta he pystyisivät arvioimaan sitä, onko järjestelmän koettu hitaus tehottomuutta vai vain ratkaistavan ongelman rajoite. Lyhyidenkin videoiden formaattikonversiot (think youtube) voivat kestää tehokkaallakin koneella kymmeniä sekunteja tai minuutteja – koettu hitaus liittyy fyysisiin eli käytettävissä olevien laitteiden nopeuteen, ei itse järjestelmän arkkitehtuurilliseen tai algoritmiseen hitauteen. Sensijaan minkä tahansa verkkopalvelun webipalvelimien (front-end) tulisi pystyä vastaamaan kymmeniä tai satoja dynaamisia sivupyyntöjä sekunnissa.

Jos siis järjestelmä on nykyisellään tehoton, ensimmäinen askel ei ole (horisontaalisen tai vertikaalisen) skaalautumisen miettiminen vaan olemassaolevan toteutuksen tehostaminen.

Aiempi esimerkkimme eli LöydäSukkasi.com-palvelu pystyi seuraamaan reaaliajassa 100 sukkaparia. Miten tahansa 100 sukkaparia käänteleekin, niin se on tehoton. Tällä suorituskyvyllä 100 miljardin sukkaparin seuraamiseen tarvitsisi miljardi palvelinta. Ensimmäinen tehtävä esimerkissämme on siis tehostaa toteutusta ennen muita toimenpiteitä.

Ainoa poikkeus jossa tehostamista voidaan lykätä on jos se on kriittistä liiketoiminnan jatkuvuuden kannalta – siis jos uhkana on kriittisen asiakkaan menettäminen ja yrityksen luhistuminen sen takia. Tällöin voidaan koneen tehostamista (vertikaalinen skaalautuminen) tai palvelun monistamista asiakaskohtaisesti (horisontaalinen skaalautuminen) käyttää tilapäisratkaisuna. Tehostaminen on kuitenkin väistämässä edessä tai kyseisellä palvelulla ei tule olemaan taloudellisia mahdollisuuksia kasvaa.

Skaalautuminen

Jos järjestelmä on jo tarpeeksi tehokas on aika miettiä seuraavia askeleita. Näitä ovat vertikaalinen ja horisontaalinen skaalautuminen (näiden määritelmät löydät edellisestä kirjoituksesta.)

Vertikaalisella skaalautumisella voidaan saavuttaa 10-30 kertainen suorituskyvyn kasvu tietyin edellytyksin (tai enemmän, jos on todella syvät taskut).

Horisontaalinen skaalautuminen tarjoaa potentiaalisesti rajattoman suorituskyvyn kasvun. Valmiiden suunnittelukaavojen ja -käytäntöjen (“design patterns”, “scalability patterns”) rajat tulevat jossain vaiheessa vastaan, jonka jälkeen skaalautuminen on edelleen mahdollista mutta vaatii jo toisenlaisia panostuksia.

Skaalautumisen toimenpiteet vaihtelevat vaativuutensa ja tuloksiensa puolesta valtavasti. Käytännössä on syytä aloittaa helpoilla toimenpiteillä ja siirtyä vasta suorituskyvyn tarpeen kasvaessa kohti haastavampia.

Suorituskyvyn ja skaalautumisen portaikko

Aiempia sekä osittain vasta tulevissa kirjoituksissa käsittelemiäni käsitteitä ja toimenpiteitä käyttämällä saadaan seuraava karkea suorituskyvyn ja skaalautumisen portaikko:

  1. Tehottoman järjestelmän tehostamisella saavutetaan 10-1000× suorituskyvyn kasvu. (“Riittävän” tehokasta järjestelmää voidaan monesti tehostaa 2-10×, mutta tällöin kustannukset kasvavat nopeasti suhteessa saavutettuun hyötyyn.)
  2. Vertikaalisella skaalautumisella eli vaihtamalla kone tehokkaampaan voidaan päästä 10-30× suorituskyvyn kasvuun. Älä aliarvioi teknisen kehityksen nopeutta – tuotekehitykseen vuosi sitten hankittu kone on merkittävästi hitaampi kuin tänä päivänä vastaava.
  3. A-luokan toimenpiteillä saadaan 5-20× lisää suorituskykyä.
  4. B-taso on lavea ja kattaa kaikenlaisia toimenpiteitä 10× ja 10 000× välillä.
  5. C-tasolla on sitten rajana taivas, eli ×.

Kustannukset jakaantuvat siten, että 1. on puhtaasti tuotekehityksen työtä, 2. puhtaasti tuotantokustannus (“deployment”, “operations”), 3. ja 4. sekä tuotekehityksen että tuotannon kustannuksia. 5. tuo vielä mukaan puhtaan tutkimuksen kustannukset.

Mitä tämä käytännössä tarkoittaa?

  1. LöydäSukkasi.com tehostaa yhden koneen järjestelmäänsä järjellisellä työllä 100-kertaiseksi (10 000 sukkapariin). Tämä tehdään lisäämällä indeksejä tietokantatauluhuin, poistamalla debuggauksen yhteydessä koodiin jääneitä tarpeettomia O(N²) varmistuksia sekä säätämällä tietokannan ja webipalvelimen parametreja kuten muistivarausta ja palveluprosessien määrää.
  2. Siirtämällä vielä palvelun tehokkaampaan – mutta ei vielä järjettömän kalliiseen – koneeseen saadaan vielä 10× suorituskyvyn kasvu.
  3. Tekemällä horisontaalisen skaalautumisen aivan perusaskeleet eli A-tason toimenpiteitä saadaan vielä 10× suorituskyky. (Näistä toimenpiteistä lisää seuraavassa osassa.)

Eli olisimme melko pienillä ja hyvin suoraviivaisilla toimilla jo 1 miljoonan sukkaparin käsittelevässä järjestelmässä. Näillä askeleilla LöydäSukkasi.com pystyisi palvelemaan kahta tuhatta Keski-Suomenlahden Aluemerisairaalan kokoista asiakasta.

Jos palvelusi olisi yhtä patologinen kuin LöydäSukkasi.com, voisit nopeilla tehostamisen ja yksinkertaisilla skaalautuvuuden toimenpiteillä siirtyä 500 päivittäisestä käyttäjästä aina puoleen miljoonaan käyttäjään. Puoli miljoonaa on maailmanlaajuisesti ajateltuna vähän käyttäjiä, mutta alueelliselle palvelulle se on monesti jo aivan riittävä määrä. Ja vaikka palvelulla on globaaleja ambitioita, niin puolikas miljoona on vähintäänkin hyväksyttävä ensiaskel, erityisesti jos vaihtoehdona on odottaa puoli vuotta lisää 5 miljoonan käyttäjän palvelua?

Seuraavassa osassa päästään jo itse skaalautumiseen ja lopetetaan tehostamisesta puhuminen.

Linkkejä:

Mainitsin jo aiemmin Nicklas Anderssonin kanssa käymästäni keskustelusta parisen viikkoa sitten pidetyn It-viikon tilaisuuden yhteydessä. Siitä sain kipinän pohtia syvällisemmin mitä a) skaalautuvuus on ja b) kuinka paljon sitä oikeasti tarvitaan.

Tarvitaanko skaalautumista? Monet asiakkaistamme pitävät sitä – ainakin aluksi – kriittisenä vaatimuksena palveluilleen. Kuitenkaan puhdas skaalautuminen ei monesti silti ole lopullisissa järjestelmän vaatimuksissa. Miksi? Yksi syy voi olla, että sana “skaalautuvuus” on vain yksi buzzword vaatimusbingossa, samalla tavalla kuin “käytettävyys,” eli sanana sitä käytetään tarkoittamaan niitä tarpeita ja tavoitteita jotka sillä hetkellä ovat tuntemattomia (mutta liittyvät jotenkin “käyttäjämääriin.”)

Toisaalta luulen “skaalautuvuuden” olevan myös pelottava peikko, mörkö jota pelätään osittain koska se on vähän vieras ja siitä puhutaan paljon IT-medioissa. Jos emme skaalaudu, olemme k****ssa! Kuitenkaan skaalautuminen keskivertopalvelussa tai -järjestelmässä ei ole ongelma. Suurillekin käyttäjämäärille voidaan muutamia peruskaavoja (“design patterns” tai “scalability patterns”) soveltamalla tehdä hyvin suoraviivainen toteutus.

Tässä Skaalautuvuuden ABC -sarjassa yritän selventää sitä, mitä skaalautuvuudella tarkoitetaan sekä sitä, miksei sitä ole syytä pelätä. Kirjoitan suomeksi, koska vaikka materiaalia on runsaasti englanniksi, ei sitä löydy juurikaan suomeksi. Itse olen löytänyt suomeksi lähinnä joko korkeakoulujen kurssimateriaalia tai yritysten omaa skaalautuvuuskonsultointipuffausta. (Kyllä, nämä kirjoituksetkin ovat Codenton osaamisen korostamista.)

Se taustasta, nyt itse asiaan.

Puhekielessä “skaalautuvuudella” tarkoitetaan monia asioita. Yksi on liiketoiminnan skaalautuvuus, eli sitä miten bisnestä voidaan kasvattaa ja moninkertaistaa. Franchising on yksi malli skaalautuvasta liiketoimintamallista. Monesti liiketoiminnan ja IT-järjestelmien skaalautuvuudella ei kuitenkaan ole mitään tekemistä keskenään, joten on virhe olettaa skaalautuvan liiketoiminaan väistämättä edellyttävän skaalautuvia IT-palveluita.

Tässä sarjassa kirjoitan kuitenkin vain  tuote- tai palveluohjelmistojen skaalautuvuudesta eli järjestelmien skaalautuvuudesta. Tässä yhteydessä käytän ennemmin sanaa “järjestelmä” kuin “ohjelmisto,” koska isommissa palveluissa on käytössä useita eri ohjelmistoja monissa eri tarkoituksissa. Liiketoiminnan näkökulmasta on mielekästä puhua vain koko järjestelmän suorituskyvystä tai skaalautuvuudesta, josta yksittäisen järjestelmän osan suorituskyky tai skaalautuvuus on vain osatekijä.

Minkään järjestelmän skaalautuvuus ei (yleensä) ole liiketoiminnan itsetarkoitus, vaan skaalautuvuudesta pitää puhua yhtenä järjestelmän ominaisuutena jonka avulla pystytään tarvittaessa kasvattamaan järjestelmän kokonaissuorityskykyä. Kärjistäen voi sanoa, ettei bisnestä kiinnosta saadaanko järjestelmästä haluttu suorituskyky tietokoneiden vai hiirien avulla, kunhan se vastaa tarpeita (joihin voi kuulua – mutta ei aina – myös kustannustehokkuus.)

Otetaan hatusta täysin tekaistu yritys, LöydäSukkasi.com joka rakentaa palvelua, jolla ihmiset voivat löytää pesukoneen syömät RFID-tunnisteiset sukkansa. Maailmalla on satoja miljardeja sukkapareja, joten potentiaalia kasvulle on valtavasti. Yrityksellä on valmis pilottitoteutus järjestelmästä suurasiakkaalle, vaikkapa Keski-Suomenlahden Aluemerisairaalalle. Järjestelmän pilotti toimii yhdessä palvelintietokoneessa ja toteuttaa oleelliset asiat palvelusta eli seuraa sukkien kulkua pilottikiinteistössä RFID-lukijoiden avulla  ja tarjoaa verkkopalvelun jota kautta tarkoin rajattu käyttäjäjoukko pystyy seuraamaan sukkaparien (ja orpojen sukkien) tilaa ja sijaintia. Pilottijärjestelmä pystyy tällä hetkellä seuraamaan reaaliajassa 100 sukkaparin tilaa.

Järjestelmän suorityskyky on siis 100 yksikköä (sukkaparia.) Ongelma on vain se, että Keski-Suomenlahden Aluemerisairaalassa on 500 sukkaparia! Tavoite on siis kasvattaa järjestelmän suorituskykyä. Miten?

Voimme siirtää järjestelmän tehokkaampaan tietokoneeseen, eli siirtyä “ylöspäin” kohti tehokkaampaa tietokonetta. Tämä on vertikaalista skaalautumista. Siirtymällä perus-1U räkkipalvelimesta high-end moniprosessoripalvelimeen voidaan palvelua tehostaa 10-20× luokkaa. LöydäSukkasi.com voisi siis skaalautua vertikaalisesti siirtämällä palvelunsa tehokkaampaan koneeseen.

Skaalautuminen vertikaalisesti, eli siirtämällä järjestelmä tehokkaampaan koneeseen.

Vertikaalinen skaalautuminen kuitenkin edellyttää järjestelmän komponenttien pystyvän hyötymään useammasta prosessoricoresta (koska megahertsien kasvattaminen polku palvelimissa loppui jo vuosia sitten). Jos näin ei ole, vaihtoehtoina on joko uudelleenkirjoittaa palvelu hyödyntämään moniprosessoriarkkitehtuuria tai siirtyä suoraan horisontaaliseen skaalautumiseen.

Vaihtoehto tehokkaamman koneen hankkimiselle on monistaa järjestelmän osia useisiin eri koneisiin, eli skaalautua horisontaalisesti. Jos lisäisimme järjestelmään neljä palvelinta niin teoreettisesti voisimme saavuttaa 500 sukkaparin suorituskyvyn. Edellytyksenä on kuitenkin, että 1) järjestelmän pullonkaulakomponentit voidaan hajauttaa toimimaan useammassa koneessa ja 2) eri koneissa olevien komponenttien välillä ei ole niiden toimintaa hidastavia riippuvuuksia.

Skaalautuminen vertikaalisesti, eli siirtämällä järjestelmä tehokkaampaan koneeseen.

Kultainen ohjenuora skaalautuvien järjestelmien suunnittelussa on, ettei kumpikaan näistä oletuksista päde ellei toisin todisteta. (Todistettu – ei faktuaalisesti todettu. Skaalautuminen voidaan todeta todelliseksi vasta kun järjestelmä on testattavana – eli ei siis vielä suunnitellessa, jolloin pitää nojautua argumentatiiviseen todisteluun ja/tai analyyttisten mallien antamiin ennusteisiin.)

Kävin läpi sekä vertikaalisen että horisontaalisen skaalautuvuuden mahdollisina ratkaisuina järjestelmän suorituskyvyn nostamisessa 100 sukkaparista 500 sukkapariin. Yksi varteenotettava, mutta monesti unohdettu vaihtoehto on järjestelmän komponenttien tehostaminen. Selkokielellä tämä tarkoittaa olemassaolevan koodin profilointia, analysointia, debuggausta, pullonkaulojen etsimistä ja poistamista. Tehostuksen hyödyllisyys riippuu tietysti täysin lähtötilanteesta.

Seuraavassa osassa kirjoitan suorituskyvyn ja skaalautuvuuden rajoista ja kustannuksista.

Sokerina pohjalla vähän linkkejä:

P.S. Jos tiedätte hyvää verkossa tai verkon ulkopuolella olevaa suomenkielistä materiaalia skaalautumisesta, niin jakakaa se ihmeessä kaikkien lukijoiden kanssa!

P.P.S. Tsekkaa myös seuraava osa.

Tiedostojen synkronisointi

Kirjoittanut Markus Holmberg, 1.2.2010 - 08:45 - 3 vastausta

Yksi Amazon S3 -talletuspalvelua usein hyödyntävä luokka palveluita on verkkolevyt ja muut tiedostojen synkronisointipalvelut. Eli palvelut, joiden avulla käyttäjä voi lukea ja kirjoittaa omia tiedostojaan usealta eri laitteelta. Esimerkkejä tällaisista ovat Dropbox ja Jungle Disk.

Tiedostojen synkronisointipalvelu muodostaa käytännössä käyttäjän laitteista hajautetun järjestelmän, jossa jokainen synkronisointiin osallistuva laite on oma noodi tätä järjestelmää. Hajautetuissa järjestelmissä on erityisiä haasteita, joista CAP-teoreema kuvaa yhtä: kolmesta ominaisuudesta C, A ja P, hajautettu järjestelmä voi yhtäaikaisesti taata ainostaan kaksi. Mitkä ovat sitten ominaisuudet C, A ja P tällaisessa tiedostojen synkronisointijärjestelmässä?

  • C: näenko täsmälleen samat tiedostot ja sisällöt jokaisella synkronisointiin osallistuvalla laitteella? (engl. consistency)
  • A: ovatko tiedostoni luettavissa ja kirjoitettavissa aina tarvittaessa, olettaen että järjestelmä yleisesti on toimivassa tilassa? (engl. availability)
  • P: ovatko tiedostoni luettavissa ja kirjoitettavissa myös kun verkkoyhteys ei toimi? (engl. partition-tolerance)

Huvin ja hyödyn vuoksi näitä määritelmiä voi nyt käyttää ymmärtääkseen paremmin mitä ominaisuuksia eri palveluilla on. Eli, mitkä yhdistelmät ominaisuuksista C, A ja P ovat eri tiedostojen synkronisointipalveluiden tarjoajat valinneet?

  • Dropbox on palvelu, jossa joukkoa tiedostoja käyttäjän laitteen paikallisessa tiedostojärjestelmässä jatkuvasti päivitetään muutoksilla jotka on tehty muilla synkronisointiin osallistuvilla laitteilla. Palvelua voi luonnehtia AP-palveluna, koska tiedostot ovat jatkuvasti luettavissa ja kirjoitettavissa niin kauan kuin paikallinen tiedostojärjestelmä toimii (A) ja samat tiedostot ovat edelleen luettavissa ja kirjoitettavissa vaikka verkkoyhteys ei toimi (P). Toisaalta kaksi laitetta voi toisistaan riippumatta tallettaa ristiriitaiset versiot samasta tiedostosta, esim. kun verkkoyhteys ei toimi (eli ei C).
  • Jungle Disk on palvelu, jossa tiedostojen sisältö ensisijaisesti elää palveluntarjoajan verkopalvelimella. Palvelua voi luonnehtia CA-palveluna: Jokainen tiedosto-operaatio vaatii synkronisen viestin lähettämistä verkkopalvelimelle (hieman yksinkertaistettuna). Tämä takaa että jokainen laite aina näkee viimeisimmän ja saman version tiedostosta, koska se joka kerta haetaan samasta keskeisestä verkkopalvelimesta (C). Lisäksi tiedostot ovat luettavissa ja kirjoitettavissa, kunhan järjestelmä, eli verkkopalvelin, yleisesti on toimivassa tilassa (A). Tiedostot eivät kuitenkaan ole luettavissa eikä kirjoitettavissa, jos verkkoyhteys ei toimi (eli ei P).

Nämä kaksi (AP ja CA) näyttävät olevan yleisimmät CAP-yhdistelmät tiedostojen synkronisointipalveluissa. Esimerkkiä palvelusta CP-ominaisuuksilla ei tule heti mieleen.

Lisäksi A:n ja P:n eroa voi tosiaan olla hankala hahmottaa. Tästä huolimatta CAP-teoreema auttaa ymmärtämään hajautettujen järjestelmien haasteita ja ominaisuuksia. Ja näyttää että jopa niin näennäisesti triviaalin sovelluksen kuin tiedostojen synkronisoinnin taustalla on merkittäviä suunnitteluperiaatteita.