...

bcc tools i praksis: Praktisk vejledning til Linux-ydeevneoptimering med eBPF

Jeg viser trin for trin, hvordan jeg bcc-værktøjer bruger eBPF til hurtigt at indkredse og afhjælpe flaskehalse på Linux-servere. Her benytter jeg praktiske arbejdsgange, måler reelle forsinkelser i kernen og sammenkæder hændelser fra CPU, I/O og netværk til en klar Årsagsanalyse.

Centrale punkter

  • eBPF giver dyb sporingsfunktion med lav overhead.
  • bcc-værktøjer omfatter CPU, I/O, netværk og processer.
  • Produktionsnært kan bruges uden ændringer i appen.
  • Tjekliste med ti værktøjer til at komme i gang.
  • Sikkerhed ved hjælp af Verifier og klare retningslinjer.

Hvorfor eBPF til Linux-ydeevneoptimering

Jeg rækker ud efter eBPF, fordi jeg ønsker at måle kernelhændelser på en sikker og selektiv måde og med meget lidt overhead. Traditionelle værktøjer viser samlede tal, men de forklarer sjældent, hvorfor tråde venter, pakker sendes igen, eller I/O går i stå; eBPF udfylder dette hul med konkrete Begivenheder. Programmerne kører i kernen, verifikatoren kontrollerer dem på forhånd, og jeg kan starte dem uden at genstarte. På den måde kan jeg sammenholde userland-kald med kernestier og få et overblik, der muliggør øjeblikkelige optimeringer. Hvis du ønsker at dykke dybere ned i emnet, kan du finde en oversigt i min korte introduktion til eBPF-ydeevneanalyse, der skitserer samspillet mellem sporing og observabilitet.

Hvad er BCC-værktøjer, og hvor kan jeg finde dem?

Die bcc tools er færdige diagnosticeringsprogrammer baseret på eBPF og findes typisk i /usr/share/bcc/tools. Jeg starter dem direkte fra shellen, får tydelige standardudskrifter og behøver ikke at omprogrammere mine applikationer. Samlingen dækker processer, systemkald, filsystemer, blok-I/O, netværk, scheduler og profilering og er dermed velegnet til produktiv Analyser. Da jeg målrettet aktiverer sporing, er indflydelsen begrænset, og målefejl som følge af overvågningen er små. I mere komplekse tilfælde supplerer jeg værktøjerne med mit eget eBPF eller anvender desuden sampling-profiler.

Installation og krav

Jeg installerer den bcc værktøjer via pakkehåndteringen (bcc-tools eller bpfcc-tools) på gængse distributioner. Det kræver en kerne med eBPF-understøttelse (fra 4.x, helst 4.9+), aktiverede BPF-funktioner og tilstrækkelige rettigheder til at indlæse programmerne. På produktive servere tester jeg på forhånd kernelens og distributionens eBPF-funktioner i et testmiljø, så senere målinger pålidelig kører. Jeg forhindrer sikkerhedsprofiler, der blokerer eBPF fuldstændigt, ved hjælp af tilpassede politikker. De kortfattede vejledninger til opsætning og betjening giver et praktisk overblik over eBPF-analyseværktøjer.

Før start: System- og sikkerhedskontrol

Inden jeg foretager målinger i produktionen, kontrollerer jeg værtsenhedens grundlæggende funktioner. På den måde undgår jeg fejl ved opstart og opnår reproducerbare resultater.

  • Kontroller kernefunktioner: uname -r og tilgængelige BPF-funktioner (f.eks. via Feature-Check). Vigtige er kprobes/tracepoints, BTF (til stabile typeoplysninger) og perf-begivenheder.
  • Rettigheder og politikker: Jeg sikrer, at kun autoriserede brugere må indlæse eBPF (CAP_BPF/CAP_SYS_ADMIN eller tilsvarende politik), og at LSM-profiler ikke blokerer indlæsningen.
  • Systemparametre: kernel.unprivileged_bpf_disabled er normalt aktiv i produktive miljøer. Derfor arbejder jeg bevidst ud fra sikrede sessioner og med tydelig logføring.
  • Gennemsigtige stier: Jeg foretrækker mapper som /sys/kernel/debug/tracing og /sys/fs/bpf med henblik på at rydde op i artefakter efter målingerne.

Denne hygiejne sikrer, at jeg kan udføre målinger målrettet og på en reproducerbar måde – uden bivirkninger.

Praktisk vejledning: De første ti værktøjer

Til en hurtig ydeevne-tjek følger jeg en fast rækkefølge. På den måde kan jeg præcist indkredse årsagerne i CPU, I/O eller netværket og beslutte, om jeg skal se nærmere på stakker eller timinger. Tabellen viser værktøjernes hovedformål og det spørgsmål, jeg bruger dem til at afklare. Jeg holder kørselstiden kort i første omgang og gentager målingerne, så snart jeg har en mistanke bekræfte vil. På den måde undgår jeg blinde vinkler og spilder ikke tid på akutte Hændelser.

Værktøj Observeret Typisk spørgsmål
execsnoop Nye processer Hvem opretter kortvarige job, der skaber en byrde?
opensnoop Filttyper Hvilke stier åbnes eller logges løbende?
ext4 er langsommere (xfs*, btrfs*, zfs*) Langsomme FS-operationer Hvilke opkald viser høje ventetider pr. volumen?
biolatency Fordeling af blok-I/O Er der sporadiske eller vedvarende spidsbelastninger?
biosnoop Enkelte I/O-anmodninger Hvilken proces får visse enheder til at bryde sammen?
cachestat Side-cache-adfærd Er det værd at opgradere til mere RAM, eller oplever appen problemer?
tcpconnect Nye TCP-forbindelser Hvem henvender sig til hvilken service, og hvor ofte?
tcpaccept Godkendte forbindelser Hvilke serversockets er udsat for stor belastning?
tcpretrans Re-udsendelser Er tab af pakker et tegn på ustabile stier?
runqlat Scheduler-forsinkelser Venter trådene for længe på CPU-tid?

Jeg bruger også profiler for at identificere hotspots i bruger- eller kernelspace og sammenfatte call-stacks. På den måde opdager jeg ressourcekrævende regulære udtryk, ineffektive drivere eller spinlocks, som jeg derefter afhjælper i koden eller i konfigurationen. Jeg bruger korte sampling-intervaller og sammenligner flere kørsler, så outliers synlig bliver. Denne kombination af overblik og dybdegående analyse sparer mig for meget tid på analysen. Derefter tester jeg optimeringen igen under den samme belastning.

Udvidelse: Visning af off-CPU, låsninger og ventetider

Ikke alle tilfælde af høj latenstid skyldes CPU’en. Ofte venter tråde „off-CPU“ på I/O, låse eller wakeups. Her kan supplerende bcc-værktøjer og -profiler være til hjælp:

  • Off-CPU-analyse: Jeg måler, hvor længe tråde ikke befinder sig på CPU’en, og hvilke stakke der fører dertil. Dette adskiller regnetid fra ventetid og afslører blokeringer.
  • Låsekonflikter: Jeg ser specifikt på kritiske låse i kernen og brugerrummet. Lange ventetider eller høje konflikter tyder på serialiseringspunkter, som jeg bryder op (f.eks. ved hjælp af sharding, finere granularitet eller andre datastrukturer).
  • Wakeup-stier: Forsinkelser mellem „blev vækket“ og „kører igen“ afslører problemer med planlægning og prioritering eller for store worker-puljer.

Jeg sammenholder disse signaler med runqlat og biolatency, for at skelne mellem årsager relateret til hukommelse, I/O og scheduler.

Målehygiejne: Filtre, varighed, tærskelværdier

For at sikre, at eBPF-målingerne forbliver reproducerbare, følger jeg tre grundregler:

  • Kort og præcist: I starten lader jeg værktøjerne køre i kort tid (f.eks. 10–30 sekunder) og fokuserer på mistænkelige PID’er, containere eller sockets.
  • Indstilling af tærskelværdier: Når jeg bruger „*slower“-værktøjer, filtrerer jeg små forsinkelser fra for at reducere støj og kun se de problematiske opkald.
  • Begrænsning af frekvens: Jeg bruger selektive filtre (f.eks. procesnavn, TID'er, porte) for at holde begivenhedsfrekvensen lav. På den måde holdes overheadet på et minimum, og jeg undgår tabte begivenheder.

Først når jeg ser et mønster, forlænger jeg løbetiden eller udvider omfanget. På den måde får jeg ren og pålidelige stikprøver.

Praksisscenarie 1: Uforklarligt høj CPU-belastning

Hvis CPU-indikatoren konstant viser høje værdier, starter jeg med execsnoop, for at identificere kortvarige processer. Derefter måler jeg med runqlat, hvor længe tråde venter på CPU-tid, og kontrollerer, om køerne er overfyldte, eller om prioriteterne er forkert indstillet. Hvis ventetiderne bliver for lange, reducerer jeg antallet af arbejdstråde, ændrer trådpuljerne eller spreder cron-jobbene, så scheduleren Tag fat kan. Med profile samler jeg stacks og finder de egentlige hotspots i biblioteker og i min egen kode. Først når jeg har samlet disse oplysninger, træffer jeg beslutninger om grænser, garbage collection, affiniteter eller kompilerflags.

Praktisk scenario 2: I/O-forsinkelser og træge applikationer

Hvis brugerne klager over, at systemet fryser ved lav CPU-belastning, tjekker jeg med ext4 er langsommere langsomme filsystemkald pr. proces. Dernæst bruger jeg biolatency til at se på fordelingen af blok-I/O-tiderne pr. enhed for at opdage sporadiske spidsbelastninger eller vedvarende flaskehalse. biosnoop viser mig, om en enkelt tjeneste genererer et unormalt stort antal små skrivninger og dermed udløser kødannelse, der bremser andre processer. Med cachestat kan jeg se, om sidecachen rammer, eller om der er fejl dominere og mere RAM ville hjælpe. I sidste ende er det mig, der afgør, om batch-skrivninger, større buffere eller en overgang til hurtigere lagringsmedier vil betale sig.

Praksisscenarie 3: Netværksstier og mikrotjenester

I distribuerede miljøer starter jeg med tcpconnect, for at måle oprettelsen af forbindelser mellem tjenester. Derefter tjekker jeg med tcpaccept, hvilke serversockets der har særligt mange indgående forbindelser, og om begrænsningerne på listener-siden virker. tcpretrans afslører gentagne forsendelser og skelner mellem transportproblemer og applikationsfejl, inden jeg justerer timeouts og gentagelsesforsøg. Med disse tre signaler kan jeg se, om det er netværket, appen eller en upstream-tjeneste, der er årsagen til Forsinkelse . Derefter tilpasser jeg backoff-strategier, keepalive-værdier, load balancer-indstillinger og bufferstørrelser.

Driftssikkerhed og pålidelighed ved eBPF

Jeg uploader kun pålidelig Jeg tester mine egne eBPF-programmer først på Staging. Kernel-Verifier blokerer fejlbehæftede programmer, men jeg sætter desuden grænser for maps og buffers, så hukommelsesforbruget holdes inden for rimelige rammer. Jeg gemmer logfilerne for at holde øje med adfærd og bivirkninger og hurtigt kunne gribe ind, hvis det bliver nødvendigt. Politikker fastlægger, hvem der må indlæse eBPF, så kontrollen forbliver hos platformsteamet, og sikkerhedskravene overholdes. Disse regler sikrer, at sporing i produktionsmiljøer Pålidelig forbliver uændret og giver ingen overraskelser.

Container- og Kubernetes-miljøer

I containere adskiller jeg systematiske problemer fra pod-specifikke effekter. Til det formål filtrerer jeg målinger efter cgroup, navnerum eller PID-interval. Mange bcc-værktøjer tillader filtrering efter procesnavne eller -ID'er; alternativt foretager jeg målinger på værten og tildeler hændelser til arbejdsbelastningerne via cgroup. Vigtigt:

  • PID-navneområde: PID’erne er forskellige på værten og i containeren. Jeg kortlægger ID’erne eller filtrerer efter procesnavne/porte.
  • Ressourcekvoter: CPU-begrænsning via CFS-kvoter viser sig som lange ventetider, selvom systemet ikke udnyttes fuldt ud. Det kan jeg se ved hjælp af runqlat i kombination med kvotemålinger.
  • Netværksnavneområder: Ved socket-analyser er jeg opmærksom på, at jeg bruger det rigtige navneområde. Jeg foretager målinger på værtsgrænsefladen og sammenholder resultaterne med pod-IP-adresser og porte.

På den måde forbliver måleresultaterne pålidelige, selv når mange arbejdsbelastninger kører tæt på hinanden.

Integration i observability-stacks

Jeg erstatter ikke min overvågning, men supplerer den med eBPF. bcc-værktøjer giver mig dybden, mens metrik-systemer, logfiler og APM viser bredden; tilsammen giver det et sammenhængende billede. Om nødvendigt leder jeg traces fra bcc ind i log-pipelines, udløser snapshots ved hændelser og dokumenterer resultaterne i teamet. Til punktuelle profiler bruger jeg sampling som supplement til tidslinjer fra metrics, så afvigelser håndgribelig bliver. Hvis man desuden foretrækker scripting, finder man i bpftrace i hosting en enkel måde at besvare ad hoc-spørgsmål ved hjælp af miniskripter.

Almindelige forhindringer – og hvordan jeg kommer uden om dem

  • Noisy Neighbor: Enkelte job skaber en kortvarig, men intens belastning. execsnoop plus profiler disse mønstre afsløres pålideligt; jeg sætter tidsrammer for dem eller isolerer dem ved hjælp af kvoter.
  • NUMA og affiniteter: Høje ventetider på trods af ledige kerner tyder på adgang på tværs af NUMA-områder. Jeg tjekker CPU-affiniteter, hukommelsestilknytning og IRQ-fordeling.
  • IRQ/SoftIRQ-hotspots: Netværksbelastningen kan overbelaste ksoftirqd-kerner. Jeg overvåger retransmissioner, fordeler IRQ’er via RSS/køer og justerer RPS/XPS.
  • Effekter af sidecache: Koldstarter virker langsommere. Jeg tager højde for opvarmningsfaser og sammenligner cachestat-Værdier før og efter belastning.
  • Kernel-opdateringer: Kprobes kan ændre sig ved versionsskift. Jeg foretrækker stabile tracepoints, tester på forhånd og har et minimalt sæt klar.

Arbejdsgange, der har vist sig at fungere godt

  • Incident-Snapshot: 60–120 sekunders kombineret kørsel (execsnoop, runqlat, biolatency, tcpretrans, profile). Derefter fokuserer jeg på det påfaldende delsystem.
  • Baseline-rutine: Ugentlige korte målinger på centrale stier (f.eks. lager- og netværksprofil). På den måde opdager jeg afvigelser i god tid.
  • Validering af ændringer: Før og efter konfigurationsændringer sammenligner jeg de samme målepunkter for at kunne kvantificere effekten.

Løbende Linux-ydeevneoptimering

Jeg betragter performance som en løbende proces, ikke som Engangsaktion. I CI/CD integrerer jeg korte eBPF-baserede kontroller for at opdage regressioner tidligt og stoppe dem inden udrulningen. I vedligeholdelsesvinduer måler jeg typiske stier under belastning, opstiller baselinjer og dokumenterer acceptable latenstidsintervaller. På den måde opdager jeg afvigelser hurtigt og undgår at skulle gætte mig frem under en hændelse, fordi sammenligningsdata tilgængelig. Denne rutine bidrager direkte til tilgængelighed, omkostningsstyring og brugeroplevelsen.

Mini-casestudie: Fra symptom til årsag på 12 minutter

Et API-cluster melder stigende 99p-forsinkelser, mens RPS forbliver uændret. Jeg tager et snapshot af hændelsen: tcpconnect viser ingen uregelmæssigheder i oprettelsen af forbindelsen, tcpretrans forbliver lav – det er netværket tilsyneladende ikke. runqlat rapporterer korte, men hyppige ventetider; profiler viser hotspots i en JSON-serialisering. Samtidig overvåger jeg med cachestat et fald i cache-hitraten under spidsbelastninger. Korrelationen tyder på: Mange små payloads, der serialiseres synkront og skrives med det samme.

Jeg verificerer med ext4 er langsommere, der viser fsync-operationer på flere millisekunder på det samme volumen for API-processen; biolatency bekræfter sporadiske spidsbelastninger i køen på den berørte enhed. Modforanstaltning: Batching af skrivninger, større buffer og asynkron tømning på mindre følsomme punkter. Efter implementeringen falder 99p-latenserne med 35 %, cache-hitrate genoprettes, og runqlat viser igen smalle fordelinger.

Resumé til brug i praksis

Med bcc Med værktøjer og eBPF får jeg hurtigt et overblik over CPU, I/O og netværk uden at skulle ændre på applikationerne. Tjeklisten bestående af execsnoop, opensnoop, ext4slower, biolatency, biosnoop, cachestat, tcpconnect, tcpaccept, tcpretrans og runqlat udgør et godt udgangspunkt. Som supplement bruger jeg profile til at synliggøre hotspots og afhjælpe kodepatier. Takket være klare retningslinjer, logning og begrænsninger forbliver brugen i kernen sikker og overskuelig. Den, der konsekvent anvender denne metode, løser kapacitetsproblemer hurtigere, planlægger kapaciteten bedre og sænker omkostningerne pr. forespørgsel.

Aktuelle artikler