Ik zal proberen je vraag te beantwoorden, maar ik zal beginnen met iets dat er in eerste instantie misschien vreemd uitziet:als je niet geïnteresseerd bent in Redis internals, zou het je niets kunnen schelen over hoe gegevenstypen intern worden geïmplementeerd. Dit heeft een simpele reden:voor elke Redis-bewerking vindt u de tijdcomplexiteit in de documentatie en, als u de reeks bewerkingen en de tijdcomplexiteit hebt, is het enige andere dat u nodig hebt een idee over geheugengebruik (en omdat we doen veel optimalisaties die kunnen variëren afhankelijk van de gegevens, de beste manier om deze laatste cijfers te krijgen, is door een paar triviale tests uit de echte wereld uit te voeren).
Maar aangezien je het vroeg, hier is de onderliggende implementatie van elk Redis-gegevenstype.
- Tekens worden geïmplementeerd met behulp van een C-bibliotheek met dynamische tekenreeksen, zodat we niet (asymptotisch gesproken) betalen voor toewijzingen in toevoegbewerkingen. Op deze manier hebben we bijvoorbeeld O(N)-appends in plaats van kwadratisch gedrag.
- Lijsten worden geïmplementeerd met gekoppelde lijsten.
- Sets en Hashes worden geïmplementeerd met hash-tabellen.
- Gesorteerde sets zijn geïmplementeerd met skip-lijsten (een eigenaardig type uitgebalanceerde bomen).
Maar wanneer lijsten, sets en gesorteerde sets klein zijn in aantal items en de grootte van de grootste waarden, wordt een andere, veel compactere codering gebruikt. Deze codering verschilt voor verschillende typen, maar heeft als kenmerk dat het een compacte blob met gegevens is die vaak voor elke bewerking een O(N)-scan afdwingt. Aangezien we dit formaat alleen voor kleine objecten gebruiken, is dit geen probleem; het scannen van een kleine O(N)-blob is cache-onbewust dus praktisch gezien is het erg snel, en wanneer er te veel elementen zijn, wordt de codering automatisch overgeschakeld naar de oorspronkelijke codering (gekoppelde lijst, hash, enzovoort).
Maar uw vraag ging niet alleen over interne onderdelen, uw punt was Welk type moet u gebruiken om wat te bereiken? .
Snaren
Dit is het basistype van alle typen. Het is een van de vier typen, maar is ook het basistype van de complexe typen, omdat een lijst een lijst met tekenreeksen is, een set een reeks tekenreeksen, enzovoort.
Een Redis-string is een goed idee in alle voor de hand liggende scenario's waarin u een HTML-pagina wilt opslaan, maar ook wanneer u wilt voorkomen dat uw reeds gecodeerde gegevens worden geconverteerd. Dus als u bijvoorbeeld JSON of MessagePack heeft, kunt u objecten gewoon als strings opslaan. In Redis 2.6 kun je zelfs dit soort objectserver-side manipuleren met Lua-scripts.
Een ander interessant gebruik van strings zijn bitmaps, en in het algemeen random access arrays van bytes, aangezien Redis commando's exporteert om toegang te krijgen tot willekeurige reeksen van bytes, of zelfs enkele bits. Bekijk bijvoorbeeld deze goede blogpost:Fast Easy realtime metrics met Redis.
Lijsten
Lijsten zijn goed wanneer u waarschijnlijk alleen de uitersten van de lijst aanraakt:dichtbij de staart of dichtbij de kop. Lijsten zijn niet erg goed om dingen te pagineren, omdat willekeurige toegang traag is, O(N). Dus goed gebruik van lijsten zijn gewone wachtrijen en stapels, of het verwerken van items in een lus met RPOPLPUSH met dezelfde bron en bestemming om een ring te "roteren" aantal items.
Lijsten zijn ook goed als we gewoon een afgetopte verzameling van N items willen maken waar meestal we hebben alleen toegang tot de bovenste of onderste items, of wanneer N klein is.
Sets
Sets zijn een ongeordende gegevensverzameling, dus ze zijn elke keer dat je een verzameling items hebt goed en het is erg belangrijk om op een zeer snelle manier te controleren op het bestaan of de grootte van de verzameling. Een ander cool aspect van sets is de ondersteuning voor het gluren of knallen van willekeurige elementen (SRANDMEMBER- en SPOP-commando's).
Sets zijn ook goed om relaties weer te geven, bijvoorbeeld "Wat zijn vrienden van gebruiker X?" enzovoorts. Maar andere goede datastructuren voor dit soort dingen zijn gesorteerde sets, zoals we zullen zien.
Sets ondersteunen complexe bewerkingen zoals kruispunten, vakbonden, enzovoort, dus dit is een goede gegevensstructuur om Redis op een "computationele" manier te gebruiken, wanneer u gegevens heeft en u transformaties op die gegevens wilt uitvoeren om wat output te verkrijgen.
Kleine sets worden op een zeer efficiënte manier gecodeerd.
Hashes
Hashes zijn de perfecte datastructuur om objecten weer te geven, samengesteld uit velden en waarden. Velden van hashes kunnen ook atomair worden verhoogd met behulp van HINCRBY. Wanneer je objecten hebt zoals gebruikers, blogposts of een ander soort item , hashes zijn waarschijnlijk de beste keuze als u uw eigen codering zoals JSON of iets dergelijks niet wilt gebruiken.
Houd er echter rekening mee dat kleine hashes zeer efficiënt worden gecodeerd door Redis, en u kunt Redis vragen om afzonderlijke velden op een zeer snelle manier atomair te GET, SET of te verhogen.
Hashes kunnen ook worden gebruikt om gekoppelde datastructuren weer te geven met behulp van verwijzingen. Controleer bijvoorbeeld de implementatie van opmerkingen op lamernews.com.
Gesorteerde sets
Gesorteerde sets zijn de enige andere gegevensstructuren, naast lijsten, om geordende elementen te behouden . Met gesorteerde sets kun je een aantal leuke dingen doen. U kunt bijvoorbeeld allerlei soorten Top Something . hebben lijsten in uw webapplicatie. Topgebruikers op score, topposts op paginaweergaven, top wat dan ook, maar een enkele Redis-instantie ondersteunt tonnen invoeg- en get-top-elementen-bewerkingen per seconde.
Gesorteerde sets kunnen, net als gewone sets, worden gebruikt om relaties te beschrijven, maar ze stellen je ook in staat om de lijst met items te pagineren en de volgorde te onthouden. Als ik me bijvoorbeeld vrienden van gebruiker X herinner met een gesorteerde set, kan ik ze gemakkelijk onthouden in volgorde van geaccepteerde vriendschap.
Gesorteerde sets zijn goed voor wachtrijen met prioriteit.
Gesorteerde sets zijn als krachtigere lijsten waarbij het invoegen, verwijderen of ophalen van bereiken uit het midden van de lijst altijd snel gaat. Maar ze gebruiken meer geheugen en zijn O(log(N)) datastructuren.
Conclusie
Ik hoop dat ik wat informatie in dit bericht heb gegeven, maar het is veel beter om de broncode van lamernews te downloaden van http://github.com/antirez/lamernews en te begrijpen hoe het werkt. Binnen Lamer News worden veel datastructuren van Redis gebruikt en er zijn veel aanwijzingen over wat te gebruiken om een bepaalde taak op te lossen.
Sorry voor grammaticale typefouten, het is hier middernacht en te moe om het bericht te bekijken;)