Incidentu reaģēšana

Redis MISCONF kļūda: "Unable to Persist to Disk" un kā to novērst

Pēkšņi katra rakstīšana beidzas ar MISCONF, un tāpat arī PING. Redis nav avarējis: pēdējais fona snapshot neizdevās, un tas apzināti atsakās pieņemt rakstīšanu. Lūk, kā noskaidrot, kāpēc saglabāšana neizdevās, un kā atgūt rakstīšanu, neatsakoties no drošības tīkla.

· 16 min lasīšanai · AG Data komanda

Redis MISCONF kļūda parasti parādās vissliktākajā brīdī: lietotnes žurnāls pildās ar neizdevušos rakstīšanu, veselības pārbaudes kļūst sarkanas, bet Redis process ir dzīvs un atbild uz lasīšanas pieprasījumiem. Tieši šī detaļa ir pavediens. MISCONF nav avārija. Redis mēģināja saglabāt snapshot, saglabāšana neizdevās, un kopš tā brīža tas apzināti noraida rakstīšanu, lai jūs to pamanītu.

Šo pilno tekstu saņem klienti:

(error) MISCONF Redis is configured to save RDB snapshots, but it's currently
unable to persist to disk. Commands that may modify the data set are disabled,
because this instance is configured to report errors during writes if RDB
snapshotting fails (stop-writes-on-bgsave-error option). Please check the
Redis logs for details about the RDB error.

Valkey atgriež to pašu ziņojumu ar savu nosaukumu, un viss turpmāk teiktais attiecas arī uz to.

Kāpēc Redis pārstāj pieņemt rakstīšanu

Šo uzvedību nosaka viena opcija, stop-writes-on-bgsave-error, kas pēc noklusējuma ir yes. Komentārs failā redis.conf paskaidro loģiku: ja snapshot ir ieslēgti un pēdējā fona saglabāšana neizdevās, Redis padara problēmu redzamu "skarbā veidā", jo citādi neviens nepamanītu, ka dati vairs nenonāk diskā, līdz restarts tos izdzēstu.

Pārbaude failā server.c ir īsa. Rakstīšana tiek atteikta, ja izpildās visi trīs nosacījumi:

Divas praktiskas sekas ir viegli palaist garām:

Radniecīgs ziņojums, MISCONF Errors writing to the AOF file: ..., nāk no append-only faila. To nekontrolē stop-writes-on-bgsave-error: ja AOF ir ieslēgts un rakstīšana vai fsync tajā neizdodas, Redis atsakās pieņemt rakstīšanu, līdz AOF atkal var ierakstīt. Cēloņi parasti ir tās pašas diska problēmas, kas aprakstītas tālāk.

1. solis: apstipriniet stāvokli

redis-cli INFO persistence | grep -E 'rdb_(last_bgsave_status|bgsave_in_progress|changes_since_last_save|last_save_time|last_cow_size)'

redis-cli CONFIG GET save
redis-cli CONFIG GET dir
redis-cli CONFIG GET dbfilename

Lauki no INFO persistence, kas šeit ir svarīgi:

CONFIG GET dir un dbfilename parāda, kur Redis mēģina rakstīt. Pierakstiet šīs vērtības: tās būs vajadzīgas diska pārbaudēm, un tās ir vērts apskatīt arī drošības nolūkos (skatiet piezīmi zemāk).

2. solis: lasiet žurnālu, tajā ir cēlonis

Kļūdas teksts iesaka pārbaudīt žurnālus, un tas ir labs padoms: īstais iemesls tiek ierakstīts tur, nevis atbildē klientam. Ziņojumi nāk no rdb.c. Šie ir biežākie:

Background saving started by pid 48211
Write error while saving DB to the disk(rdbSaveRio): No space left on device
Background saving error

Failed opening the temp RDB file temp-48211.rdb (in server root dir /var/lib/redis) for saving: Permission denied

Can't save in background: fork: Cannot allocate memory

Background saving terminated by signal 9

"No space left on device": disks ir pilns

Biežākais cēlonis. Redis raksta jauno snapshot pagaidu failā temp-<pid>.rdb direktorijā dir un tikai pēc tam pārdēvē to vecā dump vietā. Tāpēc uz brīdi vajag vietu gan vecajam, gan jaunajam dump vienlaikus. Sējums ar 6 GB dump un 4 GB brīvas vietas izgāzīs katru saglabāšanu, lai gan pilns tas neizskatās. Neizdevusies saglabāšana arī neatstāj neko noderīgu: pēc rakstīšanas kļūdas Redis pagaidu failu izdzēš, tāpēc vēlāk nav redzams, ka vieta uz brīdi bija aizņemta.

Meklējiet, kas vēl atrodas tajā pašā sējumā: AOF faili, lietotnes žurnāli, vecas dump.rdb kopijas, ko kāds izveidoja "katram gadījumam". Atbrīvojiet vietu vai pārvietojiet dir uz lielāku sējumu konfigurācijā un restartējiet apkopes logā.

"Permission denied" vai "Read-only file system"

Tipiski pēc migrācijas, atjaunošanas no rezerves kopijas ar nepareizu īpašnieku, konteinera sējuma, kas piemontēts ar citu UID, vai failu sistēmas, ko kodols pēc I/O kļūdām pārmontēja tikai lasīšanai. Salīdziniet dir īpašnieku ar lietotāju, ar kuru darbojas Redis. Ja failu sistēma pati kļuva tikai lasāma, vispirms uztveriet to kā diska kļūmi un tikai tad kā Redis problēmu.

"fork: Cannot allocate memory"

BGSAVE izveido (fork) bērnprocesu, kas raksta snapshot, kamēr vecākprocess turpina apkalpot klientus. Ar Linux noklusējuma iestatījumu vm.overcommit_memory = 0 kodols noraida pieprasījumus, ko uzskata par acīmredzamu overcommit, tāpēc liela procesa fork var neizdoties, ja brīvā RAM kopā ar swap šķiet par mazu, lai gan bērnprocesam copy-on-write dēļ parasti vajag daudz mazāk. Redis to zina: startā tas pārbauda šo iestatījumu un žurnālā raksta, ka memory overcommit ir jāieslēdz, citādi "fona saglabāšana vai replikācija var neizdoties pie maza atmiņas apjoma". Ieteiktais risinājums ir vm.overcommit_memory = 1 failā /etc/sysctl.conf un sysctl vm.overcommit_memory=1, lai to piemērotu uzreiz (skatiet syscheck.c).

"terminated by signal 9": bērnprocess tika nogalināts

Fork izdevās, bet bērnprocess tika nogalināts pirms pabeigšanas, ļoti bieži ar kodola OOM killer. Kamēr bērnprocess raksta, katra lapa, ko vecākprocess maina, tiek nokopēta, tāpēc instancei ar intensīvu rakstīšanu saglabāšanas laikā vajag reālu rezervi virs used_memory. dmesg parādīs nogalināšanu. Ilgtermiņa risinājumi ir atstāt vairāk brīvas RAM, saglabāt retāk rakstīšanas pīķos vai samazināt datu apjomu ar saprātīgu maxmemory; mūsu ceļvedis par Redis OOM un izlikšanas politikām aplūko izmēru plānošanu.

OS pārbaudes visiem četriem cēloņiem:

df -h /var/lib/redis            # brīvā vieta, kur tiek rakstīts dump
ls -ld /var/lib/redis           # īpašnieks un tiesības pret Redis lietotāju
sysctl vm.overcommit_memory     # Redis brīdina startā, ja vērtība nav 1
dmesg -T | grep -i -E 'oom|killed process'

3. solis: atgūstiet rakstīšanu

Kad cēlonis novērsts, palaidiet saglabāšanu paši, nevis gaidiet nākamo save punktu:

redis-cli BGSAVE
redis-cli INFO persistence | grep -E 'rdb_bgsave_in_progress|rdb_last_bgsave_status'
# rdb_last_bgsave_status:ok  -  rakstīšana atkal tiek pieņemta

Kad statuss kļūst ok, rakstīšana atsākas bez restarta. Ja tā atkal neizdodas, žurnāla rinda pateiks, kas vēl nav kārtībā.

Ja bizness nevar gaidīt, kamēr atbrīvojat diska vietu vai pievienojat atmiņu, ir avārijas izeja:

redis-cli CONFIG SET stop-writes-on-bgsave-error no
# ...salabojiet diska / atmiņas problēmu, palaidiet BGSAVE, pārbaudiet ok...
redis-cli CONFIG SET stop-writes-on-bgsave-error yes

Ar izslēgtu opciju Redis pieņem rakstīšanu, lai gan nekas netiek saglabāts diskā. Tā ir apzināta apmaiņa: lietotne atkal strādā, bet katrs ieraksts kopš pēdējā veiksmīgā snapshot dzīvo tikai RAM. Izmantojiet to kā tiltu uz minūtēm vai stundām, turiet incidentu atvērtu un ieslēdziet opciju atpakaļ, tiklīdz saglabāšana izdodas. Nelabojiet MISCONF, ierakstot stop-writes-on-bgsave-error no konfigurācijas failā un aizmirstot par to; komentārs redis.conf to iesaka tikai tad, ja jums ir kārtīgs persistence monitorings.

Divas situācijas, kurās pareizā atbilde ir cita:

Pārbaudiet, kur norāda dir. Ja CONFIG GET dir atgriež kaut ko līdzīgu /root/.ssh, /etc vai cron direktoriju, un dbfilename nav dump faila nosaukums, tā nav diska problēma. Redis instances, kas pieejamas tīklā bez autentifikācijas, ir zināms mērķis: uzbrucējs darbības laikā maina dir un dbfilename un ar saglabāšanu novieto failu uz servera. Neizdevusies saglabāšana dīvainā vietā var būt redzamās pēdas no tā. Kopš Redis 7.0 dir un dbfilename ir aizsargātas konfigurācijas, un tās nevar mainīt ar CONFIG SET, ja to neatļauj enable-protected-configs. Uztveriet šādu atradumu kā drošības incidentu.

Kā novērst nākamo reizi

Galvenās atziņas

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

Redis tieši tagad atsakās rakstīt?

Varam ātri pieslēgties jūsu Redis vai Valkey serveriem, noskaidrot, kāpēc persistence neizdevās, un atjaunot rakstīšanu, nezaudējot datus. Pastāstiet, ko redzat.

Sazināties Vairāk no emuāra