En af udfordringerne, når du har at gøre med et nyt databasedesign, er, at du ikke ved ting som, hvor store tabellerne ender med at blive, før de faktisk er fyldt med en rimelig mængde data. Men hvis designet skal tage højde for de eventuelle skalerbarhedsproblemer, kan du ikke implementere det for at få disse data, før estimeringen er færdig. En måde at undgå dette på er at aggressivt prototype ting. Brug iscenesættelseshardware til dette formål, som nye applikationer kan leve på midlertidigt, mens du sorterer detaljer som denne fra. Du kan bare medregne, at du bliver nødt til at flytte appen og muligvis redesigne den efter et par måneder, når du har en bedre idé om, hvilke data der skal dukke op i den.
Den anden måde at komme uden om dette kylling/æg problem på er at skrive en datagenerator. Konstruer nok prøvedata i hånden til at se, hvordan det ser ud, hvor tæt det er, og hvordan dets værdier er fordelt. Skriv derefter noget, der tager disse statistikker og producerer et større datasæt, der ligner det. Du får det aldrig til at være perfekt, men det behøver det ikke at være. Generering af gigantiske datasæt, selv med nogle fejl, er stadig den bedste tilgængelige måde at foretage estimering af databasestørrelse på. Der er så mange kilder til overhead, at det er svært at tage højde for, at enhver målt tabel- og indeksstørrelse, baseret på noget som dine data, vil være langt mere nøjagtige end nogen anden tilgang. Der er en grund til, at jeg ender med at besvare mange spørgsmål om præstationsrelaterede bekymringer ved at bruge pgbench til først at oprette en database i den passende størrelse.
Datagenerering er dog ikke let. Især at generere realistiske tidsstempler er altid irriterende. Og uanset hvor effektivt du tror, du har skrevet dem, tager de normalt længere tid, end du forventer at køre – og endnu længere tid at få de resulterende data ind i en database og korrekt indekseret.
Og det fortsætter med at være tilfældet, uanset hvor mange gange du har gjort dette, for selvom du gør alt rigtigt, vil Murphys lov trænge sig på for at gøre arbejdet smertefuldt uanset. Mine computere derhjemme er alle bygget af relativt billig pc-hardware. Ikke de billigste ting til rådighed – jeg har standarder – men bruger bestemt ikke den samme kvalitet, som jeg vil anbefale folk at kigge efter på en server. Denne uges datagenereringsproblem mindede om, hvorfor bedre hardware er værd, hvor meget det koster for forretningskritisk arbejde.
Efter at have genereret et par milliarder rækker af data og set importen i 10 timer, var jeg ikke glad for at få hele jobbet afbrudt på denne måde:
psql:load.sql:10: ERROR: invalid input syntax for type timestamp: "201^Q-04-14 12:17:55"
CONTEXT: COPY testdata, line 181782001, column some_timestamp: "201^Q-04-14 12:17:55"
Det viser sig, at et sted midt under skrivningen af de 250 GB testdata, jeg genererede, var en af linjernes output beskadiget. To bits vendte, og de udskrevne data var forkerte. Jeg ved ikke med sikkerhed, hvor det skete.
Hukommelse er den mest sandsynlige mistænkte. Rigtige servere bruger ECC RAM, og det er der god grund til. Hvis du overvåger et system med meget RAM, kan antallet af fejl, der stilles rettet af ECC, være chokerende. Den RAM, jeg bruger derhjemme, er god, men fejlrater på enhver hukommelse uden fejldetektions-/korrektionsfunktioner vil være højere, end du måske kunne lide - og aldrig opdaget, medmindre de sker i kode, der fører til et systemnedbrud. Datagenereringsarbejde er godt til at afsløre disse problemer, fordi det typisk sætter mindst én CPU på din server under hård belastning i potentielt dage i træk. Hvis der er ustabilitet i dit system, vil det forværre det, hvis systemet bliver varmt og ladet det gå i lang tid.
Et andet lag af beskyttelse mod denne form for korruption er at lægge kontrolsummer på data, der skrives til disken, for at beskytte mod fejl, der skriver og derefter læser dataene tilbage igen. Blokkontrolsummen udført af ZFS-filsystemet er en af de bedre implementeringer af det. I mit tilfælde, om jeg havde brugt ZFS eller ej, har måske ikke gjort nogen forskel. Hvis bitsene blev vendt, før blokkontrolsummen skete, ville jeg have skrevet uønsket data ud - med en uønsket kontrolsum, der matcher det - uanset.
Mit næste skridt var at bruge split værktøj til at tage min gigantiske fil og bryde den op i mere mundrette stykker – endnu et par timer at vente på, at det er færdigt. Så kunne jeg starte med at indlæse de gode filer, mens jeg rettede den dårlige.
I betragtning af at de resulterende filer var 13 GB hver, og min ene server har 16 GB RAM, selvom jeg kunne rette denne tastefejl ved hjælp af vi. Teoretisk set burde det være tilfældet, men jeg er begyndt at være i tvivl om, hvor længe jeg har ventet på, at filen skulle skrives ud igen bagefter:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21495 gsmith 20 0 8542m 8.3g 1544 R 98 53.0 419:56.70 vi datafile-ag
Det er 7 timer, jeg har ventet på, at denne ene stavefejl blev rettet, så jeg kan afslutte indlæsningen af testdataene. Som jeg sagde, er seriøs datagenerering aldrig let.