Incidentu reaģēšana

Redis "LOADING Redis is loading the dataset in memory": ko darīt

Pēc restarta vai replikas atkārtotas sinhronizācijas katra komanda atgriež LOADING, un lietotne ziņo, ka Redis nedarbojas. Patiesībā Redis ir aizņemts, lasot savus datus atpakaļ RAM. Lūk, kā redzēt, cik ilgi tas prasīs, kāpēc veselības pārbaudes to var pārvērst restartu ciklā un kā gaidīšanu saīsināt vai padarīt nemanāmu.

· 12 min lasīšanai · AG Data komanda

Redis kļūda "LOADING Redis is loading the dataset in memory" nozīmē, ka serveris darbojas, bet vēl nav pabeidzis lasīt savus datus no diska vai no galvenā servera atpakaļ RAM. Kamēr tas nav pabeigts, gandrīz katra komanda tiek noraidīta ar šo kļūdu. Nekas nav salūzis, un godīgs risinājums bieži ir pagaidīt. Darbs ir zināt, cik ilgi, neļaut veselības pārbaudēm nonāvēt Redis pusceļā un padarīt nākamo ielādi īsāku.

$ redis-cli GET user:42
(error) LOADING Redis is loading the dataset in memory

Kad Redis ielādē datus un kas joprojām strādā

Ir divi bieži brīži:

Pati pārbaude atrodas failā server.c: kamēr iestatīts server.loading, jebkura komanda bez karodziņa CMD_LOADING tiek noraidīta ar šo kļūdu. Kurām komandām karodziņš ir, nosaka commands.def, un sarakstā ir daži pārsteigumi:

Valkey darbojas tāpat. Tā server.c veido to pašu kļūdu ar servera nosaukumu tajā, un PING tur ir tie paši karodziņi.

Cik ilgi tas prasīs?

Tā kā INFO ielādes laikā strādā, Redis pats pasaka savu progresu:

Izvades piemērs (skaitļi ir ilustratīvi):

$ redis-cli INFO persistence | grep -E '^(async_)?loading'
loading:1
async_loading:0
loading_start_time:1762573620
loading_total_bytes:9663676416
loading_rdb_used_mem:0
loading_loaded_bytes:4187593113
loading_loaded_perc:43.33
loading_eta_seconds:131

INFO dokumentācija apraksta loading kā karodziņu, ka notiek dump faila ielāde. Kamēr tā notiek, parādās lauki loading_*: sākuma laiks, kopējie un ielādētie baiti, procenti un ETA. ETA failā server.c ir vienkārša ekstrapolācija no pagājušā laika un atlikušajiem baitiem, tāpēc uztveriet to kā aplēsi. Tā pietiek, lai atbildētu uz jautājumu "sekundes vai pusstunda?", kad kāds gaida uz jums.

Žurnāls rāda, cik ilgi ilga iepriekšējās ielādes. Tieši ar šo skaitli jāplāno:

# servera starts
* DB loaded from disk: 228.415 seconds
* DB loaded from append only file: 311.902 seconds   (AOF)
* Done loading RDB, keys loaded: ..., keys expired: ...

# replikas pilnā sinhronizācija
* MASTER <-> REPLICA sync: receiving ... bytes from master to disk
* MASTER <-> REPLICA sync: Loading DB in memory

Ja starti kļūst arvien lēnāki, datu kopa aug vai disks zem tās ir lēns. Abas lietas vērts zināt pirms nākamā restarta, nevis tā laikā.

Kā veselības pārbaudes pārvērš ielādi dīkstāvē

Šis ir gadījums, kas dažas ielādes minūtes pārvērš stundām ilgā dīkstāvē. Liveness pārbaude, kas palaiž redis-cli PING un gaida PONG, ielādes laikā neizdodas. Kubernetes vidē neizdevusies liveness pārbaude restartē konteineru. Jaunais process sāk ielādi no sākuma, pārbaude atkal neizdodas, un Redis nekad nepabeidz. Tas pats notiek ar jebkuru uzraudzības rīku vai orķestrētāju, kas restartē "neveselus" procesus.

Kubernetes dokumentācijā ir pareizais rīks: ja konfigurēta startup pārbaude, liveness un readiness pārbaudes netiek palaistas, līdz tā izdodas. Dodiet Redis startup pārbaudi, kas atbilst tā reālajam ielādes laikam, un liveness pārbaudi veidojiet tā, lai tā pieņem LOADING:

startupProbe:              # dod Redis laiku ielādei; liveness gaida uz to
  exec:
    command: ["sh", "-c", "redis-cli INFO persistence | grep -q '^loading:0'"]
  periodSeconds: 10
  failureThreshold: 90     # līdz ~15 minūtēm; pielāgojiet reālajam ielādes laikam
livenessProbe:             # "dzīvs" arī ielādes laikā pēc vēlāka restarta
  exec:
    command: ["sh", "-c", "redis-cli PING | grep -qE 'PONG|LOADING'"]
readinessProbe:            # nekādas slodzes, kamēr dati nav ielādēti
  exec:
    command: ["sh", "-c", "redis-cli PING | grep -q PONG"]

Ārpus Kubernetes izmantojiet to pašu noteikumu izvietošanas skriptos: gaidiet loading:0, pirms sūtāt slodzi vai restartējat nākamo mezglu.

#!/bin/sh
# gaidiet, līdz Redis pabeidz ielādi, tad turpiniet
until redis-cli INFO persistence | grep -q '^loading:0'; do
  redis-cli INFO persistence | grep -E '^loading_(loaded_perc|eta_seconds)'
  sleep 5
done
echo "Redis is ready"

Ko redz klienti

Klientu bibliotēkas LOADING uztver kā atsevišķu kļūdas veidu. Piemēram, redis-py savā atbilžu parserī prefiksu LOADING piesaista BusyLoadingError, kas ir ConnectionError apakšklase. Tāpēc to ir viegli apstrādāt apzināti: atkārtot ar pieaugošu pauzi ierobežotu laiku vai, ja Redis ir kešatmiņa, izmantot primāro datu avotu. Ko jūs negribat, ir ciešs atkārtojumu cikls no katras lietotnes instances, kas bombardē serveri, kamēr tas ielādē datus.

Nerestartējiet Redis tāpēc, ka tas "iestrēdzis" LOADING stāvoklī. Vispirms pārbaudiet loading_loaded_perc. Ja skaitlis kustas, restarts izmet progresu un sāk no jauna. Tikai tad, ja procenti ilgi nemainās un žurnālā nav progresa, kaut kas patiešām nav kārtībā.

Kā padarīt nākamo ielādi īsāku

Replikām ar Redis 7.0 un jaunāku ir vēl viena iespēja. Ar repl-diskless-load swapdb replika parsē jaunos datus tieši no socket, vienlaikus turpinot apkalpot pašreizējo datu kopu. 7.0 redis.conf norāda, ka tas neattiecas uz gadījumiem, kad replika nevar atpazīt galveno serveri kā tādu, kam ir datu kopa no tās pašas replikācijas vēstures, un ka vajag pietiekami daudz atmiņas abām kopijām, citādi riskējat ar OOM kill. Šādas ielādes laikā INFO rāda async_loading:1, un tiek noraidītas tikai komandas, kas atzīmētas kā nedrošas asinhronajai ielādei.

# replika, Redis 7.0+: turpiniet apkalpot veco datu kopu pilnās sinhronizācijas laikā
repl-diskless-load swapdb
# vajag atmiņu vecajai un jaunajai datu kopai vienlaikus

Galvenās atziņas

Redis Valkey Persistence Kubernetes Problēmu novēršana
Sadarbība ar mums

Redis restarti ilgst pārāk ilgi?

Mēs pielāgojam Redis un Valkey persistenci, replikāciju un failover, lai restarti un atkārtotas sinhronizācijas nekļūtu par dīkstāvi. Pastāstiet par datu apjomu un uzstādījumu, un mēs palīdzēsim atrast ātrāko drošo ceļu.

Sazināties Vairāk no emuāra