sql >> Database >  >> NoSQL >> Redis

Redis 10x meer geheugengebruik dan data

Welnu, dit wordt verwacht van elke efficiënte gegevensopslag:de woorden moeten in het geheugen worden geïndexeerd in een dynamische gegevensstructuur van cellen die door wijzers zijn verbonden. Grootte van de structuur metadata, pointers en geheugentoewijzer interne fragmentatie is de reden waarom de data veel meer geheugen in beslag nemen dan een bijbehorend plat bestand.

Een Redis-set wordt geïmplementeerd als een hashtabel. Dit omvat:

  • een reeks wijzers die geometrisch groeien (machten van twee)
  • een tweede array kan nodig zijn wanneer incrementeel opnieuw hashen actief is
  • enkel-gekoppelde lijstcellen die de items in de hashtabel vertegenwoordigen (3 pointers, 24 bytes per item)
  • Redis object wrappers (één per waarde) (16 bytes per item)
  • werkelijke gegevens zelf (elk voorafgegaan door 8 bytes voor grootte en capaciteit)

Alle bovenstaande maten zijn gegeven voor de 64-bits implementatie. Rekening houdend met de overhead van de geheugentoewijzer, resulteert dit in Redis die ten minste 64 bytes per set-item (bovenop de gegevens) neemt voor een recente versie van Redis met behulp van de jemalloc-allocator (>=2,4)

Redis biedt geheugenoptimalisaties voor sommige gegevenstypen, maar ze dekken geen reeksen tekenreeksen. Als je echt het geheugengebruik van sets wilt optimaliseren, zijn er trucs die je kunt gebruiken. Ik zou dit niet doen voor slechts 160 MB RAM, maar als je grotere gegevens hebt, kun je het volgende doen.

Als u de unie, intersectie, differentie-mogelijkheden van sets niet nodig hebt, kunt u uw woorden opslaan in hash-objecten. Het voordeel is dat hash-objecten automatisch kunnen worden geoptimaliseerd door Redis met zipmap als ze klein genoeg zijn. Het zipmap-mechanisme is vervangen door ziplist in Redis>=2.6, maar het idee is hetzelfde:een geserialiseerde datastructuur gebruiken die in de CPU-caches past om zowel prestaties als een compacte geheugenvoetafdruk te krijgen.

Om te garanderen dat de hash-objecten klein genoeg zijn, kunnen de gegevens worden gedistribueerd volgens een of ander hash-mechanisme. Ervan uitgaande dat u 1 miljoen items moet opslaan, kan het toevoegen van een woord op de volgende manier worden geïmplementeerd:

  • hash het modulo 10000 (aan clientzijde gedaan)
  • HMSET woorden:[hashnum] [woord] 1

In plaats van op te slaan:

words => set{ hi, hello, greetings, howdy, bonjour, salut, ... }

je kunt opslaan:

words:H1 => map{ hi:1, greetings:1, bonjour:1, ... }
words:H2 => map{ hello:1, howdy:1, salut:1, ... }
...

Om het bestaan ​​van een woord op te halen of te controleren, is het hetzelfde (hash het en gebruik HGET of HEXISTS).

Met deze strategie kan aanzienlijk geheugen worden bespaard, op voorwaarde dat de modulo van de hash is gekozen volgens de zipmap-configuratie (of ziplist voor Redis>=2.6):

# Hashes are encoded in a special way (much more memory efficient) when they
# have at max a given number of elements, and the biggest element does not
# exceed a given threshold. You can configure this limits with the following
# configuration directives.
hash-max-zipmap-entries 512
hash-max-zipmap-value 64

Let op:de naam van deze parameters is gewijzigd met Redis>=2.6.

Hier betekent modulo 10000 voor 1 miljoen items 100 items per hash-object, wat garandeert dat ze allemaal worden opgeslagen als zipmaps/ziplists.



  1. Hoe kan ik een regex-variabele gebruiken in een query voor MongoDB?

  2. Tips voor het op afstand beheren van MongoDB

  3. MongoDB-veldvolgorde en documentpositie wijzigen na update

  4. MongoDB sort()