In deze derde en laatste aflevering van "Your Worst-case Serverless Scenario" zullen we het hebben over een vervelend 'onzichtbaar proces' van DynamoDB en kort ingaan op partitie ontwerpen en tabel indexen. We sluiten deze case af met een samenvatting van onze geleerde lessen. Als je de eerste twee delen van deze serie nog niet gelezen hebt, raden we je aan om ze te bekijken, aangezien dit artikel verder bouwt op de vorige artikelen.
Last but not least, hebben we het probleem van de origin tabel die nog steeds problemen ondervindt nadat alles is opgeruimd. Meer specifiek, als je probeerde om meer items naar de tabel te schrijven, zelfs een dag later, zou je nog steeds time-out fouten krijgen. Lezen uit de tabel werkte echter prima. Het vreemde was dat je geen enkele activiteit in de metriek kon zien die aangaf dat schrijfverzoeken op dit moment werden gesmoord of dat er überhaupt een proces aan de gang was. Ook het aantal items in de tabel nam niet meer toe en auto scaling had de lees- en schrijfcapaciteiten teruggebracht tot hun normale capaciteiten. Zoals we al wisten van een ander geval, had dit te maken met het updaten van de index. Zodra je een item naar een tabel schrijft, zal dit item ook naar alle indexen van de tabel geschreven worden. Om dit te laten gebeuren, is een read op de basistabel en een write op de doelindexen nodig.
Onze auto scaling opties waren ingesteld op zowel lees- als schrijfcapaciteit afzonderlijk met dezelfde instellingen toegepast op alle Global Secondary Indexes (we hadden slechts één index). Dat betekende dat tijdens het massaal schrijven op de basistabel, de schrijfcapaciteiten van de basistabel en doelindex omhoog schoten, maar de leescapaciteit gelijk bleef. Met andere woorden: de items konden aanvankelijk naar de basistabel worden geschreven, maar daarna merkte de index dat hij het niet kon bijbenen, omdat, hoewel de schrijfcapaciteit van de index was opgeschaald, de leescapaciteit van de basistabel te laag was. Om het nog erger te maken, bleek de opgeschaalde schrijfcapaciteit ook onvoldoende te zijn, omdat de partitiesleutel van de index zeer slecht gekozen was. In dit specifieke geval hadden alle geschreven items op de basistabel verschillende partitiesleutelwaarden, maar dezelfde partitiesleutelwaarde op de index, wat in ons geval 56 miljoen items waren! Volgens de officiële AWS documentatie over het ontwerpen van partitiesleutels om je werk gelijkmatig te verdelen:
"Het partitiesleutelgedeelte van de primaire sleutel van een tabel bepaalt de logische partities waarin de gegevens van een tabel worden opgeslagen. Dit heeft op zijn beurt invloed op de onderliggende fysieke partities. De voorziene I/O-capaciteit voor de tabel wordt gelijk verdeeld over deze fysieke partities. Daarom kan een partitiesleutelontwerp dat I/O-verzoeken niet gelijkmatig verdeelt, 'hot' partities creëren die resulteren in throttling en inefficiënt gebruikmaken van uw I/O-capaciteit.
In het kort: een zeer slecht gekozen index' partitie sleutel en de scheiding van lees- en schrijfcapaciteit auto scaling leidden tot een index die simpelweg niet alle schrijfacties kon bijhouden die op de basistabel werden uitgevoerd. Het nare neveneffect was dat op de achtergrond de index nog steeds beetje bij beetje gevuld werd, maar er is geen enkele metric die je laat zien hoe het proces verloopt. Als iemand een idee heeft of en hoe we dit "onzichtbare proces" verder kunnen inspecteren en/of beïnvloeden, laat het ons weten in de commentaren, want dat zou zeer nuttig zijn om een beter begrip te krijgen van DynamoDB's achtergrond processen.
Onze beste oplossing om deze puinhoop op te ruimen was om een snapshot te nemen van de tabel van net voor dit alles begon en de tabel in die toestand te herstellen.
Hoewel wij nogal wat problemen hebben ondervonden toen dit alles gebeurde, was het ook het perfecte geval om van te leren. Ik denk dat het goed is deze zaak af te sluiten met een opsomming van enkele van de belangrijkste dingen die we ervan hebben geleerd.
En met de grootste geleerde lessen samengevat, sluit deze zaak. We streven er naar om nooit meer problemen op zo'n grote schaal te ervaren en we hopen dat jij dat ook nooit hoeft te doen. Al met al is deze case rijk geweest aan leermomenten voor ons en maakt het ons betere Serverless ontwikkelaars op de lange termijn. We hopen dat je genoten hebt van de artikelen en als je nog vragen of opmerkingen hebt, voel je vrij om ze te stellen.