...

bcc tools in azione: guida pratica all'ingegneria delle prestazioni su Linux con eBPF

Vi mostrerò passo dopo passo come faccio a strumenti bcc utilizzo eBPF per individuare e risolvere rapidamente i colli di bottiglia sui server Linux. A tal fine, mi avvalgo di flussi di lavoro pratici, misuro le latenze effettive nel kernel e metto in relazione gli eventi provenienti da CPU, I/O e rete per ottenere un chiaro Analisi delle cause.

Punti centrali

  • eBPF garantisce un tracciamento approfondito con un overhead ridotto.
  • strumenti bcc coprono CPU, I/O, rete e processi.
  • Legato alla produzione Utilizzabile senza modifiche all'app.
  • Lista di controllo con dieci strumenti per iniziare.
  • Sicurezza grazie a Verifier e a politiche chiare.

Perché utilizzare eBPF per l'ingegneria delle prestazioni su Linux

Mi avvicino a eBPF, perché voglio misurare gli eventi del kernel in modo affidabile, selettivo e con un overhead minimo. Gli strumenti tradizionali mostrano i valori complessivi, ma raramente spiegano perché i thread rimangono in attesa, i pacchetti vengono reinviati o l’I/O si blocca; eBPF colma questa lacuna con concreto Eventi. I programmi vengono eseguiti nel kernel, il Verifier li verifica in anticipo e posso avviarli senza riavviare il sistema. In questo modo posso mettere in relazione le chiamate dell’userland con i percorsi del kernel e ottenere un quadro che consente ottimizzazioni immediate. Chi desidera approfondire l’argomento troverà una panoramica nella mia breve introduzione alla Analisi delle prestazioni di eBPF, che delinea l'interazione tra tracciamento e osservabilità.

Cosa sono gli strumenti BCC e dove posso trovarli?

Il sito bcc Gli strumenti sono programmi di diagnostica già pronti basati su eBPF e si trovano in genere nella directory /usr/share/bcc/tools. Li avvio direttamente dalla shell, ottengo output standard chiari e non devo modificare le mie applicazioni. La raccolta copre processi, chiamate di sistema, file system, I/O a blocchi, rete, scheduler e profilazione, rendendola adatta a produttivo Analisi. Poiché attivo il tracciamento in modo mirato, l'impatto rimane limitato e gli errori di misurazione dovuti al monitoraggio sono minimi. Per casi più complessi, integro gli strumenti con un eBPF personalizzato oppure utilizzo anche profili di campionamento.

Installazione e requisiti

Sto installando il bcc strumenti disponibili tramite il gestore di pacchetti (bcc-tools o bpfcc-tools) sulle distribuzioni più diffuse. Sono necessari un kernel con supporto eBPF (a partire dalla versione 4.x, preferibilmente 4.9+), le funzioni BPF attivate e diritti sufficienti per caricare i programmi. Sui server di produzione, verifico preventivamente le capacità eBPF del kernel e della distribuzione in un ambiente di test, in modo che le successive misurazioni affidabile funzionano. Impedisco l’applicazione di profili di sicurezza che bloccano completamente l’eBPF tramite politiche adeguate. Le brevi indicazioni su Strumenti di analisi eBPF.

Prima dell'avvio: controlli del sistema e di sicurezza

Prima di effettuare le misurazioni in produzione, verifico le competenze di base dell'host. In questo modo evito false partenze e ottengo risultati riproducibili.

  • Verifica delle funzionalità del kernel: uname -r e le funzioni BPF disponibili (ad esempio tramite Feature-Check). Sono importanti kprobes/tracepoints, BTF (per informazioni stabili sui tipi) e gli eventi perf.
  • Diritti e politiche: mi assicuro che solo gli utenti autorizzati possano caricare eBPF (CAP_BPF/CAP_SYS_ADMIN o politica equivalente) e che i profili LSM non ne impediscano il caricamento.
  • Parametri di sistema: kernel.unprivileged_bpf_disabled È solitamente attivo negli ambienti di produzione. Per questo motivo lavoro consapevolmente da sessioni protette e con un audit chiaro.
  • Percorsi trasparenti: ritengo che le directory come /sys/kernel/debug/tracing e /sys/fs/bpf con l'obiettivo di ripulire gli artefatti in base alle misurazioni.

Questa procedura igienica mi garantisce di eseguire misurazioni mirate e riproducibili, senza effetti collaterali.

Guida pratica: i primi dieci strumenti

Per un rapido controllo delle prestazioni seguo una sequenza fissa. In questo modo riesco a individuare con precisione se il problema è legato alla CPU, all’I/O o alla rete e decido se approfondire l’analisi degli stack o dei tempi. La tabella illustra la funzione principale degli strumenti e la domanda a cui mi permette di rispondere. Inizialmente mantengo breve la durata dell’esecuzione e ripeto le misurazioni non appena ho un sospetto confermare voglio. In questo modo evito i punti ciechi e non perdo tempo in situazioni di emergenza Incidenti.

Strumento Osservato Domanda tipica
execsnoop Nuovi processi Chi crea posti di lavoro precari che generano oneri?
opensnoop Apertura dei file Quali percorsi vengono costantemente aperti o registrati?
ext4 più lento (xfs*, btrfs*, zfs*) Operazioni FS lente Quali richieste presentano latenze elevate per volume?
biolatenza Distribuzione I/O a blocchi Si verificano picchi di latenza sporadici o persistenti?
biosnoop Singole richieste I/O Qual è il processo che mette in ginocchio determinati dispositivi?
cachestat Comportamento della cache delle pagine Vale la pena aumentare la RAM o l'app presenta dei problemi?
tcpconnect Nuove connessioni TCP Chi utilizza quale servizio e con quale frequenza?
tcpaccept Collegamenti accettati Quali socket del server sono sottoposti a un carico elevato?
tcpretrans Ritrasmissioni La perdita di pacchetti è indice di percorsi instabili?
runqlat Latenza dello scheduler I thread attendono troppo a lungo per ottenere tempo di CPU?

Uso anche profili per individuare i punti critici nello spazio utente o nello spazio del kernel e aggregare gli stack di chiamate. In questo modo individuo espressioni regolari dispendiose, driver inefficienti o spinlock, che poi risolvo nel codice o nella configurazione. Utilizzo intervalli di campionamento brevi e confronto più esecuzioni, in modo da individuare i valori anomali visibile . Questo mix di visione d'insieme e approfondimento mi fa risparmiare molto tempo nell'analisi. Successivamente, testo nuovamente l'ottimizzazione con lo stesso carico.

Estensione: rendere visibili le operazioni off-CPU, i lock e i tempi di attesa

Non tutte le latenze elevate sono legate alla CPU. Spesso i thread „off-CPU“ rimangono in attesa di operazioni di I/O, blocchi o wakeup. In questi casi sono utili gli strumenti e i profili bcc complementari:

  • Analisi off-CPU: misuro per quanto tempo i thread non sono attivi sulla CPU e quali stack li conducono lì. Questo permette di distinguere il tempo di calcolo dal tempo di attesa e di individuare i fattori di blocco.
  • Contesa sui blocchi: esamino in modo mirato i blocchi critici del kernel e dello spazio utente. Tempi di attesa prolungati o livelli elevati di contesa indicano punti di serializzazione che cerco di eliminare (ad esempio tramite sharding, una granularità più fine o strutture dati alternative).
  • Percorsi di riattivazione: le latenze tra „è stato riattivato“ e „è di nuovo in esecuzione“ evidenziano problemi di scheduling e di priorità oppure pool di worker troppo grandi.

Metto in relazione questi segnali con runqlat e biolatenza, per distinguere tra cause legate alla memoria, all'I/O e allo scheduler.

Igiene delle misurazioni: filtri, durata, soglie

Affinché le misurazioni eBPF rimangano riproducibili, mi attengo a tre regole fondamentali:

  • In breve e in modo mirato: all’inizio lascio girare gli strumenti solo per un breve periodo (ad esempio 10–30 secondi) e mi concentro su PID, container o socket sospetti.
  • Impostazione delle soglie: con gli strumenti „*slower“ filtro le piccole latenze per ridurre il rumore e visualizzare solo le chiamate problematiche.
  • Limitare la frequenza: utilizzo filtri selettivi (ad es. nome del processo, TID, porte) per mantenere bassa la frequenza degli eventi. In questo modo l'overhead rimane minimo ed evito la perdita di eventi.

Solo quando individuo uno schema, prolungo la durata o amplio l'ambito. In questo modo ottengo pulire e campioni rappresentativi.

Caso pratico 1: carico della CPU inspiegabilmente elevato

Se l'indicatore della CPU mostra costantemente valori elevati, inizio con execsnoop, per individuare i processi di breve durata. Successivamente, utilizzo runqlat per misurare per quanto tempo i thread rimangono in attesa di tempo CPU e verifico se le runqueue sono sovraffollate o se le priorità sono impostate in modo inadeguato. Se si riscontrano tempi di attesa anomali, riduco il numero di worker, modifico i thread pool o distribuisco i cronjob in modo che lo scheduler afferrare posso. Con profile raccolgo gli stack trace e individuo i veri punti critici nelle librerie e nel mio codice. Solo dopo aver messo insieme queste indicazioni, prendo decisioni relative a limiti, garbage collection, affinità o flag del compilatore.

Scenario pratico 2: latenze I/O e applicazioni lente

Se gli utenti segnalano blocchi con un carico ridotto della CPU, verifico con ext4 più lento Chiamate lente al file system per processo. Successivamente, con biolatency esamino la distribuzione dei tempi di I/O a livello di blocco per ciascun dispositivo, al fine di individuare picchi sporadici o colli di bottiglia persistenti. biosnoop mi mostra se un singolo servizio genera un numero eccessivo di piccole operazioni di scrittura, causando così un accumulo in coda che rallenta gli altri processi. Con cachestat verifico se la cache di pagina va a segno o se si verificano miss dominare e se una maggiore quantità di RAM sarebbe d'aiuto. Alla fine deciderò se conviene optare per le scritture in batch, buffer più capienti o il passaggio a un sistema di archiviazione più veloce.

Scenario pratico 3: percorsi di rete e microservizi

Negli ambienti distribuiti, inizio con tcpconnect, per misurare la creazione di connessioni tra i servizi. Poi, con tcpaccept, verifico quali socket del server registrano un numero particolarmente elevato di richieste in entrata e se i limiti sul lato listener sono efficaci. tcpretrans individua le ritrasmissioni e distingue i problemi di trasporto dagli errori dell’applicazione, prima che io regoli i timeout e i tentativi di riprova. Grazie a questi tre indicatori, posso capire se la rete, l’app o un servizio a monte è la causa del Latenza . Successivamente, adeguo le strategie di backoff, i valori di keepalive, le impostazioni del bilanciatore di carico e le dimensioni dei buffer.

Sicurezza operativa e affidabilità di eBPF

Carico solo affidabile Utilizzo gli strumenti e testo i miei programmi eBPF prima nell’ambiente di staging. Il Kernel Verifier blocca i programmi difettosi, ma impongo anche dei limiti per le mappe e i buffer, in modo che l’utilizzo della memoria rimanga ben circoscritto. Conservo i log per tenere sotto controllo il comportamento e gli effetti collaterali e intervenire rapidamente se necessario. Le policy stabiliscono chi è autorizzato a caricare eBPF, in modo che il controllo rimanga nelle mani del team della piattaforma e che i requisiti di sicurezza vengano rispettati. Queste regole garantiscono che il tracciamento negli ambienti di produzione Affidabile rimane tale e non riserva sorprese.

Ambienti container e Kubernetes

Nei container separo i problemi sistematici dagli effetti specifici dei pod. A tal fine filtro le misurazioni in base al cgroup, al namespace o all’intervallo di PID. Molti strumenti bcc consentono di applicare filtri in base al nome o all’ID del processo; in alternativa, effettuo le misurazioni sull’host e assegno gli eventi ai carichi di lavoro tramite cgroup. Importante:

  • Spazio dei nomi PID: i PID variano tra host e container. Effettuo una mappatura degli ID oppure applico un filtro in base ai nomi dei processi o alle porte.
  • Quote delle risorse: il throttling della CPU dovuto alle quote CFS si manifesta con lunghi tempi di attesa senza che il sistema sia utilizzato al massimo delle sue capacità. Me ne accorgo tramite runqlat in combinazione con gli indicatori relativi alle quote.
  • Spazi dei nomi di rete: per le analisi dei socket, mi assicuro di utilizzare lo spazio dei nomi corretto. Effettuo le misurazioni sull'interfaccia dell'host e le metto in correlazione con gli indirizzi IP e le porte dei pod.

In questo modo i risultati delle misurazioni rimangono significativi, anche quando molti carichi di lavoro vengono eseguiti in contemporanea a breve distanza l'uno dall'altro.

Integrazione negli stack di osservabilità

Non sostituisco il mio monitoraggio, ma lo integro con eBPF. Gli strumenti bcc mi forniscono la profondità, mentre i sistemi di metriche, i log e l’APM mostrano l’ampiezza; insieme danno vita a un quadro coerente. Se necessario, convoglio le tracce provenienti da bcc nelle pipeline dei log, attivo gli snapshot in caso di incidenti e documento i risultati con il team. Per i profili puntuali utilizzo il campionamento in aggiunta alle timeline delle metriche, in modo da individuare le anomalie tangibile saranno. Chi preferisce utilizzare anche lo scripting, troverà in bpftrace nell'hosting un modo semplice per rispondere a domande ad hoc utilizzando mini-script.

Ostacoli comuni – e come li supero

  • Noisy Neighbor: singoli processi generano un carico di breve durata ma intenso. execsnoop più profili Questi modelli vengono individuati in modo affidabile; li suddivido in intervalli di tempo o li isolo tramite quote.
  • NUMA e affinità: le elevate latenze nonostante la disponibilità di core liberi indicano accessi cross-NUMA. Verifico le affinità della CPU, l'allocazione della memoria e la distribuzione degli IRQ.
  • Punti critici IRQ/SoftIRQ: il carico di rete può saturare i kernel ksoftirqd. Monitoro le ritrasmissioni, distribuisco gli IRQ tramite RSS/code e regolo RPS/XPS.
  • Effetti della cache della pagina: gli avvii a freddo risultano più lenti. Prendo in considerazione le fasi di riscaldamento e faccio un confronto cachestat-Valori prima e dopo il carico.
  • Aggiornamenti del kernel: i Kprobes possono cambiare in caso di salti di versione. Preferisco utilizzare tracepoint stabili, li testo in anticipo e ne tengo a disposizione un set minimo.

Procedure operative che hanno dato buoni risultati

  • Panoramica dell'incidente: esecuzione combinata di 60–120 secondi (execsnoop, runqlat, biolatency, tcpretrans, profile). Successivamente mi concentro sul sottosistema che presenta anomalie.
  • Procedura di riferimento: misurazioni brevi settimanali sui percorsi principali (ad es. profilo di archiviazione e di rete). In questo modo riesco a individuare tempestivamente eventuali scostamenti.
  • Convalida delle modifiche: prima e dopo le modifiche alla configurazione, confronto gli stessi punti di misurazione per rendere quantificabile l'effetto.

Ingegneria continua delle prestazioni di Linux

Considero la performance come un processo in continua evoluzione, non come Azione una tantum. Nel CI/CD integro brevi controlli basati su eBPF per individuare tempestivamente eventuali regressioni e bloccarle prima del rollout. Durante le finestre di manutenzione, misuro i percorsi tipici sotto carico, definisco le linee di base e documento gli intervalli di latenza accettabili. In questo modo individuo rapidamente le anomalie ed evito di dover procedere per tentativi durante la gestione degli incidenti, poiché dispongo di dati di riferimento disponibile. Questa procedura contribuisce direttamente alla disponibilità, al controllo dei costi e all'esperienza utente.

Mini-caso di studio: dal sintomo alla causa in 12 minuti

Un cluster API segnala un aumento delle latenze al 99° percentile a parità di RPS. Avvio uno snapshot dell'incidente: tcpconnect non presenta anomalie nella connessione, tcpretrans rimane basso – ma la rete non lo è di certo. runqlat segnala tempi di attesa brevi ma frequenti; profili mostra gli hotspot in una serializzazione JSON. Parallelamente, osservo con cachestat un calo dei tassi di hit della cache durante i picchi. La correlazione suggerisce: molti payload di piccole dimensioni, serializzati in modo sincrono e scritti immediatamente.

Verifico con ext4 più lento, che mostra operazioni fsync della durata di diversi millisecondi sullo stesso volume per il processo API; biolatenza Conferma picchi sporadici nella coda sul dispositivo interessato. Contromisura: raggruppamento delle operazioni di scrittura, buffer più capiente e svuotamento asincrono in punti meno sensibili. Dopo l’implementazione, le latenze al 99° percentile diminuiscono di 35 %, il tasso di hit della cache torna a livelli normali e runqlat mostra nuovamente distribuzioni ristrette.

Sintesi per la pratica

Con bcc Grazie a tools ed eBPF riesco a farmi rapidamente un quadro chiaro della situazione relativa a CPU, I/O e rete, senza modificare le applicazioni. La checklist composta da execsnoop, opensnoop, ext4slower, biolatency, biosnoop, cachestat, tcpconnect, tcpaccept, tcpretrans e runqlat costituisce un punto di partenza coerente. Inoltre, utilizzo profile per individuare i punti critici e ottimizzare i percorsi di codice. Grazie a policy, registrazione e limiti ben definiti, l’utilizzo nel kernel rimane sicuro e trasparente. Chi applica questo metodo in modo coerente risolve più rapidamente i problemi di prestazione, pianifica meglio le capacità e riduce i costi per ogni richiesta.

Articoli attuali