May 24, 2016

Joskus onnistut, joskus taas…

Fotolia_74274270_L_Sometimes_you_win....jpg

Better_Tech_Blog_intro_banner.jpg
[In English below] Sanotaan, että se mikä ei tapa, se vahvistaa - tai ainakin tekee erikoisemmaksi. Sanonta pätee ihmisiin ja vain harvoin järjestelmiin, sillä vain ihminen (yleensä) oppii kohtaamistaan haasteista ja kehittää itselleen sietokykyä. Järjestelmille kyky oppia on ainakin vielä toistaiseksi harvinaista: ne usein yksinkertaisesti joko kestävät haasteet tai luhistuvat niiden alle. Luhistumisen voi aiheuttaa esimerkiksi hetkellisesti liian suureksi nouseva kuorma eli aiemmassa blogikirjoituksessani käsittelemäni dataryöppy. Dataryöppyihin vastataan rakentamalla järjestelmästä skaalautuvuuden kautta elastinen, mikä kasvattaa järjestelmän vastustuskykyä. Vastustuskykyinen järjestelmä kykenee sietämään myös muunlaisia haasteita, joita voidaan yleisesti kutsua vioiksi.
 

Uppoamattomia järjestelmiä

Vikoihin varautumisella on pitkä historia laivateollisuudessa. Sata vuotta taaksepäin kilpailu suurempien ja nopeampien laivojen rakentamisessa kävi kiivaana. Laivojen koon kasvaessa niissä alettiin hyödyntämään uudenlaista laipiorakennetta¹. Ajatuksena oli, että jos yksi laipioilla eristetty laivan osasto vaurioituu täyttyen vedestä, ei koko laiva uppoa, vaan vesi pääsee ainoastaan vaurioituneeseen osastoon. Tämä “uppoamaton” laipiorakenne joutui tosikoetukseen ensikertaa vuonna 1912, kun yksi ensimmäisistä uudenlaisen laipiorakenteen laivoista, RMS Titanic, teki neitsytmatkansa.

Want to know more about working for Landis+Gyr? Just click.

Surullisenkuuluisan Titanicin tarina tunnetaan, mutta miksi “uppoamaton” ei ollutkaan uppoamaton? Syy on monien tekijöiden summa, joista vähäisin ei varmastikaan ole vähintään Jyväskylän Innovan kokoinen jäävuori. On kuitenkin myös toinen uppoamiseen suuresti vaikuttanut tekijä. Laivan laipiorakenteessa osastojen väliset laipiot eivät yltäneet laivan kannelle asti eivätkä osastojen katot olleet vesitiiviitä, jolloin vesi pääsi tulvimaan vesitiiviiden ovien yli aluksen muihin osiin. Osastoja ei ollut siis eristetty riittävästi, ja osastojen tulviminen eteni ketjureaktion tavoin upottaen lopulta koko laivan surullisin seurauksin. Nykylaivat noudattavat edelleen laipiorakennetta, mutta laipiot eristävät osastot koko laivan korkeudelta. Teoriassa laivan pitäisi olla lähes kokonaan veden alla, jotta se uppoaisi.

Osastojen ja eristämisen tärkeys tietojärjestelmissä

Nykypäivän tietojärjestelmät ovat monoliittien sijaan enenevissä määrin useamman (mikro)palvelun summia - siis hieman kuin useista osastoista koostuvia risteilijöitä. Toisinaan tietojärjestelmät on valitettavasti rakennettu niin, että palvelut eivät ole riittävän itsenäisiä ja eristettyjä. Ne riippuvat tiukasti muista järjestelmän palveluista, jolloin yhden vikaantuminen voi aiheuttaa lamaantumisten muissa palveluissa ja lopulta koko järjestelmässä.

Eteeni osui artikkeli, jossa avattiin syitä erääseen merkittävään satojatuhansia suomalaisia koskettaneeseen järjestelmähäiriöön viime tammikuulta: "Järjestelmät on suunniteltu kestämään kaikkia ylikuormitustilanteita, mutta tässä tapauksessa tietty ei-kriittinen prosessointitoiminto, jonka olisi tullut kytkeytyä pois käytöstä, esti ylikuormituksen automaattisen purkautumisen. Tämä johti valitettaviin palvelukatkoksiin Yritys X:n asiakkaille, mitä pahoittelemme syvästi", kertoo Yritys Y tiedotteessaan. Edellisessä kuvatun järjestelmän voi arvata rakentuneen niin, että se koostui toisistaan eristetyistä osastoista. Kuitenkin, huolimatta suuresta vaivannäöstä kokonaisarkkitehtuurin suunnittelussa, järjestelmään oli rakennettu yksi pieni osasto, jota ei ollut eristetty muista osastoista. Vesi pääsi tälle pienelle osastolle ja tulvi sitä kautta kaikkialle upottaen koko järjestelmän.

Kaaos parantaa vastustuskykyä

Videoiden suoratoistopalvelu Netflix on yksi esimerkki yrityksestä, jossa viat on hyväksytty väistämättömänä pahana ja nostettu jalustalle alusta alkaen. Yksi Netflixin vahvuuksista on kyky palvella suurta yhtäaikaista käyttäjämäärää tehokkaasti. Tähän tarvitaan järjestelmän hajauttamista ja aiemmassa kirjoituksessani mainitsemaani elastisuutta. Hajautus tuo mukanaan myös uuden mielenkiintoisen ongelmakentän, jota Antti Nevala loistavassa blogitekstissään taannoin avasi. Se johtaa väistämättä monimutkaisempaan järjestelmään, jota on vaikea testata kokonaisuutena. Netflix käyttää kompleksisen järjestelmänsä vikapaikkojen tunnistamiseen työkalua, joka tunnetaan nimellä Chaos Monkey. Netflix siis ikään kuin vapauttaa järjestelmäänsä lauman kaaosapinoita aiheuttamaan vikoja, esimerkiksi kaatamaan satunnaisia järjestelmäpalvelimia. Järjestelmän on kyettävä selviytymään näistä tilanteista, sillä niitä tapahtuu ilman kaaosapinoitakin – tosin harvemmin, mikä taas vaikeuttaisi merkittävästi vikojen havaitsemista ennen kuin ne tulisivat eteen tositilanteessa.

Paras tapa puolustautua suurilta odottamattomilta vioilta on epäonnistua usein, monimuotoisesti ja mahdollisimman aikaisin. Kun vikoja aiheutetaan alusta asti tiheästi, järjestelmän palvelut pakotetaan rakentumaan vastustuskykyisiksi vioille. Tiedämme, että tietoverkko kadottaa ja vääristää bittejä ja palvelimet hajoavat ja kaatuilevat - kuvainnollisesti ja fyysisesti. Järjestelmiä tuleekin testata näitä väistämättömiä vikaantumisia vastaan tehokkaasti. Laivojen virhesietoisuutta on kallista testata ajamalla ne karille. Ohjelmistojen kohdalla meidän on vain löydettävä tai rakennettava sopivat karikot ja ajettava niitä karikoita vasten monesta eri suunnasta ja usein. Tällainen fail fast -kulttuuri sopiikin erityisen hyvin juuri järjestelmien kehittämiseen - jos järjestelmässä tapahtuu vika, sen tulee kaatua heti ja näkyvästi. Rakentamalla vikasietoista koodia vioille, jotka väistämättä saavat järjestelmän käyttäytymään poikkeavasti, kehitetään vain suurempia ongelmia tulevaisuuteen. Ei siis kannata ensisijaisesti rakentaa vikasietoista järjestelmää vaan vioille vastustuskykyinen järjestelmä.

Virhe opettaa onnistumaan

Vikoja syntyy väistämättä. Niitä syntyy tietoverkkoihin, laitteisiin ja myös ihmiset tekevät virheitä. Vikaantumista ei voi kokonaan estää, mutta kun mahdolliset vikapaikat tunnistetaan, voidaan ongelmiin varautua. Parasta mitä voimme tehdä, on yrittää tunnistaa ongelmakohdat jo ennen tositilannetta. Tunnistettuamme vikaantuvat pisteet voimme parannella järjestelmää niin, että vastustuskyky tunnistetuille vioille kasvaa. Vastustuskykyisten järjestelmien rakentamisen ytimessä on juuri virheiden ja vikojen hyväksyminen ja arvostaminen. Joskus onnistut, joskus taas opit onnistumaan.

Sukellus ohjelmistovian seurauksiin

1) Laipiorakenteiset laivat on jaettu osastoihin, jotka on eristetty toisistaan eristävillä seinämillä eli laipioilla

Lisäluettavaa:

Related articles

___________________________________________________________________________________

Sometimes you win, sometimes you...

They say that what doesn’t kill you only makes you stronger – or at least more special. This saying applies to people, but very rarely to systems. Generally only people are able to learn from the challenges they face and develop a thick skin. For systems, the ability to learn is still rare: they either simply endure challenges or crumple under them. This crumpling can result from a momentary overload, i.e. the data waves that I discussed in an earlier blog entry. Data waves can be met by building an elastic system through scalability, which increases the system’s resilience. A resilient system can also withstand other types of challenges, which can, generally speaking, be labelled as faults.

Unsinkable systems

Preparing for faults has a long history in the shipping industry. A hundred years back, the competition to build bigger and faster ships was in full swing. As the ships grew in size, a new type of bulkhead structure was introduced¹. The idea was that if a ship compartment separated by bulkheads is damaged and fills with water, the entire vessel does not sink; instead the water only infiltrates the damaged compartment. This “unsinkable” bulkhead structure was truly put to the test for the first time in 1912 when one of the first ships to have the new type of structure, the RMS Titanic, made its maiden voyage.

Want to know more about working for Landis+Gyr? Just click.

The story of the Titanic is infamous, but why wasn’t the “unsinkable” unsinkable? Many factors were involved, of which the iceberg the size of the Innova building in Jyväskylä was probably not the least. Another factor was also a major contributor to the sinking. The bulkheads between the ship compartments did not reach all the way to the upper deck and the compartments’ ceilings were not waterproof, meaning that the water was able to flood the other parts of the ship over the watertight doors. The compartments were not sufficiently watertight and the flooding of the compartments proceeded in a chain reaction, finally sinking the entire ship, with tragic consequences. Modern ships still have a bulkhead structure but the bulkheads isolate the compartments along the entire height of the ship. In theory, a vessel would have to be almost completely submerged for it to sink.

Importance of compartments and isolation in information systems

Modern information systems are more and more often the sum of (micro) services instead of monoliths – not much unlike a bit like a cruise ship made up of several compartments. Sometimes information systems are unfortunately built in a way in which the services are not sufficiently independent and isolated. They are firmly reliant on the system’s other services, which means that a fault in one can cause the other services, and finally the entire system, to be immobilized.

I happened upon an article that explained the reasons for the system failure that affected hundreds of thousands of Finns last January: “The systems are designed to withstand all overload situations but in this case a specific non-critical process function, which should have switched off, prevented the automatic discharging of the overload. This unfortunately led to service breaks for Company X’s customers, which we are deeply sorry about,” says Company Y in its press release. The system described above was probably built so that it consisted of compartments that were isolated from one another. However, despite the great amount of work taken to design the overall architecture, the system had one small compartment that had not been isolated from the others. The water seeped into this small compartment, finally flooding the entire system. 

Chaos improves resilience

The video streaming service Netflix is an example of a company where faults have been recognized as an unavoidable evil and lifted up on a pedestal from day one. One of Netflix’s strengths is the ability to efficiently serve a large number of users simultaneously. This requires a distributed system and the elasticity that I mentioned in my earlier blog post. Distribution also brings with it a new, interesting range of problems, as Antti Nevala wrote in his excellent blog entry while ago. This inevitably leads to a more complicated system, which is difficult to test as a whole. Netflix uses a tool to recognize faults in its complex system, which is known as Chaos Monkey. Netflix can thus let loose a troop of chaos monkeys into its system to cause faults, for example to crash random system servers. The system must be able to withstand these situations because they will also happen without the chaos monkeys – less often of course, which would, on the other hand, make it difficult to observe the faults before they come up in real situations.

The best way to defend against unexpected faults is to fail often, diversely and as early as possible. When faults are initiated frequently from the very start, the system’s services are forced to build up their resilience to them. We know that information networks lose and distort bits, and servers break down and crash – both figuratively and physically. Systems need to be vigorously tested against these inevitable types of faults. It is expensive to test the fault tolerance of ships by running them aground. In terms of software we only need to find and construct suitable obstacles and frequently run the systems against these obstacles from many different directions. This type of fail fast culture is particularly well suited to system development – if a fault occurs in a system, it should crash immediately and conspicuously. Building a fault-tolerant code for faults that inevitably cause the system to function unusually only serves to create bigger problems in the future. It is thus not useful to build a fault-tolerant system but instead a system that is resilient to faults.

Learning from failures

Failures are inevitable. They occur in information networks, devices and are also caused by humans. Faults can never be prevented entirely but when potential fault points are identified we can prepare for them. The best thing we can do is to try and spot the problems before they hit us. Once we recognize the fault points we can improve the system so that it can build up its resilience to the identified faults. At the core of building a resilient system is precisely the acceptance and valuing of failures and errors. Sometimes you win, sometimes you learn.

Diving into consequences of software errors

1) Ships with bulkhead structures are divided into compartments that are partitioned from one another with bulkheads.

Further reading:

Related articles