Ja jūsu lietotne pēkšņi žurnālā raksta OOM command not allowed when used memory > 'maxmemory', Redis dara tieši to, kas tam likts: tas sasniedzis atmiņas limitu un atsakās pieņemt ierakstus, nevis izliek atslēgas. Pretējā kļūme ir vēl sliktāka: limita nav vispār, Redis aug, līdz Linux OOM killer to izbeidz, un jūsu kešatmiņa vai rinda pazūd vienā mirklī. Abām ir viens cēlonis: Redis maxmemory un izlikšanas politikas iestatījumi, kurus neviens nav apzināti izvēlējies. Šajā rakstā: kā darbojas limits, kā izvēlēties izlikšanas politiku un kā reālistiski plānot atmiņu. Viss šeit rakstītais attiecas arī uz Valkey.
Ko OOM kļūda patiesībā nozīmē
Redis pārbauda atmiņas lietojumu ikreiz, kad klients izpilda komandu, kas pievieno datus. Ja lietojums pārsniedz maxmemory, Redis piemēro iestatīto maxmemory-policy. Ar noklusējuma politiku noeviction nekas netiek izlikts: serveris atgriež kļūdu, mēģinot izpildīt komandas, kas saglabā jaunus datus, bet lasīšana turpina darboties (Redis dokumentācija: atslēgu izlikšana).
Tātad kļūda nav avārija. Tā ir Redis pašaizsardzība. Jautājums ir, vai jūs vēlaties tieši šādu uzvedību, un atbilde atkarīga no tā, ko tajā glabājat.
Vispirms izlemiet: vai šis Redis ir kešatmiņa vai datubāze?
No šī lēmuma izriet viss pārējais.
- Tīra kešatmiņa (katru atslēgu var atjaunot no īstās datubāzes): atslēgu izlikšana ir pieņemama. Jūs vēlaties, lai Redis izmet vecus ierakstus un turpina pieņemt jaunus.
- Dati, kurus nedrīkst zaudēt (sesijas, kuras negribat pazaudēt, rindas, pieprasījumu limitu skaitītāji, uzdevumu stāvoklis, jebkas bez citas kopijas): izlikšana klusi dzēš datus. Šeit drošāka izvēle ir
noevictionkopā ar pietiekamu atmiņu un labiem brīdinājumiem. Redzama kļūda ir labāka nekā klusi pazuduši dati. - Abi vienā instancē: šeit rodas lielākā daļa pārsteigumu. Redis dokumentācija šādam sajaukumam iesaka
volatile-*politikas, bet arī saka, ka, ja iespējams, vajadzētu apsvērt divas atsevišķas Redis instances. Mēs piekrītam: atsevišķas instances, atsevišķi limiti, atsevišķas politikas.
Izlikšanas politikas vienkāršiem vārdiem
noeviction: nekad neizlikt; kad pilns, ierakstiem atgriezt kļūdas. Noklusējums.allkeys-lru: izlikt visilgāk neizmantotās atslēgas. Dokumentācija to sauc par labu noklusējuma izvēli, ja nav iemesla dot priekšroku citai, kešatmiņām, kurās dažas atslēgas ir daudz karstākas par citām.allkeys-lfu: izlikt visretāk izmantotās atslēgas (Redis 4.0+). Bieži labāka, ja popularitāte ir svarīgāka par nesenumu.allkeys-random: izlikt nejaušas atslēgas. Saprātīgi, ja visām atslēgām piekļūst aptuveni vienādi.volatile-lru,volatile-lfu,volatile-random: tas pats, bet tikai starp atslēgām ar TTL.volatile-ttl: izlikt atslēgas ar TTL, kuru derīgums beigsies visātrāk.allkeys-lrm,volatile-lrm: visilgāk nemainītās atslēgas, pievienotas Redis 8.6. Lasīšana laikspiedolu neatjauno, to dara tikai ieraksti. Valkey dokumentācijā tās nav minētas, tāpēc pirms izmantošanas pārbaudiet savu dzinēju un versiju (Valkey dokumentācija).
Lamatas: volatile-* politikas uzvedas kā noeviction, ja nevienai atslēgai nav TTL. Komandas iestata volatile-lru, aizmirst, ka puse lietotnes raksta atslēgas bez derīguma termiņa, un tik un tā saņem OOM kļūdas. Ja izvēlaties volatile politiku, pārbaudiet, vai atslēgām, kuras paredzēts izlikt, tiešām ir TTL.
Redis LRU un LFU ir tuvinājumi: Redis paņem dažu atslēgu paraugu (maxmemory-samples, noklusējums 5) un izliek labāko kandidātu no tām. Palielinot paraugu skaitu līdz 10, rezultāts tuvojas īstam LRU uz nelielu CPU rēķina. Lielākajai daļai slodžu ar 5 pietiek.
maxmemory izmērs: kāpēc "visa RAM" ir nepareizi
64 bitu sistēmās maxmemory pēc noklusējuma ir 0, kas nozīmē bez limita. Tieši tā Redis nonāk līdz kodola nogalināšanai. Iestatiet to skaidri un atstājiet vietu lietām, kas nav jūsu dati:
- Papildu izmaksas un fragmentācija. Redis administrēšanas ceļvedis to saka tieši: ja domājat, ka jums ir 10 GB brīvas atmiņas, iestatiet 8 vai 9 (Redis administrēšana).
- Replikācijas un AOF buferi. Atmiņa buferiem, kas gaida nosūtīšanu replikām vai AOF failam, netiek ieskaitīta
maxmemory. Ar replikāciju vai saglabāšanu atstājiet tiem brīvu RAM.INFO memorypašreizējo apjomu rāda kāmem_not_counted_for_evict. - Fork saglabāšanas laikā. Kad Redis raksta RDB momentuzņēmumu vai pārraksta AOF, tas izveido fork. Lietotnē ar daudz ierakstiem saglabāšanas laikā Redis var izmantot līdz 2 reizēm vairāk atmiņas nekā parasti, jo mainītās lapas tiek kopētas. Plānojiet to, citādi tieši saglabāšanas brīdī uzbruks OOM killer.
- Citi procesi serverī: monitoringa aģenti, Sentinel, OS lapu kešatmiņa saglabāšanas failiem.
Administrēšanas ceļvedis iesaka arī vm.overcommit_memory = 1, lai fona saglabāšana neizgāztos uz fork(), un izslēgt Transparent Huge Pages, kas var pasliktināt atmiņas lietojumu un latentumu.
Kā diagnosticēt Redis, kam beidzas atmiņa
redis-cli INFO memory
redis-cli INFO stats
redis-cli MEMORY DOCTOR
redis-cli --bigkeys
used_memorypretmaxmemory: cik tuvu esat limitam.used_memory_rssunmem_fragmentation_ratio: ja RSS ir daudz lielāks par izmantoto atmiņu, RAM apēd fragmentācija. Var palīdzēt aktīvā defragmentācija (activedefrag).evicted_keysunexpired_keys: vai atslēgas tiek izliktas vai beidzas, kā paredzēts?keyspace_hitsunkeyspace_misses: trāpījumu attiecība. Krītoša trāpījumu attiecība kopā ar daudzām izlikšanām nozīmē, ka kešatmiņa ir par mazu vai politika izliek nepareizās atslēgas.--bigkeysunMEMORY USAGE <key>: atrodiet dažas milzīgās atslēgas (saraksts, kas nekad netiek apgriezts, hash, kas mūžīgi krāj visus lietotājus), kas bieži ir īstais cēlonis.
Ko darīt, ja tas notiek tieši tagad
- Ja tā ir tīra kešatmiņa, pārslēgšanās uz izliekošu politiku darbības laikā ir ātra:
CONFIG SET maxmemory-policy allkeys-lru. Pēc tam saglabājiet to konfigurācijas failā. - Ja tajā ir svarīgi dati, nepārslēdzieties uz izlikšanu panikā: jūs dzēstu datus, lai kļūda pazustu. Palieliniet
maxmemory, ja serverim tiešām ir brīva RAM, vai palieliniet resursus, tad noskaidrojiet, kas izauga. - Meklējiet atslēgu, kas uzsprāga. Nevaldāms saraksts vai kopa ir bieža parādība, un šīs vienas atslēgas salabošana bieži atbrīvo lielāko daļu atmiņas.
- Pārbaudiet atslēgas bez TTL, kurām tas bija paredzēts.
Kā novērst atkārtošanos
- Katrā instancē skaidri iestatiet
maxmemoryunmaxmemory-policy. Noklusējumi nav lēmums. - Brīdiniet par atmiņas lietojumu attiecībā pret
maxmemory, par augošuevicted_keysdatu instancēs un par noraidītām komandāmINFO commandstats. Tie pieder pie citiem agrīnajiem signāliem rakstā datubāzu rādītāji, kas paredz incidentus. - Katrai kešatmiņas atslēgai piešķiriet TTL, ja vien nav skaidra iemesla to nedarīt.
- Turiet kešatmiņas un svarīgus datus atsevišķās instancēs.
- Ja pārejat no Redis uz Valkey, pārnesiet šos iestatījumus apzināti un testējiet ar produkcijai līdzīgiem datiem; pārējo kontrolsarakstu aptver mūsu Redis uz Valkey migrācijas ceļvedis.
Galvenās atziņas
- "OOM command not allowed" nozīmē, ka Redis sasniedzis
maxmemoryar noklusējuma politikunoevictionun atsakās pieņemt ierakstus. - Izvēlieties politiku pēc tā, ko glabājat: izlikšana tīrām kešatmiņām,
noevictionar brīdinājumiem datiem, kurus nedrīkst zaudēt. volatile-*politikas izliek tikai atslēgas ar TTL; bez TTL tās darbojas kānoeviction.- Iestatiet
maxmemoryzem fiziskās RAM: atstājiet vietu papildu izmaksām, replikācijas buferiem un līdz 2x atmiņai saglabāšanas laikā. - Uzraugiet atmiņu, izlikšanas, trāpījumu attiecību un lielās atslēgas, un turiet kešatmiņas atsevišķi no svarīgiem datiem.