Løsningseleganse
Det er svært lett, når man jobber med IT, å bli opptatt av store, komplekse løsninger. Det virker som om det er her de gode løsningene må ligge – store løsninger, mye programvare, alle de nyeste dingsene. Det vi gjør er spennende, og det er veldig lett å bli revet med i farten. Det er gøy å arbeide med krevende, store prosjekter. Å høre hva andre IT-fagfolk gjør, hvordan andre selskaper løser utfordringer, og å snakke med leverandører som har store systemer å selge – alt dette bidrar til spenningen, og det er svært lett å miste begrep om omfang og mål. Det er så vanlig å se store, overdrevne løsninger på enkle problemer at det kan virke som om dette bare er slik IT er.
Men slik trenger det ikke å være. Kompleksitet er fienden til både pålitelighet og sikkerhet. Unødvendig komplekse løsninger øker kostnadene både ved anskaffelse og implementering, samt ved vedlikehold, samtidig som de generelt er tregere, mer skjøre og har en stor angrepsflate som er vanskeligere å forstå og beskytte. Enkle, eller mer presist, elegante løsninger er den beste tilnærmingen. Dette betyr ikke at alle design vil være enkle – slett ikke. Komplekse design er ofte nødvendige. IT er knapt et fagfelt som mangler kompleksitet. Faktisk er det ofte hevdet at programvareutvikling kanskje er den mest komplekse av alle menneskelige virksomheter, i hvert fall av dem som utøves i noen skala. En typisk IT-installasjon inkluderer millioner av kodelinjer, hundrevis eller tusenvis av protokoller, store antall sammenknyttede systemer, lag av unike programvarekonfigurasjoner, flere innstillinger enn noe team kan kjenne til – og først da legger vi til kompleksiteten med hundre- eller tusenvis eller hundretusener av uforutsigbare, irrasjonelle mennesker som forsøker å bruke disse systemene, hver på sin unike måte. IT er, uten tvil, komplekst.
Det som er viktig er å erkjenne at IT er komplekst, at dette ikke kan unngås fullstendig, men å fokusere på å designe og konstruere løsninger som er så enkle, så grasiøse... så elegante som mulig. Denne designideen kommer fra, i hvert fall i mitt hode, programvareutvikling, der kompleks kode anses som en feil og enkel, vakker kode som er lett å lese og lett å forstå regnes som vellykket. Et av de høyeste hedersbeviser som kan tildeles en programvareingeniør er at koden hennes betegnes som elegant. Hvor treffende at dette sitatet tilskrives Blaise Pascal, etter hvem ett av de mest populære programmeringsspråkene på 1970- og 1980-tallet ble oppkalt (oversatt dårlig fra fransk): “Jeg beklager at jeg måtte skrive deg et så langt brev, men jeg hadde ikke tid til å skrive et kort.”
Det er ofte langt lettere å designe komplekse, innviklede løsninger enn det er å finne ut hvilken enkel tilnærming som ville være tilstrekkelig. Enten vi har det travelt eller ikke vet hvor vi skal begynne en undersøkelse, er eleganse alltid en utfordring. Bransjens momentum er å fremme den vanskeligere veien. Det er i leverandørenes interesse å selge mer utstyr – ikke bare for å gjøre det første salget, men de vet at mer utstyr gir mer supportinntekter, og hvis nok nytt, komplekst utstyr selges, slutter supportbehovet å øke lineært og begynner å øke geometrisk ettersom det trengs ekstra support ikke bare for utstyret eller programvaren i seg selv, men også for konfigurasjon og support av systeminteraksjoner eller ytterligere tilpasning. De finansielle insentivene bak kompleksitet er store, og de stopper ikke med leverandørene. IT-fagfolk oppnår mye jobbsikkerhet, eller illusjonen av den, ved å administrere store sett med maskinvare og programvare som er vanskelig å sømløst overføre til en annen IT-fagperson.
Ofte er kompleksitet så antatt, så forventet, at prosessen med å velge en løsning begynner med stor kompleksitet som en gitt ting uten noen vurdering av muligheten for at en mindre kompleks løsning kan være tilstrekkelig, eller til og med overlegen utenfor spørsmålet om kompleksitet og kostnad i seg selv. Kompleksitet er noen ganger til og med fullstendig knyttet til visse konsepter i en slik grad at jeg faktisk har møtt vantro ved tanken om at en enkel løsning kanskje kan overgå en kompleks én i pris, ytelse og pålitelighet.
Retorikk er enkelt, men hva er et reelt eksempel? De beste eksemplene jeg ser i dag er for det meste relatert til virtualisering, enten det gjelder lagring, et skybehandlingslag, programvare eller bare virtualisering i seg selv. Jeg ser ganske ofte at en samtale som bare involverer virtualisering for én person umiddelbart gir assosiasjoner om behov for nettverkstilkoblet, delt blokklagring, dyr virtualiseringsadministrasjonsprogramvare, mange redundante virtualiseringsnoder og kompleks programvare for høy tilgjengelighet – ingen av delene er iboende i virtualisering, og de fleste tjener sjelden formålet med å støtte eller egentlig heller ikke er i bedriftens interesse for dem som de vil bli implementert for. Snarere enn å arbeide ut fra forretningskrav oppstår disse konseptene overveiende fra teknologiske forutinntatte forestillinger. Det er enkelt å peke på kompleksitet og se ut til å løse et problem – kompleksitet skaper en følelse av trygghet. Filtrer mange argumenter ned og du vil høre «Hvordan kan det ikke virke, det er jo komplekst?» Kompleksitet gir en illusjon av fullstendighet, av å ha løst et problem, men dette kan ofte skjule det faktum at en løsning kanskje ikke faktisk er fullstendig eller engang funksjonell, men kompleksitetsnivået gjør dette vanskelig å se. Sinnet vårt vil da ikke lett akseptere en enklere tilnærming som mer fullstendig og løsende for et problem når en kompleks ikke gjør det, fordi det føles så motintuitivt.
Et godt eksempel på dette er at vi tyr til å diskutere redundans i stedet for pålitelighet. Pålitelighet er vanskelig å måle, redundans er enkelt å kvantifisere. En murstein er svært pålitelig, selv alene. Det krever ikke redundans for at en murstein skal være stabil og robust. Designet er enkelt. Du kunne lage en bærende konstruksjon av mange redundante pinner som ikke ville være nær så pålitelig som en enkelt murstein. Hvis du snakker om pålitelighet – sjansen for at konstruksjonen ikke vil feile – er det klart at mursteinen er et overlegent valg fremfor flere pinner. Men hvis du sier «men det er ingen redundans, mursteinen kan feile og det er ingenting til å erstatte den» høres du tullete ut. Men når vi snakker om datamaskiner og datasystemer finner vi systemer som er så komplekse at folk sjelden ser når de har en murstein eller en pinne, og siden de ikke kan fastslå påliteligheten som betyr noe, fokuserer de på den lett kvantifiserbare redundansen som ikke betyr det samme. Hele systemet er for komplekst, men å søke den enkle løsningen, den som direkte adresserer kjernen av problemet som skal løses, kan redusere kompleksiteten og gi oss et langt bedre svar til slutt.
Dette kan til og med sees i RAID. Speilvendt RAID er enkelt, bare én disk eller et sett med disker som er en eksakt kopi av et annet sett. Det er så enkelt. Paritet-RAID er komplekst med beregninger på en variabel stripe på tvers av mange enheter som må kodes ved skriving og dekodes hvis en enhet feiler. Speilvendt RAID mangler denne kompleksiteten og løser problemet med diskpålitelighet gjennom enkle, elegante kopieringsoperasjoner som er svært pålitelige og godt forstått. Paritet-RAID er unødvendig komplekst noe som gjør det skjørt. Likevel, ved å gjøre dette og ved å undergrave sin egen evne til å løse problemet det ble designet for, fremstår det også, samtidig, som tilsynelatende mer pålitelig basert på ingen annen faktor enn sin egen kompleksitet. Det menneskelige sinnet hopper umiddelbart til «det er komplekst, derfor er det mer avansert, derfor er det mer pålitelig» – men ingen av disse slutningene er logiske. Kompleksitet antyder ikke at det er mer avansert, og det å være avansert antyder ikke at det er pålitelig, men det menneskelige sinnet i seg selv er komplekst og lett å villede.
Det finnes intet enkelt svar for å finne enkelhet. Å vite at kompleksitet er dårlig av natur men uunngåelig til tider lærer oss å være bevisste, men det lærer oss ikke når vi skal mistenke over-kompleksitet. Vi må være årvåkne, alltid søkende etter å fastslå om det finnes et mer elegant svar, og ikke akseptere kompleksitet som det riktige svaret bare fordi det er komplekst. Vi må stille spørsmål ved foreslåtte løsninger og stille spørsmål ved oss selv. «Er denne løsningen virkelig så enkel som den bør være?» «Er denne kompleksiteten nødvendig?» «Krever dette den kompleksiteten jeg hadde antatt?»
I de fleste systemdesignranbefalinger jeg gir, er det første tekniske vurderingstrinnet jeg normalt tar, etter trinnet med å spørre om forretningsbehovet som skal løses, å stille spørsmål ved kompleksiteten. Hvis kompleksiteten ikke kan forsvares, er den sannsynligvis unødvendig og aktivt ødeleggende for formålet den ble valgt for.
«Er det virkelig nødvendig å dele disse diskene inn i mange separate arrayer? Hvis ja, hva er den tekniske begrunnelsen for å gjøre det?»
«Er delt lagring virkelig nødvendig for oppgaven du foreslår det for?»
«Rettferdiggjør virksomheten virkelig bruk av distribuerte teknologier for høy tilgjengelighet?»
«Hvorfor erstatter vi et enkelt system som var tilstrekkelig i går med et dramatisk mer komplekst system i morgen? Hva har endret seg som gjør at en betydelig forbedring, mens man forblir enkel, ikke er mer enn nok, men krever størrelsesordener mer kompleksitet og mer utgifter som ikke var berettiget tidligere?»
Dette er bare vanlige eksempler – kompleksitet finnes i alle aspekter av vår bransje. Se etter enkelhet. Streb etter eleganse. Ikke aksepter kompleksitet uten å granske den grundig. Sett den gjennom den sprikvannelige mangelen. Ikke la kompleksitet snike seg inn der det ikke er berettiget. Ikke la tvil komme kompleksiteten til gode – ved tvil, feil enkelt. Å oversimplisere en løsning resulterer vanligvis i en mindre feil, mens det å gjøre den for kompleks åpner for en langt større grad av feil. Den sikrere innsatsen er med den enklere løsningen. Og hvis en enkel løsning velges og viser seg utilstrekkelig, er det langt lettere å legge til kompleksitet enn det er å fjerne den.
