feil måte Å skalere Opp Cassandra DB når sekundære indekser er på plass
Cassandra Er min favoritt (ikke administrert) database av mange grunner: Den har ikke et enkelt feilpunkt (SPoF), støtter multi-region, bra for lese og skrive ops, fleksibel om lese og skrive konsistensnivåer, skalaer lineært og ikke for komplisert å administrere for den daglige driften.
som alle databaser, bør Du bruke Cassandra basert på datatilgangsmønstrene dine, så hvis du trenger en fleksibel database for ad hoc-spørringer eller tilpasningsdyktig nok til stadig endringer i databasemodellen, bør du vurdere andre alternativer.
Cassandra er en kolonne-orientert DB og det er veldig kraftig når du har dine data spørringer allerede definert. Datastax, selskapet som støtter Cassandra, anbefaler at du bør starte med å designe dine spørsmål og deretter datamodellen Din I Cassandra. Til tross for kolonnestrukturen støtter Cassandra mange datastrukturer som en kolonne (r) type, for Eksempel Kart.
Cassandra Er en primærnøkkeldatabase, noe som betyr at dataene dine er vedvarende og organisert rundt en klynge basert på hashverdien (partisjonsnøkkelen) til primærnøkkelen. For tabeller som har mer ENN EN PK, Vurderer Cassandra bare den første delen av PK som det er partisjonsnøkkel. Se mer om sammensatte nøkler her.
for å være tydeligere, la oss komme tilbake til En Av De viktigste egenskapene Til En Cassandra DB: det er arkitektur og det faktum at det ikke har En SPoF.
En Cassandra-klynge består av noder (3 eller flere) og disse nodene komponerer sammen en ring av noder:
hver node på En Cassandra-klynge fungerer “uavhengig”, men forskjellige noder kan lagre de samme dataene tilsvarende replikasjonsfaktoren (RF) konfigurasjonen konfigurert for klyngen.
For å vite hvor (hvilken node) dataene dine vedvarer, Bruker Cassandra hash-verdien (token) beregnet gjennom en konsekvent hash-funksjon ved HJELP AV pk-kolonnen i en gitt tabell.
når du kjører en spørring, vil koordinatornoden (normalt den nærmeste av applikasjonsinstansene dine) se etter hvilke noder i en ring som har dataene dine, på den måten hvis en node er nede av en eller annen grunn, kan en annen node betjene dataene dine (RF ≥2). Det er magien om en mesterløs tilnærming, hvor hver knute i en ring er lik når det gjelder å lese og skrive.
dette konseptet OM PK og replikasjonsfaktoren er svært viktig å forstå om hvordan Du skalerer Cassandra-klyngen når applikasjonen din er under høye belastningsforhold.
Sekundære Indekser
Cassandra har også begrepet sekundære indekser. I relasjonsdatabaser kan du ha mange indekser i en gitt tabell, kostnaden for har en sekundær indeks er knyttet til skriveoperasjoner, ikke for leseoperasjoner. I Cassandra er dette ikke sant.
Sekundære indekser I Cassandra kan være nyttige og fristende når datamodellen din endres, og du må spørre basert på en ny kolonne.
På den måten, med en sekundær indeks, kan du kjøre en spørring slik:
VELG * fra my_table DER SECONDARY_INDEX = ‘verdi’;
problemet Med Å bruke En Sekundær Indeks
Tenk deg scenariet: du er I En Blackfriday / CyberMonday og Cassandra-klyngen din lider av topphendelser, og du må legge til flere noder for å skalere databasen din, balansere bedre trafikken din og … overleve. Greit, ikke sant?
Normalt er Det en normal situasjon i en svært skalerbar applikasjon. Men hva om søknaden din kjører spørringer ved hjelp av en sekundær indeks?
Ja, du har poenget.
Husk Da jeg sa At Cassandra distribuerer data i en ring ved hjelp av partisjonsnøkkelen? Dette skjer allerede, men problemet er når du introduserer en sekundær indeks i spørringen din. Sekundære indekser er IKKE EN del av en partisjonsnøkkel, Og Cassandra vet om hvor dataene dine lever gjennom partisjonsnøkkelen. Når Du kjører en spørring som bruker denne typen indeks, Hva Cassandra gjør er ute etter hver node i ringen prøver å tilfredsstille søket.
Ekte Scenario
under En Blackfriday var våre applikasjoner med høye belastninger. Mange og mange kunder som ønsker å dra nytte av de store rabatter som Tilbys Av En Blackfriday-hendelse.
Vi tok en titt på VÅR APM og all analysen førte oss til vår utholdenhet, i dette tilfellet En Cassandra DB. Vi har lange perioder med ventetid, men ikke for hver forespørsel, bare for noen.
Prøver å holde ting tilbake til normal tilstand igjen, vår første manøver var å legge til flere noder Til Vår Cassandra klynge.
vi la til, og vi lider fortsatt av latensproblemer. Spørsmålet var: hvorfor skjer dette fortsatt?
Vi tok feil. Det var en forenklet konklusjon, og vi tok ikke vare på en veldig viktig detalj: denne oppførselen skjedde ikke i alle forespørsler, men i noen av dem.
hvis du tenkte på den sekundære indeksen, bingo! Det var akkurat problemet.
Å Legge til noder ville aldri løse problemet, fordi problemet ikke var relatert til alle spørringene som kom inn i databasen, var problemet i noen, og de var de virkelige som degraderte databasens ytelse. Det var Helt En Pareto ting.
Detaljering av problemet og hvordan vi reduserer det
På et øyeblikk før Blackfriday-hendelsen, måtte vi endre datamodellen vår. Vi regionaliserte vår søknad og kundens region begynte å være en viktig ting for oss, vi trengte å spørre data basert på et produkt eller en region.
Når Vi Ser tilbake og forbinder prikkene, kunne vi innse at vi var veldig dyrebare om implementeringen som vi ønsket å gjenspeile denne nye oppførselen, ikke bare I API-Laget (new query param), men også i måten vi fikk tilgang til dataene i Cassandra.
Og hvorfor var vi så dyrebare? Fordi selv vurderer at vår spørringstid ikke økte så mye, gjorde vi endringen.
denne implementeringen økte ikke bare spørringen vår ved å bruke en sekundær indeks, men genererte også flere problemer i henhold til At Vi skalerte Opp Cassandras infrastruktur. Da vi la til flere noder i klyngen vår, betydde flere noder å slå opp for å finne dataene, og dermed økte problemet eksponentielt.
for å redusere problemet, var det vi gjorde å ta tilbake antall noder som vi tidligere hadde og økt replikasjonsfaktoren for flertallet av våre noder i klyngen.
vi endret også vårt lesekonsistensnivå for å være mindre konsistent. Vi brukte * QUORUM og i stedet endret VI TIL EN. Dette hjalp oss med å senke lasten i noder.
da vi frøs våre applikasjoner dager før arrangementet, visste vi at vi ikke hadde nye data (skriveoperasjoner) og dataene ville være konsistente i sin nåværende tilstand.
dagene etter OG DB-modellløsningen
som en del av den endelige løsningen måtte vi (re)tenke på databasemodellen vår og rulle tilbake endringene som vi gjorde som en begrensningsbane under arrangementet.
før hendelsen brukte vi produkt-ID (PID)som partisjonsnøkkel, noe som var en god beslutning, siden PID har gode egenskaper til Å være EN PK på grunn av sin natur om å være et sekvensielt tall (høy kardinalitet), og på den måten sprer dataene jevnt rundt klyngen.
Om det nye feltet “region” bruker Vi Datatypen Cassandra collections og brukte Et Kart for hver region som en kolonne i produkttabellen vår.
Sekundære Indekser er alltid en dårlig ide?
det korte svaret er nei.
Forklarer litt bedre, det finnes to typer indekser i Cassandra: lokale og globale indekser.
en lokal indeks som navnet sier er en slags indeks som bare eksisterer lokalt, det betyr i en node. Når Du oppretter en sekundær indeks, Oppretter Cassandra en ny (skjult) tabell der sekundæret blir en primærnøkkel i denne tabellen. Synligheten til denne nye tabellen er i form av en node, ikke en ring (klynge). Det er tilfelle av sekundære indekser.
på den annen side har en global indeks ringsynlighet gjennom partisjonsnøkkelen, Så Cassandra vet hvor du data er i en ring gjennom den partisjonsnøkkelen.
Sekundære indekser kan være et alternativ, når du har i en spørring både: primære og sekundære indekser. I så fall Vet Cassandra hvor dataene dine ligger (hvilken node) gjennom partisjonsnøkkelen, og ser deretter opp det lokale tabellen i noden som refererer til (lokale) sekundære indekser.
Det er også noen andre nyanser om sekundære indekser som er veldig godt forklart her, men det beste er å unngå dem ved å denormalisere datamodellen din.