sql >> Databáze >  >> NoSQL >> Redis

Redis 10x více využití paměti než dat

To se očekává od každého efektivního úložiště dat:slova musí být indexována v paměti v dynamické datové struktuře buněk spojených ukazateli. Velikost metadat struktury, ukazatelů a vnitřní fragmentace alokátoru paměti je důvodem, proč data zabírají mnohem více paměti než odpovídající plochý soubor.

Sada Redis je implementována jako hashovací tabulka. To zahrnuje:

  • Pole geometricky rostoucích ukazatelů (mocniny dvou)
  • Pokud je aktivní přírůstkové přehašování, může být vyžadováno druhé pole
  • buňky seznamu s jedním odkazem představující položky v tabulce hash (3 ukazatele, 24 bajtů na položku)
  • Obálky objektů Redis (jedna na hodnotu) (16 bajtů na položku)
  • samotná skutečná data (každý z nich má předponu 8 bajtů pro velikost a kapacitu)

Všechny výše uvedené velikosti jsou uvedeny pro 64bitovou implementaci. Při zohlednění režie alokátoru paměti to má za následek, že Redis zabere alespoň 64 bajtů na položku sady (navrch k datům) pro nejnovější verzi Redis pomocí alokátoru jemalloc (>=2.4)

Redis poskytuje optimalizace paměti pro některé typy dat, ale nepokrývají sady řetězců. Pokud opravdu potřebujete optimalizovat spotřebu paměti sad, existují triky, které můžete použít. Neudělal bych to pro pouhých 160 MB RAM, ale pokud máte větší data, můžete udělat toto.

Pokud nepotřebujete sjednocovací, průnikové, rozdílové schopnosti množin, můžete svá slova ukládat do hashovacích objektů. Výhodou je, že hash objekty může Redis automaticky optimalizovat pomocí zipmap, pokud jsou dostatečně malé. Mechanismus zipmap byl v Redis>=2.6 nahrazen ziplistem, ale myšlenka je stejná:použití serializované datové struktury, která se vejde do mezipaměti CPU, aby se dosáhlo výkonu i kompaktní paměti.

Aby bylo zajištěno, že hash objekty jsou dostatečně malé, data by mohla být distribuována podle nějakého hashovacího mechanismu. Za předpokladu, že potřebujete uložit 1 milion položek, přidání slova by mohlo být implementováno následujícím způsobem:

  • hash it modulo 10000 (provedeno na straně klienta)
  • HMSET slova:[hashnum] [slovo] 1

Místo uložení:

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

můžete uložit:

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

Chcete-li načíst nebo zkontrolovat existenci slova, je to stejné (hashujte je a použijte HGET nebo HEXISTS).

S touto strategií lze dosáhnout významné úspory paměti za předpokladu, že modul hash je zvolen podle konfigurace zipmap (nebo ziplistu pro 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

Pozor:název těchto parametrů se změnil s Redis>=2.6.

Zde modulo 10000 pro 1M položek znamená 100 položek na hash objekty, což zaručí, že všechny budou uloženy jako zipmapy/ziplisty.



  1. MongoDB 'nelze najít index pro dotaz $geoNear'

  2. Jak se aerospike liší od jiných databází nosql klíč-hodnota?

  3. Redis transakce a dlouhotrvající Lua skripty

  4. Jaký je rozdíl mezi id a _id v mongoose?