Miten rakennat järjestelmän, joka skaalautuu 100 miljoonalle käyttäjälle? Vastaus: Et rakenna.

Onko tämä kompa vai yritänkö vetää lukijaa nenästä? Kyllä ja ei. Siksi vähän pidempi vastaus: Älä rakenna itse sellaista skaalautuvuutta, jonka joku muu on jo ratkaissut (ja jota voit hyödyntää).

IaaS- ja PaaS -markkinoilla on paljon skaalautuvia infra- ja middlewareratkaisuja joissa toimittaja ottaa vastuun palvelun skaalautumisesta, ja tilaajan vastuulle jää laskun maksaminen. Yksinkertaisen esimerkin saa tehtyä Amazon Web Service:n S3-tiedostopalvelulla sekä SQS-viestijonopalvelulla. Alla on esimerkkikuva arkkitehtuurista jossa selain lukee tiedot S3:sta ja viestii taustajärjestelmälle vain SQS:n kautta:

Järjestelmä toimii siten, että kohdassa A taustajärjestelmä työntää S3:een tiedot, jotka asiakasohjelma (selain) hakee kohdassa B. Selaimessa pyörivä ohjelma interaktoi käyttäjän kanssa ja lähettää tarvittaessa asynkroniset palvelupyynnöt taustajärjestelmälle SQS:n kautta kohdassa C. Taustajärjestelmä purkaa sitten SQS-jonoa omaa tahtiaan kohdassa D.

Jotta tämä keskustelu ei jäisi teoreettiselle tasolle, esittelen nyt (rummunpäristystä) palvelun nimeltä spingy. Kyseessä on yksinkertainen järjestelmä, joka pingailee käyttäjien määrittelemiä internet-palvelimia ja piirtää sitten käyttäjälle nätin kuvaajan palvelimen verkkotason latenssista. Tähän malliin:

Spingy toimii siten, että taustapalvelin pingailee palvelimia omaan tahtiinsa ja ajoittain työntää tulostietoja S3:een. Asiakasohjelma on selaimessa toimiva javascript-pohjainen ohjelma, joka hakee raakadatan S3:lta ja piirtää näistä kauniit kuvat. Presentaatiokerros ja sen aiheuttama kuorma on siis sataprosenttisesti selaimessa. Tiedonsiirron skaalautumisen hoitaa S3. Taustajärjestelmä itsessään ei näe käyttäjien aiheuttamaan kuormaa kuin pingattavien koneiden lukumäärän kasvuna – joka oletettavasti kasvaa hitaammin kuin käyttäjien määrä, koska julkisessa internetissä on kiinni vähemmän tietokoneita kuin planeetalla on ihmisiä.

Taustapalvelimena on yksi mikroinstanssi. Siis 1 – uno, ett, one. Enempää se ei edes tarvitse. Alunperin asetin spingylle tavoitteeksi 50 000 koneen pingauksesta kaksi kertaa tunnissa ja ainakin penkkitesteissä tämä saavutetaan helposti:

  • Yli 400 000 pingiä tunnissa yksisäikeisenä (CPU ei noussut yli 10%, joten tuota voisi rinnakkaistaa moninkertaisesti)
  • Yli 120 000 käsiteltyä ja vastaanotettua SQS-viestiä tunnissa (myös yksisäikeisenä)

SQS:ään pystyn työntämään uusia viestejä yhdeltä koneelta myös riittävän nopeasti (>200 000/h), mutta koska spingyn selainpää normaalisti lähettää vain muutamia viestejä päivässä, ei asiakaspään viestien lähetyksen kaistanleveydellä ole niin suurta merkitystä. En ole erikseen testannut SQS:n suorituskyvyn rinnakkaistumista, joten se on tässä kohtaa pelkkä oletus. (200 tuhatta viestiä tunnissa ei viestijärjestelmille ole itsessään kummoinen tulos, mutta tähän käyttöön enemmän kuin riittävä.)

Vaikka S3 on “tunnetusti” skaalautuva, päätin silti testata sitä. Ajoin Cloud Assaultilla testin 250 rinnakkaisella clientillä. Testi tosin latasi vain Spingyn etusivua, mutta sekin on S3:ssa. Tuloksena oli tasaisesti yli 1300 latausta sekunnissa.

Miten hyvin tämä toimii oikeasti? Ehkä se ei ole niin relevanttia. Kyseessä on kuitenkin tekninen demo, ei kaupallinen ratkaisu. Demona se esittelee yhden mallin tehdä skaalautuvia verkkopalveluita. Toiminnallisuudeltaan se on hyvin rajoitettu eikä sellaisenaan ole sovellettavissa muissa palveluissa – mutta ehkä mallina siitä, mikä on yksi tapa saavuttaa skaalautuvuutta.

Hmmm, luulen että kirjoitan Spingystä ja skaalautuvuusmalleista vielä jossain vaiheessa lisää. :-)

P.S. Spingyn lähdekoodi on GPLv2:n alla ja löytyy githubista. Jos sinulla on parannettavaa koodiin tai vaikka ohjeisiin niin forkkaa ja laita pull request tulemaan!

Artikkelin tagit:
 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *

*

Voit käyttää näitä HTML-tageja ja attribuutteja: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>