sql >> Database teknologi >  >> NoSQL >> Redis

Redis jokertegn slette script ved hjælp af EVAL, SCAN og DEL returnerer skrivekommandoer ikke tilladt efter ikke-deterministiske kommandoer

OPDATERING: nedenstående gælder for Redis-versioner op til 3.2. Fra den version ophæver effektbaseret replikering forbuddet mod ikke-determinisme, så alle væddemål er slået fra (eller rettere sagt tændt).

Du kan (og bør ikke) blande SCAN familie af kommandoer med enhver skrivekommando i et script, fordi førstnævntes svar er afhængig af de interne Redis-datastrukturer, som igen er unikke for serverprocessen. Sagt på en anden måde, er to Redis-processer (f.eks. master og slave) ikke garanteret at returnere de samme svar (så i Redis-replikeringskontekst [som ikke er operations- men sætningsbaseret] ville det bryde det).

Redis forsøger at beskytte sig selv mod sådanne tilfælde ved at blokere enhver skrivekommando (såsom DEL ), hvis den udføres efter en tilfældig kommando (f.eks. SCAN men også TIME , SRANDMEMBER og lignende). Jeg er sikker på, at der er måder at omgå det på, men vil du gerne gøre det? Husk, du vil gå ind i ukendt territorium, hvor systemets adfærd ikke er defineret.

Accepter i stedet det faktum, at du ikke bør blande tilfældige læsninger og skrivninger, og prøv at tænke på en anden tilgang til at løse dit problem, nemlig at slette et bundt nøgler efter et mønster på en atomart måde.

Spørg først dig selv, om du kan slække på nogle af kravene. Skal det være atomare? Atomicitet betyder, at Redis vil blive blokeret under sletningens varighed (uanset den endelige implementering), og at varigheden af ​​operationen afhænger af jobbets størrelse (dvs. antallet af nøgler, der slettes og deres indhold [sletning af et stort sæt er dyrere end at slette en kort streng for eksempel]).

Hvis atomicitet ikke er et must, SCAN med jævne mellemrum/dovent og slet i små partier. Hvis det er et must, skal du forstå, at du dybest set forsøger at efterligne de onde KEYS kommando :) Men du kan gøre det bedre, hvis du har forhåndskendskab til mønsteret.

Forudsat at mønsteret er kendt under kørsel af din applikation, kan du indsamle de relevante nøgler (f.eks. i et sæt) og derefter bruge denne samling til at aktualisere sletningen på en atomisk og replikationssikker måde, der er mere effektiv sammenlignet med at gå over hele nøglerummet .

Det mest "svære" problem er dog, hvis du har brug for at køre ad-hoc mønstermatching og samtidig sikre atomicitet. Hvis det er tilfældet, bunder problemet ned til at opnå et filtreret-efter-mønster-øjebliksbillede af nøglerummet umiddelbart efterfulgt af en række sletninger (genunderstreger:mens databasen er blokeret). I så fald kan du meget vel bruge KEYS i dit Lua-script og håber på det bedste... (men vel vidende, at du kan ty til SHUTDOWN NOSAVE ret hurtigt :P).

Den sidste optimering er at indeksere selve tasterummet. Begge SCAN og KEYS er dybest set fulde tabelscanninger, så hvad nu hvis vi skulle indeksere den tabel? Forestil dig at holde et indeks over nøglenavne, der kan forespørges under en transaktion - du kan sandsynligvis bruge et sorteret sæt og leksikografiske områder (HT @TwBert ) for at gøre op med de fleste behov for mønstertilpasning. Men til en betydelig pris... vil du ikke kun lave dobbelt bogholderi (lagre hver nøgles navneomkostninger i RAM og CPU), du vil blive tvunget til at tilføje kompleksitet til din applikation. Hvorfor tilføje kompleksitet? Fordi for at implementere et sådant indeks, skal du selv vedligeholde det i applikationslaget (og muligvis alle dine andre Lua-scripts), og omhyggeligt pakke hver skriveoperation til Redis i en transaktion, der også opdaterer indekset.

Forudsat at du gjorde alt det (og tager højde for de åbenlyse faldgruber som den tilføjede kompleksitets potentiale for fejl, mindst fordoblet skrivebelastning på Redis, RAM &CPU, begrænsninger for skalering og så videre...) kan du klappe dig selv på skulder og lykønsk dig selv med at bruge Redis på en måde, som den ikke var designet til. Mens kommende versioner af Redis måske (eller måske ikke) indeholder bedre løsninger til denne udfordring (@TwBert - vil du lave en fælles RCP/bidrag og igen hacke Redis lidt? ), før du prøver dette, opfordrer jeg dig virkelig til at genoverveje de oprindelige krav og bekræfte, at du bruger Redis korrekt (dvs. designe dit "skema" i overensstemmelse med dine behov for dataadgang).




  1. Hvordan henter man en værdi fra mongoDB efter dets nøglenavn?

  2. Mulighed for at duplikerede Mongo ObjectId'er bliver genereret i to forskellige samlinger?

  3. pymongo - dnspython-modulet skal være installeret for at bruge mongodb+srv:// URI'er

  4. MongoDB BSON guide