Monitorings

Redis mem_fragmentation_ratio pārāk augsts? Kā to saprast un novērst

Redis saka, ka izmanto 20 GB, serveris rāda 32 GB, un brīdinājums ziņo par fragmentāciju 1,6. Dažreiz tā ir reāla izšķērdība, dažreiz pāri palicis maksimums, un dažreiz aiz tā slēpjas pretēja problēma: swap.

· 13 min lasīšanai · AG Data komanda

Augsts Redis mem_fragmentation_ratio ir viens no biežākajiem atmiņas brīdinājumiem un viens no visbiežāk pārprastajiem. Šis skaitlis salīdzina to, ko redz operētājsistēma, ar to, ko Redis uzskata par piešķirtu. Vērtība 1,5 uz 30 GB instances var nozīmēt 10 GB reālas izšķērdības, nekaitīgu vakardienas maksimuma atlikumu vai uzskaites efektu, kam nav nekāda sakara ar jūsu datiem. Vērtība zem 1 ir vēl sliktāka: parasti tas nozīmē, ka kodols daļu Redis ir izspiedis uz swap. Lūk, kā to pareizi nolasīt un kas jādara katrā gadījumā.

Ko rādītājs patiesībā mēra

INFO memory definē mem_fragmentation_ratio kā attiecību starp used_memory_rss (cik RAM process aizņem operētājsistēmas skatījumā) un used_memory (cik Redis ir piešķīris caur savu alokatoru). Dokumentācija skaidri saka, ka tajā ietilpst ne tikai fragmentācija, bet arī citas procesa virsizmaksas, kods, koplietojamās bibliotēkas un steks.

Sāciet, apskatot visu kopā:

redis-cli INFO memory | grep -E '^(used_memory|used_memory_rss|used_memory_peak|mem_fragmentation_ratio|mem_fragmentation_bytes|allocator_frag_ratio|allocator_frag_bytes|allocator_rss_ratio|rss_overhead_ratio|mem_allocator):'

redis-cli MEMORY DOCTOR

Kopš Redis 4.0 MEMORY DOCTOR arī sniedz īsu, cilvēkam saprotamu pārskatu ar ieteikumiem. Pēc tam lasiet skaitļus šādā secībā:

Ja allocator_frag_ratio ir tuvu 1, bet mem_fragmentation_ratio ir augsts, jūs neskatāties uz fragmentāciju parastajā nozīmē.

1. cēlonis: pagātnes maksimums, nevis fragmentācija

Biežākais skaidrojums ir aprakstīts Redis atmiņas optimizācijas ceļvedī: Redis ne vienmēr atdod atmiņu operētājsistēmai, kad atslēgas tiek dzēstas. Ja instance izauga līdz 5 GB un pēc tam tika dzēsti 2 GB atslēgu, RSS, visticamāk, paliks ap 5 GB, kamēr used_memory nokritīsies līdz 3 GB. Atbrīvotās lapas bieži dala vietu ar atslēgām, kas vēl eksistē, tāpēc alokators nevar tās atdot.

Šī atmiņa nav zaudēta. Kad pienāk jaunas atslēgas, alokators atkārtoti izmanto atbrīvoto vietu, un RSS nemainās, līdz dati pārsniedz veco izmēru. Salīdziniet used_memory_peak ar used_memory_rss: ja RSS ir tuvu maksimumam, attiecība atspoguļo vēsturi, nevis problēmu. Ceļvedis pats izdara praktisko secinājumu: plānojiet atmiņu maksimālajam lietojumam un neuzticieties fragmentācijas attiecībai pēc liela maksimuma.

Tipiski izraisītāji ir masveida dzēšana, pakešuzdevums, kas uz dažām stundām piepildīja kešatmiņu, vai liels izlikšanas vilnis. Kā izlikšana un maxmemory mijiedarbojas, skaidrojām rakstā Redis OOM un izlikšanas politikas.

2. cēlonis: īsta fragmentācija

Īsta ārējā fragmentācija rodas, kad slodze nepārtraukti piešķir un atbrīvo dažāda izmēra vērtības: virknes, kas aug un sarūk, daudz atslēgu ar īsu TTL, jaucējtabulas un saraksti, kas pastāvīgi maina izmēru. Alokatoram paliek daudz daļēji izmantotu lapu. To redz kā augstu allocator_frag_ratio kopā ar lielu allocator_frag_bytes, un tas nepazūd, kad datu kopa atkal pieaug.

Ņemiet vērā, ka maxmemory ierobežo to, ko Redis piešķir datiem; atmiņas ceļvedis saka, ka Redis piešķir ne vairāk par šo apjomu, izņemot nelielus papildu piešķīrumus. Fragmentācija nāk klāt. Serverim ar maxmemory 24gb un īstu fragmentāciju 1,4 vajag daudz vairāk nekā 24 GB RAM, un OOM killer neinteresē, ko saka maxmemory.

3. cēlonis: attiecība zem 1 nozīmē swap

Ja used_memory ir lielāks par used_memory_rss, dokumentācija saka, ka daļu Redis atmiņas operētājsistēma ir izspiedusi uz swap, un jārēķinās ar ievērojamu aizturi. Tas ir bīstamais gadījums, un to viegli palaist garām, jo brīdinājumus parasti iestata tikai augstām vērtībām. Aiztures ceļvedis parāda, kā to apstiprināt:

redis-cli INFO server | grep process_id
grep Swap: /proc/<pid>/smaps | awk '{s+=$2} END {print s " kB swapped"}'
vmstat 1   # ne-nulles si/so kolonnas nozīmē, ka swap notiek tieši tagad

Risinājums ir mazāks atmiņas spiediens, nevis Redis pielāgošana: vairāk RAM, zemāks maxmemory vai citu atmiņu prasīgu procesu pārvietošana no servera.

Aktīvā defragmentācija

Redis 4.0 ieviesa aktīvo defragmentāciju, kas pārvieto vērtības kompaktos atmiņas apgabalos, kamēr serveris turpina darbu. Saskaņā ar redis.conf tā pēc noklusējuma ir izslēgta un darbojas tikai ar Redis komplektā iekļauto jemalloc kopiju, kas ir noklusējums Linux būvējumiem. To var ieslēgt darba laikā:

# pārbaudiet, vai serveris izmanto jemalloc
redis-cli INFO memory | grep mem_allocator

# ieslēdziet darba laikā (sliekšņiem paliek noklusējuma vērtības)
redis-cli CONFIG SET activedefrag yes
redis-cli CONFIG GET active-defrag-*

# sekojiet progresam
redis-cli INFO memory | grep -E 'allocator_frag_ratio|active_defrag_running'
redis-cli INFO stats  | grep -E 'active_defrag_(hits|misses|key_hits|key_misses)'

Noklusējuma vērtības Redis 7.4 un 8.0 un Valkey 8.1 ir vienādas:

Valkey 8.1 pievieno active-defrag-cycle-us (noklusējums 500 mikrosekundes), katra defragmentācijas cikla ilgumu, kas nosaka ietekmi uz klientu komandu aizturi. Paši konfigurācijas faili iesaka neaiztikt noklusējuma vērtības, ja nezināt, ko maināt, un ieslēgt funkciju tikai tad, ja fragmentācija tiešām ir.

Ir arī MEMORY PURGE, kas lūdz jemalloc atbrīvot netīrās lapas. Tas var samazināt allocator_rss_bytes, bet neko nekompaktē, tāpēc īstu fragmentāciju nenovērš.

Lielas instances: kas mainās

Mūsu īkšķa likums: brīdiniet par mem_fragmentation_bytes un par attiecību zem 1, nevis tikai par attiecību virs 1,5. Pirms ieslēdzat defragmentāciju, pārbaudiet allocator_frag_ratio. Ja tas ir tuvu 1, "fragmentācija" ir pagātnes maksimums vai virsizmaksas, un defragmentācija nepalīdzēs.

Kontrolsaraksts, kad iedarbojas brīdinājums

  1. Pārbaudiet mem_fragmentation_bytes: vai zudumi ir pietiekami lieli, lai būtu svarīgi?
  2. Ja attiecība ir zem 1, vispirms pārbaudiet swap failā /proc/<pid>/smaps un ar vmstat.
  3. Salīdziniet used_memory_rss ar used_memory_peak, lai saprastu, vai tas ir pagātnes maksimums.
  4. Nolasiet allocator_frag_ratio un allocator_frag_bytes, lai redzētu īsto fragmentāciju.
  5. Pārliecinieties, ka mem_allocator ir jemalloc, tad klusākā periodā ieslēdziet activedefrag un sekojiet aizturei.
  6. Ja defragmentācija nav pietiekama vai nav pieejama, plānojiet pārslēgšanu uz repliku un restartējiet veco primāro serveri.
  7. Pārskatiet izmēru: maksimālie dati plus fragmentācija plus fork virsizmaksas.

Galvenās atziņas

Redis Valkey Atmiņa Monitorings
Sadarbība ar mums

Redis atmiņa nesakrīt?

Mēs izmeklējam Redis un Valkey atmiņas problēmas produkcijā: fragmentāciju, swap, fork izmaksas un izmēru plānošanu, un novēršam tās, nezaudējot datus un neapturot kešatmiņu.

Sazināties Vairāk no emuāra