...

Narzędzia bcc w praktyce: praktyczny przewodnik po inżynierii wydajności systemu Linux z wykorzystaniem eBPF

Pokażę krok po kroku, jak narzędzia bcc wykorzystuję eBPF do szybkiego lokalizowania i usuwania wąskich gardeł na serwerach z systemem Linux. W tym celu stosuję praktyczne schematy działania, mierzę rzeczywiste opóźnienia w jądrze systemu oraz łączę zdarzenia z procesora, operacji wejścia/wyjścia i sieci w jedną czysty Analiza przyczyn.

Punkty centralne

  • eBPF zapewnia dogłębne śledzenie przy niewielkim obciążeniu.
  • narzędzia bcc obejmują procesor, wejścia/wyjścia, sieć i procesy.
  • Związane z produkcją można z niego korzystać bez wprowadzania zmian w aplikacji.
  • Lista kontrolna z dziesięcioma narzędziami na początek.
  • Bezpieczeństwo dzięki narzędziu Verifier i jasnym zasadom.

Dlaczego eBPF jest przydatny w inżynierii wydajności systemu Linux

Sięgam po eBPF, ponieważ chcę mierzyć zdarzenia jądra w sposób bezpieczny, selektywny i przy bardzo niewielkim obciążeniu. Klasyczne narzędzia pokazują sumy, ale rzadko wyjaśniają, dlaczego wątki czekają, pakiety są wysyłane ponownie lub operacje wejścia/wyjścia utknęły; eBPF wypełnia tę lukę dzięki konkretne Zdarzenia. Programy działają w jądrze, weryfikator sprawdza je wcześniej, a ja mogę je uruchomić bez konieczności ponownego uruchamiania systemu. W ten sposób koreluję wywołania z przestrzeni użytkownika ze ścieżkami jądra i uzyskuję obraz, który pozwala na natychmiastowe optymalizacje. Osoby, które chcą pogłębić swoją wiedzę, znajdą przegląd tematu w moim krótkim wprowadzeniu do Analiza wydajności eBPF, w którym nakreślono wzajemne powiązania między śledzeniem a obserwowalnością.

Czym są narzędzia BCC i gdzie je znajdę?

Die bcc Narzędzia „tools” to gotowe programy diagnostyczne oparte na eBPF, które zazwyczaj znajdują się w katalogu /usr/share/bcc/tools. Uruchamiam je bezpośrednio w powłoce, otrzymuję przejrzyste dane wyjściowe i nie muszę modyfikować moich aplikacji. Zbiór ten obejmuje procesy, wywołania systemowe, systemy plików, operacje wejścia/wyjścia blokowego, sieć, harmonogram i profilowanie, dzięki czemu nadaje się do wydajne Analizy. Ponieważ celowo włączam śledzenie, jego wpływ jest niewielki, a błędy pomiarowe wynikające z monitorowania są niewielkie. W bardziej złożonych przypadkach uzupełniam narzędzia o własny eBPF lub dodatkowo stosuję profile próbkowania.

Instalacja i wymagania

Instaluję bcc narzędzia dostępne za pośrednictwem menedżera pakietów (bcc-tools lub bpfcc-tools) w popularnych dystrybucjach. Wymagane są: jądro obsługujące eBPF (wersja 4.x lub nowsza, najlepiej 4.9+), włączone funkcje BPF oraz odpowiednie uprawnienia do ładowania programów. W przypadku serwerów produkcyjnych sprawdzam najpierw możliwości jądra i dystrybucji w zakresie eBPF w środowisku testowym, aby późniejsze pomiary niezawodny działają. Dzięki odpowiednio dostosowanym zasadom zapobiegam stosowaniu profili bezpieczeństwa, które całkowicie blokują eBPF. Praktyczny przegląd konfiguracji i obsługi zawierają zwięzłe wskazówki dotyczące narzędzia analityczne eBPF.

Przed uruchomieniem: kontrole systemu i bezpieczeństwa

Zanim przystąpię do pomiarów w środowisku produkcyjnym, sprawdzam podstawowe możliwości serwera. Dzięki temu unikam nieudanych uruchomień i uzyskuję powtarzalne wyniki.

  • Sprawdź funkcje jądra: uname -r oraz dostępne funkcje BPF (np. za pomocą Feature-Check). Istotne znaczenie mają kprobes/tracepoints, BTF (dla stabilnych informacji o typach) oraz zdarzenia perf.
  • Uprawnienia i zasady: Dbam o to, aby tylko uprawnieni użytkownicy mogli ładować eBPF (CAP_BPF/CAP_SYS_ADMIN lub odpowiednia zasada) oraz aby profile LSM nie blokowały tego procesu.
  • Parametry systemu: kernel.unprivileged_bpf_disabled jest zazwyczaj aktywne w środowiskach produkcyjnych. Dlatego świadomie pracuję w zabezpieczonych sesjach i z wyraźnym protokołem audytowym.
  • Przejrzyste ścieżki: Uważam, że katalogi takie jak /sys/kernel/debug/tracing oraz /sys/fs/bpf na oku, aby usunąć artefakty po pomiarach.

Dzięki tym środkom higieny mogę przeprowadzać pomiary w sposób precyzyjny i powtarzalny – bez efektów ubocznych.

Przewodnik praktyczny: Pierwsze dziesięć narzędzi

Aby szybko sprawdzić wydajność, stosuję ustaloną kolejność działań. Dzięki temu mogę precyzyjnie wyodrębnić przyczyny związane z procesorem, operacjami wejścia/wyjścia lub siecią i zdecydować, czy należy dokładniej przyjrzeć się stosom lub czasom. Tabela przedstawia główne zadania narzędzi oraz pytania, na które staram się za ich pomocą odpowiedzieć. Na początku ograniczam czas trwania pomiaru do minimum i powtarzam pomiary, gdy tylko pojawią się jakiekolwiek podejrzenia potwierdzać chcę. W ten sposób unikam martwych punktów i nie tracę czasu w nagłych Incydenty.

Narzędzie Zaobserwowano Typowe pytanie
execsnoop Nowe procesy Kto uruchamia krótkotrwałe zadania, które powodują obciążenie?
opensnoop Otwieranie plików Które ścieżki są stale otwierane lub rejestrowane?
ext4slower (xfs*, btrfs*, zfs*) Powolne operacje FS Które wywołania wykazują duże opóźnienia w poszczególnych woluminach?
biolatencja Rozkład operacji wejścia/wyjścia blokowego Czy występują sporadyczne lub długotrwałe skoki opóźnienia?
biosnoop Pojedyncze żądania wejścia/wyjścia Jaki proces powoduje awarię niektórych urządzeń?
cachestat Zachowanie pamięci podręcznej stron Czy warto zainstalować więcej pamięci RAM, czy też aplikacja będzie miała problemy?
tcpconnect Nowe połączenia TCP Kto, jak często i z jakiej usługi korzysta?
tcpaccept Zatwierdzone połączenia Które gniazda serwerowe są poddane dużemu obciążeniu?
tcpretrans Retransmisje Czy utrata paczki wskazuje na niestabilność ścieżek?
runqlat Opóźnienia harmonogramu Czy wątki czekają zbyt długo na czas procesora?

Używam również profile w celu wykrywania punktów newralgicznych w przestrzeni użytkownika lub jądra oraz agregowania stosów wywołań. Dzięki temu wykrywam kosztowne wyrażenia regularne, nieefektywne sterowniki lub spinlocki, które następnie eliminuję w kodzie lub w konfiguracji. Stosuję krótkie interwały próbkowania i porównuję wyniki kilku przebiegów, aby wyeliminować wartości odstające widoczny . To połączenie ogólnego przeglądu i dogłębnej analizy pozwala mi zaoszczędzić sporo czasu na analizę. Następnie ponownie testuję optymalizację przy tym samym obciążeniu.

Rozszerzenie: Wyświetlanie operacji poza procesorem, blokad i czasów oczekiwania

Nie każda wysoka latencja wynika z obciążenia procesora. Często wątki „poza procesorem“ oczekują na operacje wejścia/wyjścia, blokady lub sygnały wybudzenia. W takich sytuacjach pomocne są dodatkowe narzędzia i profile bcc:

  • Analiza poza procesorem: Mierzę, jak długo wątki nie znajdują się na procesorze oraz które stosy do nich prowadzą. Pozwala to oddzielić czas obliczeniowy od czasu oczekiwania i wskazać czynniki powodujące blokady.
  • Konflikty blokad: Analizuję w szczególności krytyczne blokady w jądrze i przestrzeni użytkownika. Długie czasy oczekiwania lub wysokie poziomy konfliktów wskazują na punkty szeregowości, które staram się wyeliminować (np. poprzez sharding, większą szczegółowość lub inne struktury danych).
  • Ścieżki budzenia: opóźnienia między momentem „został wybudzony“ a „znów działa“ wskazują na problemy z planowaniem i priorytetami lub zbyt duże pule procesów roboczych.

Koreluję te sygnały z runqlat oraz biolatencja, aby odróżnić przyczyny związane z pamięcią, operacjami wejścia/wyjścia i harmonogramem.

Higiena pomiarów: filtry, czas trwania, wartości progowe

Aby pomiary eBPF były powtarzalne, kieruję się trzema podstawowymi zasadami:

  • Krótko i na temat: na początku uruchamiam narzędzia tylko na krótko (np. na 10–30 sekund) i skupiam się na podejrzanych identyfikatorach PID, kontenerach lub gniazdach.
  • Ustawianie progów: W przypadku narzędzi typu „*slower“ odfiltrowuję niewielkie opóźnienia, aby zredukować szum i wyświetlać wyłącznie problematyczne wywołania.
  • Ograniczanie częstotliwości: Korzystam z filtrów selektywnych (np. nazwa procesu, identyfikatory TID, porty), aby utrzymać niską częstotliwość zdarzeń. Dzięki temu obciążenie pozostaje minimalne i unikam utraty zdarzeń.

Dopiero gdy dostrzegę pewien wzorzec, przedłużam czas trwania lub rozszerzam zakres. Dzięki temu uzyskuję czysty oraz wiarygodne próby.

Scenariusz praktyczny 1: Niewyjaśnione wysokie obciążenie procesora

Jeśli wskaźnik obciążenia procesora stale wskazuje wysokie wartości, zaczynam od execsnoop, aby wykryć procesy o krótkim czasie trwania. Następnie za pomocą runqlat mierzę, jak długo wątki czekają na czas procesora, i sprawdzam, czy kolejki uruchomień są przepełnione lub czy priorytety są nieodpowiednio ustawione. Jeśli czasy oczekiwania stają się zauważalne, zmniejszam liczbę procesów roboczych, zmieniam pule wątków lub rozkładam zadania cron, aby harmonogram chwyt może. Dzięki profilom gromadzę stosy i znajduję prawdziwe wąskie gardła w bibliotekach oraz we własnym kodzie. Dopiero po połączeniu tych wskazówek podejmuję decyzje dotyczące limitów, zbierania śmieci, powinowactw lub flag kompilatora.

Scenariusz praktyczny 2: Opóźnienia wejścia/wyjścia i powolne aplikacje

Jeśli użytkownicy skarżą się na zawieszanie się systemu przy niskim obciążeniu procesora, sprawdzam za pomocą ext4 wolniejszy powolne wywołania systemu plików na proces. Następnie za pomocą biolatency sprawdzam rozkład czasów operacji wejścia/wyjścia blokowego dla poszczególnych urządzeń, aby wykryć sporadyczne skoki lub trwałe wąskie gardła. biosnoop pokazuje mi, czy pojedyncza usługa generuje nadmierną liczbę drobnych operacji zapisu, powodując w ten sposób tworzenie się kolejek, które spowalniają inne procesy. Dzięki cachestat widzę, czy pamięć podręczna stron działa poprawnie, czy też występują nieudane operacje dominować i czy więcej pamięci RAM byłoby pomocne. Ostatecznie sam zdecyduję, czy opłaca się stosować zapis wtryskowy, większe bufory, czy też przejść na szybszą pamięć masową.

Scenariusz praktyczny 3: Ścieżki sieciowe i mikrousługi

W środowiskach rozproszonych zaczynam od tcpconnect, aby zmierzyć nawiązywanie połączeń między usługami. Następnie za pomocą tcpaccept sprawdzam, które gniazda serwera mają szczególnie dużo połączeń przychodzących i czy limity po stronie słuchacza są skuteczne. tcpretrans wykrywa ponowne wysyłanie danych i pozwala odróżnić problemy transportowe od błędów aplikacji, zanim dostosuję limity czasu i liczbę ponownych prób. Dzięki tym trzem sygnałom widzę, czy to sieć, aplikacja czy usługa nadrzędna jest przyczyną Opóźnienie napędza. Następnie dostosowuję strategie backoffu, wartości keepalive, ustawienia modułu równoważenia obciążenia oraz rozmiary buforów.

Bezpieczeństwo eksploatacyjne i niezawodność eBPF

Pobieram tylko godny zaufania Najpierw testuję własne programy eBPF na środowisku stagingowym. Verifier jądra blokuje błędne programy, ale dodatkowo ustalam limity dla map i buforów, aby pamięć była odpowiednio ograniczona. Zachowuję logi, aby śledzić zachowanie i skutki uboczne oraz w razie potrzeby móc szybko interweniować. Zasady określają, kto może ładować eBPF, dzięki czemu kontrola pozostaje w rękach zespołu platformy, a wymagania bezpieczeństwa są przestrzegane. Zasady te zapewniają, że śledzenie w środowiskach produkcyjnych Niezawodny pozostaje bez zmian i nie przynosi żadnych niespodzianek.

Środowiska kontenerowe i Kubernetes

W kontenerach oddzielam problemy o charakterze systemowym od efektów specyficznych dla poszczególnych podów. W tym celu filtruję pomiary według cgroup, przestrzeni nazw lub zakresu PID. Wiele narzędzi bcc umożliwia filtrowanie według nazw lub identyfikatorów procesów; alternatywnie dokonuję pomiarów na hoście i przypisuję zdarzenia do obciążeń za pomocą cgroup. Ważne:

  • Przestrzeń nazw PID: identyfikatory PID różnią się w przypadku hosta i kontenera. Mapuję te identyfikatory lub filtruję według nazw procesów/portów.
  • Limity zasobów: Ograniczanie wydajności procesora spowodowane limitami CFS objawia się długimi czasami oczekiwania przy braku pełnego obciążenia systemu. Rozpoznaję to na podstawie runqlat w połączeniu ze wskaźnikami dotyczącymi proporcji.
  • Przestrzenie nazw sieciowe: Podczas analizy gniazd zwracam uwagę na właściwą przestrzeń nazw. Dokonuję pomiarów na interfejsie hosta i koreluję wyniki z adresami IP i portami podów.

Dzięki temu wyniki pomiarów pozostają miarodajne, nawet jeśli wiele obciążeń działa w bliskim sąsiedztwie.

Integracja ze stosami rozwiązań do monitorowania

Nie zamierzam rezygnować z monitoringu, tylko uzupełniam go o eBPF. Narzędzia bcc zapewniają mi wgląd w szczegóły, podczas gdy systemy metryczne, logi i APM pokazują szerszy obraz; razem tworzą spójny obraz sytuacji. W razie potrzeby kieruję ślady z bcc do potoków logów, uruchamiam migawki w przypadku incydentów i dokumentuję ustalenia w zespole. W przypadku profilów punktowych korzystam z próbkowania jako uzupełnienia osi czasu opartych na metrykach, aby wykrywać anomalie namacalny zostaną. Ci, którzy dodatkowo preferują skrypty, znajdą w bpftrace w hostingu prosta metoda udzielania odpowiedzi na pytania ad hoc za pomocą mini-skryptów.

Typowe przeszkody – i jak je pokonuję

  • Noisy Neighbor: Poszczególne zadania generują krótkotrwałe, ale intensywne obciążenie. execsnoop plus profile niezawodnie wykrywam te wzorce; wyznaczam im limity czasowe lub izoluję je za pomocą współczynników.
  • NUMA i powiązania: Wysokie opóźnienia pomimo wolnych rdzeni wskazują na dostępy między strefami NUMA. Sprawdzam powiązania procesora, przypisanie pamięci oraz rozkład IRQ.
  • Punkty newralgiczne IRQ/SoftIRQ: Obciążenie sieciowe może doprowadzić do nasycenia jądra przez proces ksoftirqd. Obserwuję retransmisje, rozdzielam sygnały IRQ za pomocą RSS/kolejek oraz dostosowuję RPS/XPS.
  • Efekty związane z pamięcią podręczną stron: uruchomienia „na zimno” przebiegają wolniej. Uwzględniam fazy rozgrzewania i porównuję cachestat-Wartości przed i po obciążeniu.
  • Aktualizacje jądra: Kprobes mogą ulegać zmianom przy przejściu na nową wersję. Preferuję stabilne punkty śledzenia, przeprowadzam wcześniejsze testy i przygotowuję minimalny zestaw.

Sprawdzone procedury robocze

  • Zrzut stanu zdarzenia: 60–120 sekund łącznego działania (execsnoop, runqlat, biolatency, tcpretrans, profile). Następnie skupiam się na podsystemie, który wzbudził moje zainteresowanie.
  • Procedura bazowa: cotygodniowe krótkie pomiary na kluczowych ścieżkach (np. profil pamięci masowej i sieci). Dzięki temu mogę wcześnie wykrywać odchylenia.
  • Weryfikacja zmian: Przed wprowadzeniem zmian w konfiguracji i po ich wprowadzeniu porównuję te same punkty pomiarowe, aby móc oszacować efekt w sposób ilościowy.

Ciągłe optymalizowanie wydajności systemu Linux

Traktuję performans jako ciągły proces, a nie jako Działanie jednorazowe. W ramach CI/CD wdrażam krótkie testy oparte na eBPF, aby wcześnie wykrywać regresje i zapobiegać im przed wdrożeniem. W oknach serwisowych mierzę typowe ścieżki pod obciążeniem, tworzę wartości bazowe i dokumentuję dopuszczalne zakresy opóźnień. Dzięki temu szybko wykrywam odchylenia i unikam zgadywania podczas obsługi incydentów, ponieważ dane porównawcze dostępny. Procedura ta ma bezpośredni wpływ na dostępność, kontrolę kosztów i komfort użytkowania.

Mini-studium przypadku: Od objawu do przyczyny w 12 minut

Klaster API zgłasza wzrost opóźnień 99p przy niezmienionej wartości RPS. Tworzę migawkę zdarzenia: tcpconnect nie wykazuje żadnych nieprawidłowości podczas nawiązywania połączenia, tcpretrans pozostaje na niskim poziomie – sieć raczej nie. runqlat informuje o krótkich, ale częstych czasach oczekiwania; profile wyświetla punkty aktywności w formacie JSON. Równolegle obserwuję za pomocą cachestat spadek wskaźnika trafień w pamięci podręcznej w okresach szczytowego obciążenia. Korelacja sugeruje: wiele małych ładunków, które są synchronicznie serializowane i natychmiast zapisywane.

Sprawdzam za pomocą ext4 wolniejszy, co wskazuje na operacje fsync trwające kilka milisekund na tym samym woluminie dla procesu API; biolatencja Potwierdzono sporadyczne skoki długości kolejki na danym urządzeniu. Środek zaradczy: grupowanie operacji zapisu, większy bufor oraz asynchroniczne opróżnianie w mniej wrażliwych punktach. Po wdrożeniu opóźnienia 99p spadają o 35 %, wskaźnik trafień w pamięci podręcznej wraca do normy, a runqlat ponownie wykazuje wąskie rozkłady.

Podsumowanie dla praktyki

Z bcc Dzięki narzędziom i eBPF w krótkim czasie uzyskuję jasny obraz sytuacji dotyczącej procesora, operacji wejścia/wyjścia i sieci, bez konieczności wprowadzania zmian w aplikacjach. Lista narzędzi obejmująca execsnoop, opensnoop, ext4slower, biolatency, biosnoop, cachestat, tcpconnect, tcpaccept, tcpretrans i runqlat stanowi spójny punkt wyjścia. Dodatkowo wykorzystuję profile, aby zidentyfikować wąskie gardła i zoptymalizować ścieżki kodu. Dzięki przejrzystym zasadom, logowaniu i limitom wdrażanie w jądrze przebiega bez problemów. bezpieczny i przejrzysta. Kto konsekwentnie stosuje tę metodę, szybciej rozwiązuje problemy związane z wydajnością, lepiej planuje moce produkcyjne i obniża koszty w przeliczeniu na jedno zgłoszenie.

Artykuły bieżące