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:
stop-writes-on-bgsave-erroriryes;- ir konfigurēts vismaz viens
savepunkts (RDB snapshot ir ieslēgti); - pēdējā fona saglabāšana beidzās ar kļūdu.
Divas praktiskas sekas ir viegli palaist garām:
- Arī PING neizdodas. Tas pats koda ceļš noraida
PINGkopā ar rakstīšanas komandām. Liveness pārbaude vai klienta bibliotēka, kas pirms lietošanas izsauc PING, ziņos, ka serveris nedarbojas, lai gan tas joprojām apkalpoGET. Ja orķestrators pēc šī signāla restartē konteineru, mezgls, kura dati tā arī nenonāca diskā, var tikt palaists no veca dump vai pavisam tukšs. - Tas atjaunojas pats. Tiklīdz kāda fona saglabāšana izdodas, rakstīšana atkal ir atļauta. Atsevišķas "atbloķēšanas" komandas nav. Jūsu uzdevums ir panākt, lai nākamā saglabāšana izdotos.
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:
rdb_last_bgsave_status:errapstiprina, ka tas ir RDB gadījums.rdb_bgsave_in_progressparāda, vai saglabāšana notiek tieši tagad. Ja notiek, pagaidiet, pirms sākt nākamo.rdb_changes_since_last_saveunrdb_last_save_time(Unix laika zīmogs) rāda, cik daudz datu eksistē tikai atmiņā un kopš kura brīža. Šis skaitlis ir jūsu risks, ja process tagad apstāsies.rdb_last_cow_sizeir copy-on-write atmiņa, kas bija vajadzīga pēdējai saglabāšanai. Tas ir svarīgi, ja jums ir aizdomas par atmiņas problēmām.
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:
- Tīrs kešs. Ja instancē nav nekā, ko nevarētu atjaunot, snapshot var būt vienkārši nevajadzīgi. Ja nav konfigurēts neviens save punkts (
save ""), RDB pārbaude vispār netiek piemērota. Pieņemiet šo lēmumu apzināti, nevis kā reakciju uz incidentu. - Dati, ko nedrīkst zaudēt. Pirms kaut ko aiztiekat, apsveriet, vai datus atmiņā vispirms nevajag nokopēt citur, piemēram, pievienojot repliku ar veselu disku. Restarts šajā brīdī ielādētu pēdējo veiksmīgo dump un zaudētu visu, kas ierakstīts kopš tā.
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
- Iestatiet brīdinājumu par
rdb_last_bgsave_status, ne tikai par "Redis darbojas". Statuss kļūsterrpie pirmās kļūmes, ilgi pirms kāds paskatās uz paneli, unrdb_changes_since_last_saveparāda, cik daudz ir apdraudēts. - Plānojiet sējumu diviem dump plus AOF, ja to izmantojat, un iestatiet brīdinājumu par brīvo vietu ceļā
dir. Vispārējā pieeja ir aprakstīta mūsu rakstā par metrikām, kas paredz datubāzu incidentus. - Iestatiet
vm.overcommit_memory = 1Redis serveros, kā Redis pats lūdz startā, un atstājiet atmiņas rezervi copy-on-write vajadzībām saglabāšanas laikā. - Padariet veselības pārbaudes godīgas. Pārbaude, kas neizdodas pie MISCONF, ir noderīga kā brīdinājums; tāda, kas pēc tās restartē konteineru, var pārvērst diska brīdinājumu datu zudumā.
- Izlemiet, kāda persistence jums patiešām vajadzīga. RDB, AOF, abi vai nekas tīram kešam. Redis persistence dokumentācija un Valkey ekvivalents apraksta iespējas.
Galvenās atziņas
- MISCONF nozīmē, ka pēdējā fona saglabāšana neizdevās un
stop-writes-on-bgsave-error yes(noklusējums) apzināti bloķē rakstīšanu un PING. Lasīšana joprojām strādā. - Iemesls ir Redis žurnālā: nav vietas pagaidu dump, tiesības vai tikai lasāma failu sistēma, neizdevies fork vai OOM killer nogalināts bērnprocess.
- Novērsiet cēloni, palaidiet
BGSAVE, un rakstīšana atgriežas, tiklīdzrdb_last_bgsave_statusirok. Restarts nav vajadzīgs. - Opcijas izslēgšana ir pagaidu tilts, kas darbojas bez persistence, nevis risinājums.
- Negaidīta
dirvērtība ir drošības atradums, nevis diska problēma.