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

Seznamte se s databází Redis:Iterace přes klíče

Jednou z věcí, která často mate uživatele, kteří znají jiné databáze, když zkoušejí Redis, je nedostatečná viditelnost do databáze:Neexistuje žádná sada tabulek nebo kolekcí, které by vidíte, jen prostý, plochý klíčový prostor, který by (potenciálně) mohl mít miliony klíčů. Schopnost levně iterovat tento klíčový prostor se tak stává velmi důležitou pro seznámení se s obsahem databáze.

Iterace přes klíčový prostor Redis má i další důležité případy použití, které vás napadnou:

  • sbírání odpadu nebo čištění klíčů, které odpovídají určitému vzoru
  • přesun dat a změny schématu nebo přesun určité sady klíčů do jiné datové struktury
  • ladění, vzorkování dat, opravy dat nebo vyhledání a oprava všech klíčů, které byly zpackány nedávnou změnou

V tomto příspěvku se podrobně ponoříme do různých klíčových možností iterací prostoru dostupných v Redis.

O(N) iterátory:KEYS

Příkaz Redis KEYS vrátí všechny klíče v databázi, které odpovídají vzoru (nebo všechny klíče v prostoru klíčů). Podobný příkaz pro načtení všech polí uložených v hash je HGETALL a pro veškeré načtení členů SMEMBERS. Samotné klíče v Redis jsou uloženy ve slovníku (aka hash table). Příkaz KEYS funguje tak, že prochází tento slovník a odesílá vše, co odpovídá vzoru, jako jedinou odpověď pole. Ostatní příkazy fungují podobně.

Výkon takové operace závisí na velikosti kolekce, tj. O(N). V produkčním prostředí s velkým počtem klíčů se proto zásadně nedoporučuje používat KLÍČE. Redis, který je jedním vláknem, se během této iterace zablokuje, čímž zablokuje další operace. Klíče KEYS by se tedy měly používat pouze pro ladění a další zvláštní příležitosti, kde nezáleží na výkonu (například když byla databáze uvedena do režimu offline kvůli použití opravy dat). Další důležitou věcí, kterou je třeba si pamatovat u tohoto algoritmu, je, že odesílá všechny odpovídající klíče společně jako jedinou odpověď. To může být mimořádně výhodné, když je klíčový prostor malý, ale ve velkém prostoru klíčů způsobí více problémů. KEYS je však oblíbený příkaz mezi vývojáři v jejich vlastních vývojářských prostředích.

KEYS in Action:

127.0.0.1:6379[1]> MSET jeden 1 dva 2 tři 3 čtyři 4OK# Všechny klíče127.0.0.1:6379[1]> klíče *1) "čtyři"2) "tři"3) " dvě"4) "jedna"# klávesy začínající písmenem 't'127.0.0.1:6379[1]> klávesy t*1) "tři"2) "dva"# klávesy, které mají v sobě 'ee'127. 0.0.1:6379[1]> klávesy *ee*1) "tři"

Iterátory založené na kurzoru:SCAN

SCAN a jeho sesterské příkazy SSCAN (pro sady), HSCAN (pro hashe) a ZSCAN (pro seřazené sady) poskytují přístup založený na kurzoru k iteraci přes datové struktury Redis. Jsou dostupné v Redis od 2.8.0.

Klíče se vracejí v přírůstkových iteracích se zárukou konstantního času pro každou iteraci. Kurzor (v tomto případě celé číslo) je vrácen při inicializaci iterací a je vrácen aktualizovaný kurzor a každá iterace. Iterační cyklus začíná, když je kurzor v požadavku SCAN nastaven na 0, a končí, když je kurzor vrácený serverem 0.  Vzhledem k nuancím architektury Redis a implementaci algoritmu kurzoru zde jsou některé zvláštnosti tohoto přístupu:

  • Úplná iterace vždy načte všechny prvky, které byly přítomny v kolekci od začátku do konce úplné iterace.
  • Úplná iterace nikdy nevrátí žádný prvek, který NEBYL přítomen v kolekci od začátku do konce úplné iterace.
  • Daný prvek může být vrácen vícekrát. Je na aplikaci, jak si poradí s duplicitními prvky
  • Prvky, které nebyly trvale přítomny v kolekci během úplné iterace, mohou být vráceny nebo ne:není definováno.
  • Počet prvků vrácených během každého počítání se liší a může být také 0. Iterace však není dokončena, dokud server nevrátí hodnotu kurzoru 0.
  • Počet POČET Možnost lze použít k omezení počtu prvků vrácených v každé iteraci. Výchozí hodnota je 10. Je však považována pouze za návrh a není vynucována ve všech případech. Hodnotu COUNT lze změnit během každého iteračního volání.
  • Zápas volba umožňuje specifikovat vzory, jako to umožňuje příkaz KEYS.
  • Implementace kurzoru je na straně serveru zcela bezstavová. To umožňuje (potenciálně) nekonečných iterací začít paralelně. Neexistují také žádné požadavky na zajištění toho, aby iterace pokračovala až do konce a mohla být kdykoli zastavena.

Navzdory svým zvláštnostem je SCAN velmi užitečným příkazem a správným příkazem pro iteraci klíčového prostoru pro většinu případů použití.

SCAN je velmi užitečný příkaz a správný příkaz k výběru pro klíčové iterace prostoru v #RedisClick To Tweet

SKENOVÁNÍ v akci

127.0.0.1:6379[1]> flushdbOK127.0.0.1:6379[1]> klíče *(prázdný seznam nebo sada)127.0.0.1:6379[1]> ladit naplnit 33OK127.0.0.1:6379[ 1]> skenování 0 POČET 51) "4"2) 1) "klíč:1"   2) "klíč:9"   3) "klíč:13"   4) "klíč:29"   5) "klíč:23"127.0. 0.1:6379[1]> skenování 4 1) "42"2)  1) "klíč:24"    2) "klíč:28"    3) "klíč:18"    4) "klíč:16"    5) "klíč:12 "    6) "key:2"    7) "key:6"    8) "key:31"    9) "key:27"   10) "key:19"127.0.0.1:6379[1]> sken 421) "9 "2)  1) "key:3"    2) "key:4"    3) "key:20"    4) "key:8"    5) "key:32"    6) "key:5"    7) "key:26"    8) "klíč:10"    9) "klíč:21"   10) "klíč:14"127.0.0.1:6379[1]> sken 9 POČET 1001) "0"2) 1) "klíč:25"   2 ) "key:30"   3) "key:22"   4) "key:17"   5) "key:15"   6) "key:0"   7) "key:11"   8) "key:7" 

Pod pokličkou

Algoritmus, který SCAN (a jeho sesterské příkazy) používá k prohledávání, je zajímavý a vede k některým charakteristikám příkazu, které jsme popsali výše. Antirez to popsal na vysoké úrovni ve svém příspěvku na blogu a je to vysvětleno (o něco lépe) v komentářích nad implementací (funkce dictScan). Pokud jej popíšete podrobně, bude tento příspěvek příliš dlouhý, takže uvedu dostatek popisu, aby byly jeho důsledky zřejmé.

  • Většina datových struktur Redis je interně reprezentována jako slovníky (alespoň částečně v případě setříděných sad). Jsou implementovány jako hashovací tabulky s mocninou dvou velikostí s řetězením pro kolize. Výzvou při psaní iterativního algoritmu založeného na kurzoru je zde schopnost vypořádat se s rostoucím a zmenšujícím se hash, aniž by došlo k obětování Redisových principů jednoduchosti (API) a rychlosti.
  • SCAN v podstatě každou iteraci prohledá spoustu segmentů hash a vrátí prvky, které v nich odpovídají vzoru. Protože se dívá pouze na pevný seznam segmentů, některé časové iterace nemusí vrátit vůbec žádné hodnoty.
  • Vrácený kurzor je v podstatě posun do iterované hashovací tabulky. Zabývá se rozšiřováním a zmenšováním hašovacích tabulek (tj. přehášováním) pomocí chytré manipulace s bity vyšší úrovně offsetu při současném zvýšení offsetu spolu s vlastnostmi hašovací tabulky. Důsledky z tohoto přístupu jsou takové, že nové prvky přidané během iterace mohou nebo nemusí být vráceny. Samotný kurzor by se však nemusel restartovat při změně velikosti hashovací tabulky.
  • Daný segment musí být navštíven pouze jednou a všechny jeho klíče musí být vráceny najednou. Je to opět proto, aby se zajistilo, že změna velikosti hash (tj. přehašování) nebude komplikovat průběh iterace. To však vede k tomu, že argument COUNT není přísně vymahatelný.
  • Vzhledem k tomu, že výše uvedený přístup je na straně serveru zcela bezstavový, v zásadě to znamená, že lze iterace zastavit nebo spustit paralelně velké množství iterací, aniž by se zvýšilo využití paměti.

Shrnutí

Na vysoké úrovni jsou k dispozici dvě možnosti pro iteraci prostoru klíče Redis:

  1. Používejte KEYS, když vás výkon neznepokojuje nebo když je klíčový prostor přiměřeně velký.
  2. V ostatních případech použijte SCAN.
Chcete-li iterovat přes klíčový prostor #Redis, použijte KEYS, když vás výkon netrápí, jinak použijte SCANClick To Tweet

Věděli jste, že nyní podporujeme hosting pro Redis™*? Získejte plně spravovaný hosting pro Redis™ v bezpečí svého vlastního cloudového účtu a využijte kredity AWS/Azure pro svá nasazení Redis™.


  1. Jak používat příkaz HSCAN v Redis?

  2. node.js &express - globální moduly a osvědčené postupy pro strukturu aplikací

  3. Bitva o databáze NoSQL - Porovnání MongoDB a CouchDB

  4. Tipy pro vzdálenou správu MongoDB