sql >> Databasteknik >  >> NoSQL >> Redis

Redis-transaktioner och långvariga Lua-skript

Redis erbjuder två mekanismer för att hantera transaktioner – MULTI/EXEC-baserade transaktioner och Lua-skriptutvärdering. Redis Lua-skript är det rekommenderade tillvägagångssättet och är ganska populärt i användning.

Våra Redis™-kunder som har Lua-skript utplacerade rapporterar ofta detta fel – "BUSY Redis är upptagen med att köra ett skript. Du kan bara ringa SCRIPT KILL eller SHUTDOWN NOSAVE ”. I det här inlägget kommer vi att förklara Redis-transaktionsegenskapen för skript, vad det här felet handlar om och varför vi måste vara extra försiktiga med det på Sentinel-hanterade system som kan failover.

Transaktionell karaktär av Redis Lua-skript

Redis "transaktioner" är egentligen inte transaktioner som de tolkas konventionellt – i händelse av fel finns det ingen återställning av skrivningar som gjorts av skriptet.

"Atomicitet" för Redis-skript garanteras på följande sätt:

  • När ett skript börjar köras blockeras alla andra kommandon/skript tills skriptet är klart. Så andra klienter ser antingen ändringarna som gjorts av skriptet eller så gör de inte det. Detta beror på att de bara kan köras antingen före skriptet eller efter skriptet.
  • Redis gör dock inte återställningar, så vid ett fel i ett skript kommer alla ändringar som redan gjorts av skriptet att behållas och framtida kommandon/skript kommer att se dessa partiella ändringar.
  • Eftersom alla andra klienter är blockerade medan skriptet körs, är det viktigt att skriptet sköter sig väl och avslutas i tid.

Värdet 'lua-time-limit'

Det rekommenderas starkt att skriptet slutförs inom en tidsgräns. Redis upprätthåller detta på ett svagt sätt med värdet "lua-time-limit". Detta är den maximala tillåtna tiden (i ms) som skriptet får köras. Standardvärdet är 5 sekunder. Detta är en riktigt lång tid för CPU-bunden aktivitet (skript har begränsad åtkomst och kan inte köra kommandon som kommer åt disken).

Men, skriptet dödas inte när det körs efter denna tid. Redis börjar acceptera klientkommandon igen, men svarar på dem med ett UPPTAGEN-fel.

Om du måste döda skriptet vid det här laget, finns det två tillgängliga alternativ:

  • SKRIPT DÖDA kommandot kan användas för att stoppa ett skript som ännu inte har skrivit något.
  • Om skriptet redan har utfört skrivningar till servern och fortfarande måste dödas, använd SHUTDOWN NOSAVE för att stänga av servern helt.

Det är vanligtvis bättre att bara vänta på att skriptet ska slutföra sin operation. Den fullständiga informationen om metoder för att döda skriptkörningen och relaterat beteende finns i dokumentationen.

Redis-transaktioner och långvariga Lua-skriptKlicka för att tweeta

Beteende på Sentinel-övervakade system med hög tillgänglighet

Sentinel-hanterade högtillgänglighetssystem lägger till en ny rynka till detta. Faktum är att den här diskussionen gäller alla högtillgänglighetssystem som beror på att Redis-servrarna kontrolleras för hälsa:

  • Långa skript kommer initialt att blockera klientkommandon. Senare när "lua-time-limit" har passerat kommer servern att börja svara med UPPTAGEN-fel.
  • Sentinels kommer att betrakta en sådan nod som otillgänglig, och om detta kvarstår utöver ned-efter-millisekunder-värdet som konfigurerats på Sentinels, kommer de att bestämma noden som är nere.
  • Om en sådan nod är mastern, kommer en failover att initieras. En repliknod kan bli befordrad och kan börja acceptera nya anslutningar från klienter.
  • Under tiden kommer den äldre mastern så småningom att slutföra exekveringen av skriptet och komma tillbaka online. Men Sentinel kommer så småningom att konfigurera om den som en replik och den kommer att börja synkroniseras med den nya mastern. All data som skrivits av skriptet kommer att gå förlorad.

Experttips

För att uppnå hög tillgänglighet (HA) måste du distribuera en master-slave-konfiguration. Lär dig hur du ansluter till Redis-servrar i en HA-konfiguration via en enda slutpunkt.

Demonstration

Vi har skapat ett känsligt högtillgänglighetssystem för att visa detta failover-beteende. Installationen har 2 Redis-servrar som körs i en master-/replikkonfiguration som övervakas av ett kvorum med 3 sentinel.

Värdet lua-time-limit sattes till 500 ms så att det börjar svara på klienter med fel om ett skript körs längre än 500 ms. Värdet för ned-efter-millisekunder på Sentinels är inställt på 5 sekunder så att en nod som rapporterar fel markeras NED efter 5 sekunder.

Vi kör följande Lua-skript på mastern:

local i = 0
while (true)
do
local key = "Key-" .. i
local value = "Value-" .. i
redis.call('set', key, value)
i = i + 1
redis.call('time')
end

Detta fortsätter att skriva inlägg i Redis master. Vi prenumererar på händelserna på en av vaktposterna för att observera beteendet.

Skriptet initieras på mastern:

$ redis-cli -a  --eval test.lua
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

Här är en trunkerad sekvens av aktiviteter som ses på Sentinel:

3) "+vote-for-leader"
4) "9096772621089bb885eaf7304a011d9f46c5689f 1"
1) "pmessage"
2) "*"
3) "+sdown" <<< master marked DOWN
4) "master test 172.31.2.48 6379"
1) "pmessage"
2) "*"
3) "+odown"
4) "master test 172.31.2.48 6379 #quorum 3/2"
1) "pmessage"
2) "*"
3) "-role-change" << role change initiated
4) "slave 172.31.28.197:6379 172.31.28.197 6379 @ test 172.31.2.48 6379 new reported role is master"
1) "pmessage"
2) "*"
3) "+config-update-from"
4) "sentinel 9096772621089bb885eaf7304a011d9f46c5689f 172.31.2.48 26379 @ test 172.31.2.48 6379"
1) "pmessage"
2) "*"
3) "+switch-master"
4) "test 172.31.2.48 6379 172.31.28.197 6379"

Senare, när den gamla mästaren släpps online, ändras den till en replik:

3) "-role-change"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is master"
1) "pmessage"
2) "*"
3) "-sdown"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379"
1) "pmessage"
2) "*"
3) "+role-change"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is slave"

All data som skrivits till den gamla mastern via skriptet går förlorad.

Rekommendationer

  • Du måste känna till egenskaperna hos dina långvariga skript i förväg innan du distribuerar dem i produktionen.
  • Om ditt skript regelbundet bryter mot lua-tidsgränsen, måste du granska skriptet noggrant för möjliga optimeringar. Du kan också dela upp det i bitar som slutförs inom acceptabel längd.
  • Om du måste köra skript som bryter mot lua-tidsgränsen, överväg att schemalägga dessa skript under perioder där annan klientaktivitet kommer att vara låg.
  • Värdet på lua-tidsgränsen kan också ökas. Detta skulle vara en acceptabel lösning om andra klientprogram som körs parallellt med skriptet kan tolerera att få extremt försenade svar snarare än ett UPPTAGET-fel och försöka igen senare.

Ytterligare överväganden om Sentinel-övervakade högtillgänglighetssystem:

  • Om skripten bara gör läsoperationer och du har repliker tillgängliga, kan du flytta dessa skript till replikerna.

Ändra Sentinel-parametern ned-efter-millisekunder till ett värde som säkerställer att failovers inte initieras. Du måste göra detta endast efter noggrant övervägande eftersom en drastiskt ökad värde kommer att äventyra systemets egenskaper med hög tillgänglighet. Detta kan också göra att äkta serverfel ignoreras.

Fler tips till dig

Lär känna Redis-databasen:Iterera över nycklar

Möjligheten att iterera billigt över Redis-nyckelutrymmet är mycket viktigt för att bekanta dig med databasens innehåll. Lär dig de olika iterationsalternativen för nyckelrymden som finns i Redis. Läs mer

Bästa Redis användningsfall efter kärndatastrukturtyper

Redis kan fungera som en databas, en cache eller en meddelandeförmedlare och lagrar inte data i väldefinierade databasscheman som utgör tabeller, rader och kolumner. Istället lagrar Redis data i datastrukturer vilket gör det väldigt flexibelt att använda. Läs mer

6 viktiga Redis-övervakningsstatistik du måste titta på

Hur säkerställer du att din Redis-distribution är sund och uppfyller dina krav? Du behöver veta vilka övervakningsmått du ska titta på och ett verktyg för att övervaka dessa kritiska servermått för att säkerställa dess hälsa. Läs mer


  1. MongoError:anslut ECONNREFUSED 127.0.0.1:27017

  2. Mongoose Mongodb frågar efter en rad objekt

  3. Hur man säkrar ClusterControl-servern

  4. Mongoose duplicate key error med upsert