Vairumam Redis latentuma lēcienu nav nekāda sakara ar to, ka Redis būtu "lēns". Redis izpilda komandas vienā galvenajā pavedienā, tāpēc viss, kas bloķē šo pavedienu uz 50 milisekundēm, liek katram klientam gaidīt 50 milisekundes. Uzdevums ir atrast, kas to bloķēja: viena smaga komanda, fork momentuzņēmumam, disks, kas aizkavēja fsync, hipervizors vai tīkls starp lietotni un serveri.
Vispirms: vai vainīgs Redis vai ceļš līdz tam?
Lietotnes taimauti mēra visu turp un atpakaļ ceļu. Pirms maināt kādu Redis iestatījumu, pārbaudiet, kur pazūd laiks:
redis-cli -h redis1 --latency # aprites laiks no šī klienta
redis-cli -h redis1 --latency-history # tas pats, pa laika logiem
redis-cli --intrinsic-latency 100 # palaist UZ servera, 100 sekundes
redis-cli -h redis1 INFO | grep latest_fork_usec
Redis latentuma rokasgrāmatā paskaidrots, ka --intrinsic-latency ar Redis vispār nesazinās. Tas mēra, cik ilgi kodols vai hipervizors notur procesu bez CPU, tāpēc tas jāpalaiž uz servera. Ja šis skaitlis jau ir vairākas milisekundes, neviena Redis noregulēšana jūs zem tā nenovedīs. Tā pati rokasgrāmata norāda, ka virtualizēti hosti ar trokšņainiem kaimiņiem var būt daudz sliktāki par fizisku serveri.
Ja --latency no lietotnes hosta ir augsts, bet no paša Redis hosta zems, skatieties uz tīklu, savienojumu mainību un klientu. Jauna savienojuma atvēršana katram pieprasījumam vai simtiem turp un atpakaļ ceļu MGET, konveijera vai skripta vietā pievieno latentumu, ko Redis nekad neredz.
SLOWLOG: komandas, kas bloķēja serveri
CONFIG GET slowlog-log-slower-than # noklusējums 10000 (mikrosekundes = 10 ms)
CONFIG GET slowlog-max-len # noklusējums 128 ieraksti
SLOWLOG LEN
SLOWLOG GET 25 # jaunākie ieraksti: id, laiks, ilgums us, argumenti, klients
SLOWLOG RESET
Saskaņā ar SLOWLOG dokumentāciju lēnais žurnāls mēra tikai komandas izpildes laiku, nevis tīkla I/O vai atbildes sūtīšanu, un tieši šajā daļā galvenais pavediens nevar apkalpot nevienu citu. Katrā ierakstā ir ilgums mikrosekundēs, argumenti un klienta adrese, tāpēc parasti uzreiz redzams, kurš serviss to sūtīja.
Tipiski atradumi:
KEYSprodukcijas kodā vai administrēšanas skriptā. Dokumentācija to sauc par ļoti biežu latentuma avotu; aizstājiet arSCAN.- O(N) komandas uz lielām vērtībām:
HGETALL,SMEMBERS,LRANGE 0 -1,SORT,SUNION,ZRANGEpār milzīgiem diapazoniem. IzmantojietHSCAN/SSCAN/ZSCANvai lapošanu. - Milzīgas atslēgas
DEL. Miljoniem elementu atbrīvošana aizņem laiku galvenajā pavedienā.UNLINKatbrīvo atmiņu fonā. Redis opcijalazyfree-lazy-user-del, kas liekDELuzvesties kāUNLINK, pēc noklusējuma irno; Valkey kopš 8.0 lazyfree opcijas pēc noklusējuma iryes. - Gari Lua skripti vai
MULTIbloki, kas vienā piegājienā dara pārāk daudz.
Noklusējuma slieksnis ir 10 ms, un tiek glabāti tikai 128 ieraksti, tāpēc noslogotā serverī veci ieraksti ātri pazūd. Ja vajag vēsturi, vāciet tos regulāri. Valkey 8.1 un jaunākās versijās lēnais žurnāls ir daļa no COMMANDLOG, kas seko arī lieliem pieprasījumiem un lielām atbildēm; vecie slowlog-* parametri joprojām darbojas, bet ir novecojuši.
Latentuma monitors: lēcieni, kas nav komandas
Daži apstāšanās gadījumi SLOWLOG nekad neparādās, jo tie nav komandu izpilde. Latentuma monitors mēra iekšējus notikumus, piemēram, fork, aof-write, aof-fsync-always, expire-cycle, eviction-cycle un active-defrag-cycle. Pēc noklusējuma tas ir izslēgts (slieksnis 0), un to var ieslēgt darbības laikā:
CONFIG SET latency-monitor-threshold 100 # milisekundes, 0 = izslēgts (noklusējums)
LATENCY LATEST
LATENCY HISTORY fork
LATENCY DOCTOR
Iestatiet slieksni uz to, ko jūsu lietotne uzskata par pārāk lēnu. Katram notikumam tiek glabāta 160 paraugu laika rinda. LATENCY DOCTOR izdrukā lasāmu kopsavilkumu ar ieteikumiem. Kopš Redis 7.0 ir arī latentuma uzskaite katrai komandai ar p50, p99 un p99.9 vērtībām INFO latencystats; tā pēc noklusējuma ir ieslēgta.
Tipiskie aizdomās turamie ārpus komandām
- Fork RDB momentuzņēmumiem un AOF pārrakstīšanai.
fork()darbojas galvenajā pavedienā un kopē lapu tabulu, kas aug līdz ar atmiņas apjomu. Pārbaudietlatest_fork_usecizvadēINFOun notikumufork. Dokumentācija rāda, ka fork laiks dažādās platformās atšķiras par lieluma kārtām, un dažas vecākas Xen virtuālās mašīnas ir īpaši lēnas. - Transparent huge pages. Ja THP ir ieslēgts, kopēšana-pie-rakstīšanas pēc fork var skart lielās lapas un radīt gan latentumu, gan papildu atmiņas patēriņu. Dokumentācija iesaka to izslēgt:
echo never > /sys/kernel/mm/transparent_hugepage/enabled, pēc tam restartēt Redis. - AOF un disks. Ar
appendfsync alwayskatrs ieraksts gaida fsync. Areverysecfsync notiek fona pavedienā, bet, ja tas ilgst pārāk ilgi, galvenais pavediens tik un tā var bloķēties uzwrite(2). Cits smags I/O uz tā paša diska to pasliktina. Noturības kompromisi aprakstīti rakstā Redis noturība: RDB pret AOF. - Mijmaiņa (swap). Ja kodols izliek Redis lapas mijmaiņā, šo atslēgu skaršana aptur procesu. Pārbaudiet
Swap:rindas failā/proc/<pid>/smapsun kolonnassi/soizvadēvmstat 1. - Daudzu atslēgu derīgums beidzas vienlaikus. Aktīvā dzēšana parasti noņem atslēgas mazos soļos, bet, ja vairāk nekā 25% no pārbaudītajām atslēgām ar TTL jau ir beigušās, cikls atkārtojas. Tāpēc viens un tas pats
EXPIREATmiljoniem atslēgu var bloķēt serveri. Pievienojiet TTL nejaušu nobīdi. - Atmiņas spiediens un defragmentācija. Izlikšanas cikli un aktīvā defragmentācija arī darbojas galvenajā pavedienā. Ja
LATENCY LATESTparādāseviction-cyclevaiactive-defrag-cycle, skatiet Redis atmiņas fragmentācijas koeficients.
CONFIG SET watchdog-period 500) ieraksta žurnālā steka izsekojumu, ja serveris ir bloķēts ilgāk par periodu. Dokumentācija to sauc par eksperimentālu un paredzētu tikai atkļūdošanai. Izslēdziet to atpakaļ ar watchdog-period 0.Kas mainās ar lielām datu kopām
- Fork laiks aug līdz ar atmiņu. Dokumentācijas piemērs: 24 GB instancei ar 4 kB lapām vajag aptuveni 48 MB lapu tabulu, un tā visa tiek kopēta pie katra
BGSAVEvai AOF pārrakstīšanas. 100+ GB instancē šī apstāšanās klientiem var būt skaidri redzama. Plānojiet momentuzņēmumus ārpus maksimuma, apsveriet noturību tikai uz replikas un mērietlatest_fork_usecuz reālā instances izmēra. - Kopēšanai-pie-rakstīšanas vajag brīvu RAM. Momentuzņēmuma laikā katra lapa, ko maina klienti, tiek dublēta. Lielai, rakstīšanas noslogotai instancei vajag atmiņas rezervi, citādi hosts sāk izmantot mijmaiņu, kas ir daudz sliktāk par pašu fork.
- Lielas atslēgas kļūst par lielām avārijām. Hash vai sakārtota kopa ar miljoniem elementu pārvērš "nekaitīgas" komandas vairāku sekunžu apstāšanās gadījumos un ienes tos arī replikācijā un migrācijās. Atrodiet tās ar
redis-cli --bigkeysvai--memkeys, vēlams pret repliku, un sadaliet. - Pilna atkārtota sinhronizācija sāp vairāk. Replika, kas atpaliek, izraisa jaunu RDB uz primārā ar vēl vienu fork un smagu tīkla pārraidi. Izvēlieties replikācijas rezerves bufera izmēru atbilstoši rakstīšanas apjomam, lai īsi atvienojumi neizraisītu pilnu sinhronizāciju.
- Arī diagnostikai vajag uzmanību.
KEYS,DEBUGkomandas vai lielsSCANcount no klēpjdatora pret 100 GB primāro var izraisīt tieši to lēcienu, ko izmeklējat. Kur iespējams, analīzei izmantojiet repliku.
Praktiska pārbaužu secība
- Mēriet no abām pusēm:
--latencyno lietotnes hosta un no Redis hosta, un--intrinsic-latencyuz servera. - Izlasiet
SLOWLOG GETun salīdziniet ierakstus ar taimautu laiku. - Ieslēdziet latentuma monitoru un pārbaudiet
LATENCY LATESTunLATENCY DOCTOR. - Salīdziniet lēcienus ar momentuzņēmumiem, AOF pārrakstīšanu, derīguma beigu viļņiem un izlaidumiem.
- Pārbaudiet OS: THP, mijmaiņu, diska latentumu, CPU steal virtuālajās mašīnās.
Galvenās atziņas
- Redis latentuma lēcieni parasti ir kaut kas, kas bloķē galveno pavedienu, vai kaut kas ārpus Redis.
--intrinsic-latencyuz hosta parāda grīdu, kuru neviena Redis noregulēšana nepārspēs.- SLOWLOG noķer lēnas komandas; latentuma monitors (pēc noklusējuma izslēgts) noķer fork, AOF, derīguma beigu un izlikšanas apstāšanos.
- Aizstājiet
KEYSarSCAN, lielu atslēguDELarUNLINKun izkliedējiet TTL. - Lielās instancēs plānojiet fork laiku, kopēšanas-pie-rakstīšanas atmiņu un lielās atslēgas, pirms tās izraisa incidentu.