Jeg vil prøve at besvare dit spørgsmål, men jeg starter med noget, der kan se mærkeligt ud i starten:Hvis du ikke er interesseret i Redis internals, bør du være ligeglad om hvordan datatyper implementeres internt. Dette er af en simpel grund:for hver Redis-operation vil du finde tidskompleksiteten i dokumentationen, og hvis du har operationssættet og tidskompleksiteten, er det eneste andet, du behøver, et fingerpeg om hukommelsesbrug (og pga. vi laver mange optimeringer, der kan variere afhængigt af data, den bedste måde at få disse sidstnævnte tal på er at lave et par trivielle tests fra den virkelige verden).
Men siden du spurgte, er her den underliggende implementering af hver Redis-datatype.
- Strenge implementeres ved hjælp af et C dynamisk strengbibliotek, så vi ikke betaler (asymptotisk set) for allokeringer i tilføjelsesoperationer. På denne måde har vi for eksempel O(N) tilføjelser i stedet for at have kvadratisk adfærd.
- Lister er implementeret med linkede lister.
- Sæt og Hashes er implementeret med hash-tabeller.
- Sorterede sæt er implementeret med overspringslister (en ejendommelig type af balancerede træer).
Men når lister, sæt og sorterede sæt er små i antal elementer og størrelse af de største værdier, bruges en anden, meget mere kompakt kodning. Denne kodning er forskellig for forskellige typer, men har den funktion, at det er en kompakt klat data, der ofte fremtvinger en O(N)-scanning for hver operation. Da vi kun bruger dette format til små objekter, er dette ikke et problem; scanning af en lille O(N)-klat er cache uvidende så praktisk talt er det meget hurtigt, og når der er for mange elementer, skiftes kodningen automatisk til den oprindelige kodning (sammenkædet liste, hash osv.).
Men dit spørgsmål handlede egentlig ikke kun om det indre, din pointe var Hvilken type skal man bruge til at opnå hvad? .
Strenge
Dette er basistypen for alle typerne. Det er en af de fire typer, men er også basistypen for de komplekse typer, fordi en liste er en liste over strenge, et sæt er et sæt af strenge og så videre.
En Redis-streng er en god idé i alle de åbenlyse scenarier, hvor du vil gemme en HTML-side, men også når du vil undgå at konvertere dine allerede kodede data. Så hvis du for eksempel har JSON eller MessagePack, kan du bare gemme objekter som strenge. I Redis 2.6 kan du endda manipulere denne slags objektserverside ved hjælp af Lua-scripts.
En anden interessant brug af strenge er bitmaps og generelt random access-arrays af bytes, da Redis eksporterer kommandoer for at få adgang til tilfældige bytes-områder eller endda enkelte bits. Tjek for eksempel dette gode blogindlæg:Hurtig Nem realtidsmåling ved hjælp af Redis.
Lister
Lister er gode, når du sandsynligvis kun rører ved yderpunkterne af listen:nær halen eller nær hovedet. Lister er ikke særlig gode til at paginere ting, fordi tilfældig adgang er langsom, O(N). Så god brug af lister er almindelige køer og stakke, eller behandling af elementer i en loop ved hjælp af RPOPLPUSH med samme kilde og destination for at "rotere" en ring af varer.
Lister er også gode, når vi bare vil skabe en begrænset samling af N elementer, hvor normalt vi får kun adgang til de øverste eller nederste elementer, eller når N er lille.
Sæt
Sæt er en uordnet dataindsamling, så de er gode hver gang du har en samling af varer, og det er meget vigtigt at tjekke for eksistensen eller størrelsen af samlingen på en meget hurtig måde. En anden cool ting ved sæt er støtte til at kigge eller poppe tilfældige elementer (SRANDMEMBER og SPOP kommandoer).
Sæt er også gode til at repræsentere relationer, f.eks. "Hvad er venner af bruger X?" og så videre. Men andre gode datastrukturer for denne slags ting er sorterede sæt, som vi vil se.
Sæt understøtter komplekse operationer som skæringspunkter, fagforeninger og så videre, så dette er en god datastruktur til at bruge Redis på en "beregningsmæssig" måde, når du har data og du vil udføre transformationer på disse data for at opnå noget output.
Små sæt er kodet på en meget effektiv måde.
Hashes
Hashes er den perfekte datastruktur til at repræsentere objekter, sammensat af felter og værdier. Felter med hash kan også øges atomisk ved hjælp af HINCRBY. Når du har objekter såsom brugere, blogindlæg eller en anden form for emne , hashes er sandsynligvis vejen at gå, hvis du ikke ønsker at bruge din egen kodning som JSON eller lignende.
Husk dog, at små hashes kodes meget effektivt af Redis, og du kan bede Redis om at atomisk GET, SET eller øge individuelle felter på en meget hurtig måde.
Hashes kan også bruges til at repræsentere sammenkædede datastrukturer ved hjælp af referencer. Tjek f.eks. lamernews.coms implementering af kommentarer.
Sorterede sæt
Sorterede sæt er de eneste andre datastrukturer, udover lister, til at vedligeholde ordnede elementer . Du kan lave en række fede ting med sorterede sæt. For eksempel kan du have alle slags Top Noget lister i din webapplikation. Topbrugere efter score, topindlæg efter sidevisninger, top uanset hvad, men en enkelt Redis-forekomst vil understøtte tonsvis af indsættelses- og get-top-elements-operationer pr. sekund.
Sorterede sæt kan, ligesom almindelige sæt, bruges til at beskrive relationer, men de giver dig også mulighed for at paginere listen over varer og huske rækkefølgen. For eksempel, hvis jeg husker venner af bruger X med et sorteret sæt, kan jeg nemt huske dem i rækkefølge efter accepteret venskab.
Sorterede sæt er gode til prioriterede køer.
Sorterede sæt er som mere kraftfulde lister, hvor det altid er hurtigt at indsætte, fjerne eller hente intervaller fra midten af listen. Men de bruger mere hukommelse og er O(log(N)) datastrukturer.
Konklusion
Jeg håber, at jeg har givet noget info i dette indlæg, men det er langt bedre at downloade kildekoden til lamernews fra http://github.com/antirez/lamernews og forstå, hvordan det virker. Mange datastrukturer fra Redis bruges inde i Lamer News, og der er mange spor om, hvad man skal bruge til at løse en given opgave.
Beklager grammatiske stavefejl, det er midnat her og for træt til at gennemgå indlægget;)