Cassandra Indexing :The Good, The Bad and The Ugly

innenfor NoSQL er driften av indeksering, henting og søking etter informasjon nært knyttet til de fysiske lagringsmekanismene. Det er viktig a huske at rader lagres over verter, men en enkelt rad lagres pa en enkelt vert. (Med kopier) Kolonner familier lagres i sortert rekkefølge, noe som gjør spørring et sett med kolonner effektiv (forutsatt at du spenner over rader).

The Bad : Partisjonering

En av de tøffe tingene å bli vant til i begynnelsen er at uten indekser spørringer som spenner over rader kan (veldig) være dårlig. Tenker tilbake til vår lagringsmodell, men det er ikke overraskende. Strategien Som Cassandra bruker til å distribuere radene over verter kalles Partisjonering.

Partisjonering er handlingen med å kutte opp rekkevidden av rowkeys som tilordner dem til «token ring», som også tildeler ansvar for et segment (dvs.partisjon) av rowkey-serien til hver vert. Du har sikkert sett dette nar du initialiserte klyngen din med et»token». Token gir verten en plassering langs token-ringen, som tildeler ansvar for en del av token-serien. Partisjonering er handlingen med å kartlegge rowkey inn i token-området.

det er to primære partisjonere: Tilfeldig Og Orden Bevare. De er passende navn. RandomPartitioner hashes rowkeys til tokens. Med RandomPartitioner er token en hash av rowkey. Dette gjør en god jobb med jevnt å distribuere dataene dine over et sett med noder, men gjør spørring av en rekke rowkey-rom utrolig vanskelig. Fra bare en «start rowkey» – verdi og en «end rowkey» – verdi, Kan Cassandra ikke bestemme hvilket område av tokenplassen du trenger. Det trenger i hovedsak å utføre en «tabellskanning» for å svare på spørringen, og en «tabellskanning» i Cassandra er dårlig fordi den må gå til hver maskin (mest sannsynlig ALLE maskiner hvis du har en god hashfunksjon) for å svare på spørringen.

Nå, til den store kostnaden for jevn datadistribusjon, kan Du ansette OrderPreservingPartitioner (OPP). Jeg er* ikke * ned med OPP. OPP bevarer orden som det oversetter rowkeys til tokens. Nå, gitt en start rowkey verdi og en slutt rowkey verdi, Cassandra* kan * bestemme nøyaktig hvilke verter har dataene du leter etter. Den beregner startverdien til et token sluttverdien til et token, og velger og returnerer alt i mellom. MEN ved å bevare orden, med mindre rowkeys er jevnt fordelt over rommet, vil dine tokens heller ikke være, og du får en skrå klynge, noe som øker kostnadene ved konfigurasjon og administrasjon av klyngen. (ikke verdt det)

Det Gode: Sekundære Indekser

Cassandra gir en innfødt indekseringsmekanisme I Sekundære Indekser. Sekundære Indekser arbeide ut av kolonnene verdier. Du erklærer en sekundær indeks på En Kolonnefamilie. Datastax har god dokumentasjon på bruken. Under panseret, Cassandra opprettholder en «skjult kolonne familie» som indeksen. (Se Ed Anuffs presentasjon for detaljer) Siden Cassandra ikke opprettholder kolonneverdiinformasjon i en node, og sekundære indekser er på kolonneverdi (i stedet for rowkeys), må en spørring fortsatt sendes til alle noder. I tillegg er sekundære indekser ikke anbefalt for høy kardinalitetssett. Jeg har ikke sett ennå, men jeg antar at dette er på grunn av datamodellen som brukes i «skjult kolonnefamilie». Hvis den skjulte kolonnefamilien lagrer en rad per unik verdi (med rowkeys som kolonner), betyr det at du skanner radene for å finne ut om de er innenfor området i spørringen.
Fra Eds presentasjon:

  • Ikke anbefalt for høye kardinalitetsverdier (dvs.tidsstempler,fødselsdager,søkeord,etc.)
  • Krever minst en likestillingssammenligning i en spørring-ikke bra for mindre enn / større enn / utvalgsspørringer
  • Usorterte-resultatene er i token-rekkefølge, ikke spørringsverdiordre
  • Begrenset til søk på datatyper, Forstår Cassandra

med alt som er sagt, fungerer sekundære indekser ut av boksen, og vi har hatt god suksess med å bruke dem på enkle verdier.

Den Stygge: Gjør-Det-Selv (DIY) / Brede Rader

nå er skjønnhet i øyets øye. En av de vakre tingene Om NoSQL er enkelheten. Konstruksjonene er enkle: Nøkkelrom, Kolonnefamilier, Rader og Kolonner. Å holde det enkelt betyr imidlertid noen ganger at du må ta ting i egne hender.

Dette er tilfellet med brede radindekser. Utnytte Cassandra lagring modell, det er lett å bygge dine egne indekser hvor hver rad-tasten blir en kolonne i indeksen. Dette er noen ganger vanskelig å få hodet rundt, men kan forestille oss at vi har en sak der vi ønsker å velge alle brukere i et postnummer. Hovedbrukerens kolonnefamilie er tastet på userid, postnummer er en kolonne på hver bruker rad. Vi kunne bruke sekundære indekser, men det er ganske mange postnummer. I stedet kunne vi opprettholde en kolonnefamilie med en enkelt rad kalt «idx_zipcode». Vi kunne da skrive kolonner i denne raden av skjemaet «zipcode_userid». Siden kolonnene er lagret i sortert rekkefølge, er det raskt å spørre etter alle kolonner som starter med «18964» (f.eks. vi kunne bruke 18964_ og 18964_zzzzzz som start-og sluttverdier).

en åpenbar ulempe ved denne tilnærmingen er at rader er selvstendige på en vert. (igjen unntatt replikaer) dette betyr at alle spørringer kommer til å treffe en enkelt node. Jeg har ennå ikke funnet et godt svar på dette.

I TILLEGG, OG IMHO, er DEN styggeste delen AV DIY wide-row indeksering fra et klientperspektiv. I vår implementering har vi gjort vårt beste for å være språk agnostiker på klientsiden, slik at folk kan velge det beste verktøyet for jobben å samhandle med dataene i Cassandra. MED den mentaliteten presenterer DIY-indeksene noen problemer. Wide-rader bruker ofte sammensatte nøkler(tenk om du hadde en idx_state_zip, som vil tillate deg å spørre etter stat da zip). Selv om det er» innfødt » støtte for sammensatte nøkler, implementerer alle klientbibliotekene sin egen versjon av Dem (Hector, Astyanax og Thrift). Dette betyr at klienten som trenger å spørre data, må ha den ekstra logikken til å først spørre indeksen, og i tillegg må alle klienter konstruere komposittnøkkelen på samme måte.

Gjør Det Bedre…

av denne grunn har vi besluttet å frigjøre to åpen kildekode-prosjekter som bidrar til å presse denne logikken til serversiden. Det første prosjektet Er Cassandra-Triggers. Dette gjør at du kan feste asynkrone aktiviteter for å skrive I Cassandra. (en slik aktivitet kan være indeksering) Vi har også gitt Ut Cassandra-Indeksering. Den støtter bare UT8Types i indeksen), men hensikten er å gi en generisk server-side mekanisme som indekserer data som den er skrevet Til Cassandra. Ved å bruke samme server-side teknikk som vi brukte I Cassandra-Indeksering, konfigurerer du bare kolonnene du vil indeksere, og aop-koden gjør resten mens du skriver til målet CF. Som alltid er spørsmål, kommentarer og tanker velkomne. (spesielt hvis jeg er utenfor basen et sted)

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.