Tahminlere değil verilere dayanarak gecikme ve prodüksiyon darboğazlarını araştırmak için Brendan Gregg’in pratik yöntemlerini (USE, RED, flame grafikleri) öğrenin.

Brendan Gregg, özellikle Linux dünyasında sistem performansı alanında en etkili isimlerden biridir. Yaygın olarak kullanılan kitaplar yazdı, pratik araçlar geliştirdi ve—en önemlisi—gerçek üretim sorunlarını araştırmak için net yöntemler paylaştı. Ekipler onun yaklaşımını benimsiyor çünkü baskı altında işe yarıyor: gecikme arttığında ve herkes cevap isterken, “belki X”ten “kesinlikle Y”ye az drama ile geçmek için bir yol gerekir.
Bir performans metodolojisi tek bir araç ya da zeki bir komut değildir. Ne bakılacağını, gördüğünüzü nasıl yorumlayacağınızı ve sonra ne yapacağınıza nasıl karar vereceğinizi belirten tekrarlanabilir bir inceleme yoludur.
Bu tekrarlanabilirlik tahminleri azaltır. En sezgili ya da en yüksek sesli kişiye güvenmek yerine, şu tutarlı süreci izlersiniz:
Birçok gecikme incelemesi ilk beş dakika içinde yanlış yöne gider. İnsanlar doğrudan düzeltmelere atlar: “CPU ekle,” “servisi yeniden başlat,” “cache'i büyüt,” “GC'yi ayarla,” “muhtemelen ağdır.” Bazı durumlarda işe yararlar—çoğunlukla sinyali gizler, zaman kaybettirir veya yeni riskler getirir.
Gregg’in yöntemleri, daha basit soruları cevaplayana kadar “çözümleri” ertelemenizi sağlar: Hangi kaynak doymuş? Hangi hatalar var? Hangi şey yavaşladı—throughput, kuyruğa alma veya bireysel işlemler mi?
Bu rehber, kapsamı daraltmanıza, doğru sinyalleri ölçmenize ve optimize etmeden önce darboğazı doğrulamanıza yardımcı olur. Amaç, sonuçların şansa bağlı olmadığı, üretimde gecikme ve profil sorunlarını araştırmak için yapılandırılmış bir iş akışıdır.
Gecikme bir belirtidir: kullanıcılar işin bitmesini daha uzun bekler. Neden genellikle başka yerdedir—CPU çatışması, disk veya ağ beklemeleri, kilit çatışması, çöp toplama, kuyruğa alma veya uzak bağımlılık gecikmeleri. Sadece gecikmeyi ölçmek, ağrının nereden kaynaklandığını söylemez.
Bu üç sinyal birbirine bağlıdır:
Ayarlamaya başlamadan önce aynı zaman penceresi için tüm üç sinyali yakalayın. Aksi takdirde işi düşürerek veya daha hızlı başarısız kılarak gecikmeyi “düzelttiğinizi” sanabilirsiniz.
Ortalama gecikme kullanıcıların hatırladığı sıçramaları gizler. 50 ms ortalaması olan bir servis yine de sık sık 2 s beklemelere sahip olabilir.
Yüzdelikleri izleyin:
Ayrıca gecikmenin şekline dikkat edin: p50 sabitken p99 yükseliyorsa genellikle aralıklı duraklamalar (ör. kilit çatışması, I/O takılmaları, stop-the-world duraklamaları) vardır, genel bir yavaşlama değil.
Gecikme bütçesi basit bir muhasebe modelidir: “İstek 300 ms içinde bitmeli ise zaman nasıl harcanabilir?” Bunu şu kategorilere ayırın:
Bu bütçe ilk ölçüm görevinizi çerçeveler: spike sırasında hangi kovanın büyüdüğünü belirleyin, sonra o alanı araştırın; körü körüne ayarlama yapmayın.
Gecikme çalışmaları “sistem yavaş” gibi tanımlandığında sapar. Gregg’in yöntemleri daha erken başlar: sorunu belirli, test edilebilir bir soruya zorlayın.
Herhangi bir aracı kullanmadan önce iki cümle yazın:
Bu, ağrının yanlış katmanı optimize etmenizi (ör. host CPU) engeller; çünkü sorun belirli bir uç nokta veya bağlı serviste olabilir.
Şikayetle eşleşen ve mümkünse “iyi” bir karşılaştırma dönemini içeren bir pencere seçin.
Soruşturmanızı açıkça sınırlandırın:
Burada kesin olmak, sonraki adımları (USE, RED, profil) hızlandırır çünkü hipotez doğruysa hangi verinin değişmesi gerektiğini bilirsiniz.
Dağıtımlar, yapılandırma değişiklikleri, trafik dalgalanmaları ve altyapı olaylarını not edin—ama nedenselliği varsaymayın. Bunları “Eğer X olsaydı, Y beklerdik” şeklinde yazın, böylece hızlıca doğrulayıp çürütebilirsiniz.
Küçük bir günlük ekipler arasındaki tekrar eden çalışmayı önler ve devirlerin daha düzgün olmasını sağlar.
Time | Question | Scope | Data checked | Result | Next step
Böyle beş satır bile stresli bir olayı tekrarlanabilir bir sürece dönüştürebilir.
USE Yöntemi (Utilization, Saturation, Errors) Gregg’in “büyük dörtlü” kaynakları—CPU, bellek, disk (depolama) ve ağ—tarafından hızlıca taramak için kontrol listesi gibidir; böylece tahmin etmeyi bırakıp sorunu daraltabilirsiniz.
Düzine grafiklere bakmak yerine, her kaynak için aynı üç soruyu sorun:
Tutarlı uygulandığında bu, nerede “baskı” olduğunu hızlıca gösteren bir envanter olur.
CPU için kullanım CPU meşguliyet %, doygunluk run-queue basıncı veya çalışmayı bekleyen thread'ler olarak görünür ve hatalar konteynerlerdeki throttling veya yanlış davranan interrupt'lar olabilir.
Bellek için kullanım kullanılan bellek, doygunluk sayfalama veya sık GC olarak kendini gösterir, hatalar ise allocation hataları veya OOM olaylarıdır.
Disk için kullanım cihaz meşguliyet süresi, doygunluk kuyruk derinliği ve okuma/yazma bekleme zamanı, hatalar ise I/O hataları veya zaman aşımıdır.
Ağ için kullanım throughput, doygunluk düşmeler/kuyruklar/gecikme ve hatalar tekrar göndermeler, reset'ler veya paket kaybıdır.
Kullanıcılar yavaşladı dediğinde, doyma sinyalleri genellikle en açıklayıcı olanlardır: kuyruklar, bekleme süreleri ve çatışma gecikme ile daha doğrudan korelasyon gösterir.
Servis seviyesindeki metrikler (istek gecikmesi, hata oranı gibi) etkiyi söyler. USE ise hangi kaynağın baskı altında olduğunu bularak nereye bakılacağını söyler.
Pratik döngü:
RED Yöntemi sizi host grafiklerine dalmadan önce kullanıcı deneyimine bağlı tutar.
RED, kullanıcıları etkilemeyen “ilginç” sistem metriklerinin peşinden gitmenizi engeller. Daha sıkı bir döngü kurar: hangi uç nokta yavaş, hangi kullanıcılar için ve ne zamandan beri? Eğer Duration sadece tek bir rotada yükseliyorsa ve genel CPU sabitse, zaten daha net bir başlangıç noktanız var demektir.
Faydalı bir alışkanlık: RED'i servis ve en çok kullanılan uç noktalar bazında kırın (veya ana RPC metotları). Bu, geniş çaplı bir bozulmayı yerel bir regresyondan ayırmayı kolaylaştırır.
RED size acıyı nerede gösterir. USE, hangi kaynağın sorumlu olduğunu test etmenize yardımcı olur.
Örnekler:
Düzeni basit tutun:
Tutarlı bir olay iş akışı istiyorsanız, bu bölümü /blog/use-method-overview ile eşleştirin ki “kullanıcı hissediyor”dan “bu kaynak kısıt”a daha az çabayla geçebilin.
Bir performans incelemesi dakikalar içinde onlarca grafik ve hipoteze patlayabilir. Gregg’in zihniyeti bunu dar tutmaktır: işiniz “daha fazla veri toplamak” değil, belirsizliği en hızlı şekilde ortadan kaldıracak sonraki soruyu sormaktır.
Çoğu gecikme sorunu tek bir maliyet (veya küçük bir çift) tarafından domine edilir: bir sıcak kilit, yavaş bir bağımlılık, aşırı yüklenmiş disk, tek tip GC duraklaması. Önceliklendirme, önce o baskın maliyeti aramak demektir; çünkü beş farklı yerde %5 azaltmak kullanıcı görebilir gecikmeyi nadiren etkiler.
Pratik test: “Gördüğümüz gecikme değişiminin çoğunu ne açıklayabilir?” Eğer bir hipotez yalnızca küçük bir dilimi açıklayabiliyorsa, düşük önceliklidir.
Yukarıdan aşağı kullanın eğer cevap "Kullanıcılar etkileniyor mu?" ise. Uç noktalardan (RED tarzı sinyaller) başlayın: gecikme, throughput, hatalar. Bu, kritik yol üzerinde olmayan bir şeyi optimize etmenizi engeller.
Aşağıdan yukarı kullanın eğer host açıkça hasta ise (USE tarzı semptomlar): CPU doygunluğu, kontrolsüz bellek basıncı, I/O bekleme. Bir düğüm tıpkıysa, uç nokta yüzdeliklerine bakmak boşuna zaman kaybı olur.
Bir uyarı geldiğinde bir dal seçip onu doğrulayana veya çürütünceye kadar o dalda kalın:
Başlangıç için küçük bir sinyal seti ile sınırlayın, sonra bir şey hareket ettiğinde derinlemesine inin. Bir kontrol listesine ihtiyacınız varsa, adımlarınızı bir runbook'a bağlayın (ör. /blog/performance-incident-workflow) ki her yeni metrikin bir amacı olsun: belirli bir soruyu cevaplamak.
Üretimde profil almak riskli gelebilir çünkü canlı sistemi etkiler—ama çoğu zaman tartışmayı kanıta dönüştürmenin en hızlı yoludur. Loglar ve panolar şeyin yavaş olduğunu söyleyebilir. Profil ise zamanın nereye gittiğini söyler: hangi fonksiyonlar sıcak, hangi thread'ler bekliyor ve hangi kod yolları olay sırasında baskın.
Profil, bir “zaman bütçesi” aracıdır. Teorileri tartışmak yerine ("veritabanı" mu yoksa "GC" mi), şu tür kanıtlar alırsınız: “CPU örneklerinin %45'i JSON ayrıştırmada” veya “çoğu istek bir mutex'te bloklanıyor.” Bu, sonraki adımı bir veya iki somut düzeltmeye daraltır.
Her biri farklı bir soruyu yanıtlar. Düşük CPU ile yüksek gecikme genellikle off-CPU veya kilit zamanına işaret eder, CPU sıcak noktalarına değil.
Birçok ekip talep üzerine başlar, güven oluşunca sürekli açık profillere geçer.
Üretim güvenli profil, maliyeti kontrol etmektir. Örneklemeyi tercih edin (her olayı takip etmek yerine), yakalama pencerelerini kısa tutun (ör. 10–30 saniye) ve önce bir kanarya üzerinde yükü ölçün. Emin değilseniz, düşük frekanslı örneklemeyle başlayın ve sinyal çok gürültülü ise artırın.
Flame grafikleri, örnekleme penceresindeki zamanın nereye gittiğini görselleştirir. Her “kutu” bir fonksiyon (veya stack frame) ve her yığın o fonksiyona nasıl ulaşıldığını gösterir. Hızlı desenleri fark etmek için mükemmeldir—ama otomatik olarak “hata burada” demezler.
Bir flame grafiği genellikle on-CPU örnekleri temsil eder: programın gerçekten bir CPU çekirdeğinde çalıştığı zaman. CPU-yakan kod yollarını, verimsiz ayrıştırmayı, aşırı serileştirmeyi veya gerçekten CPU harcayan sıcak noktaları vurgulayabilir.
Gecikmelerin nedeni olan disk, ağ, scheduler gecikmeleri veya bir mutex üzerinde bekleme gibi off-CPU zamanını doğrudan göstermez (bunun için farklı profil gerekir). Ayrıca, kullanıcı görünür gecikme ile ilişkilendirmek için dikkatle scoped bir semptomla ilişkilendirilmelidir.
En geniş kutuya suç atmak caziptir, ama sorun: değiştirilebilir bir sıcak nokta mı yoksa upstream bir sorunun (malloc, GC, logging) sonucu mu? Ayrıca bağlam eksikliğine (JIT, inlining, semboller) dikkat edin; bu bir kutuyu fail eden değil, sadece mesajcıymış gibi gösterebilir.
Flame grafiğini şu şekilde ele alın: hangi uç nokta, hangi zaman penceresi, hangi hostlar ve ne değişti? “Önce vs sonra” (veya “sağlıklı vs bozuk”) flame grafikleri ile aynı istek yolunu karşılaştırın ki profil gürültüsünden kaçının.
Gecikme artınca birçok ekip önce CPU%'e bakar. Bu anlaşılır—ama genellikle yanlış yöne işaret eder. Bir servis "sadece %20 CPU" kullanıyor olsa bile, thread'lerin çoğu çalışmıyor ise son derece yavaş olabilir.
CPU% “işlemci ne kadar meşgul” sorusuna cevap verir. Bir isteğin zamanının nerede geçtiğini söylemez. İstekler, thread'ler beklerken, bloklanırken veya scheduler tarafından park edilirken duraklayabilir.
Ana fikir: bir isteğin duvar saati zamanı hem on-CPU işi hem de off-CPU beklemeyi içerir.
Off-CPU zamanı genellikle bağımlılıklar ve çatışma arkasında gizlenir:
Bir kaç sinyal genellikle off-CPU darboğazlarıyla korelasyon gösterir:
Bu semptomlar “bekliyoruz” der, ama neye beklediğimizi söylemez.
Off-CPU profil, "neden çalışmıyordunuz"u işaret eder: syscalls içinde bloklanma, kilitlerde bekleme, uyuma veya deschedule edilme. Bu, gecikme işleri için güçlüdür çünkü belirsiz yavaşlamaları eyleme dönüştürülebilir kategorilere çevirir: “mutex X'te bloklanıyor”, “read() için disk bekliyor” veya “upstream'e connect() içinde takılıyor.” Beklemeyi isimlendirdiğinizde onu ölçebilir, doğrulayabilir ve düzeltebilirsiniz.
Performans çalışması genellikle aynı anda başarısız olur: biri kuşkulu bir metriği görür, "sorun bu" der ve ayarlamaya başlar. Gregg’in yöntemleri sizi yavaşlamaya ve sistemi sınırlayan şeyi kanıtlamaya zorlar.
Bir darboğaz, şu anda throughput'u sınırlayan veya gecikmeyi sürükleyen kaynak veya bileşendir. Onu rahatlatırsanız, kullanıcılar iyileşme görür.
Bir sıcak nokta, zamanın harcandığı yerdir (ör. profilde sık görünen bir fonksiyon). Sıcak noktalar gerçek darboğaz olabilir—veya yavaş yol üzerinde etkisi olmayan yoğun işler olabilir.
Gürültü, anlamlı görünen ama olmayan her şeydir: arka plan işler, tek seferlik sıçramalar, örnekleme artefaktları, cache etkileri veya kullanıcı görünür soruna korele olmayan “top talker”lar.
Temiz bir önce anlık görüntüsü ile başlayın: kullanıcıya yansıyan semptom (gecikme veya hata oranı) ve önde gelen aday sinyaller (CPU doygunluğu, kuyruk derinliği, disk I/O, kilit çatışması vb.). Sonra sadece şüpheli nedeni etkilemesi gereken kontrollü bir değişiklik uygulayın.
Nedensel test örnekleri:
Korelasyon bir ipucudur, hüküm değildir. Eğer “CPU arttığında gecikme artıyor” ise, CPU kullanılabilirliğini değiştirerek veya CPU işi azaltarak gecikmenin takip edip etmediğini doğrulayın.
Ne ölçüldü, yapılan tam değişiklik, önce/sonra sonuçları ve gözlemlenen iyileşmeyi yazın. Bu, tek seferlik bir kazanımı sonraki olay için tekrar kullanılabilir bir oyuna dönüştürür—ve sezgilerin sonradan tarihi yeniden yazmasını engeller.
Performans olayları acil hissettirir; tam da bu durumda tahminler devreye girer. Hafif, tekrarlanabilir bir iş akışı sizi “bir şey yavaş” durumundan “ne değiştiğini biliyoruz” noktasına thrash olmadan taşır.
Tespit: kullanıcıya yansıyan gecikme ve hata oranına göre uyarı verin, sadece CPU değil. Susturmalı bir pencere için p95/p99 eşiği aşıldığında sayfalayın.
Triyaj: hemen üç soruyu cevaplayın: ne yavaş, ne zaman başladı ve kim etkilendi? Kapsamı (servis, uç nokta, bölge, cohort) adlandıramıyorsanız optimize etmeye hazır değilsiniz.
Ölç: darboğazı daraltan kanıtları toplayın. Kıyaslama yapabilmek için zaman sınırlı yakalamaları tercih edin (ör. 60–180 saniye).
Düzelt: aynı anda tek bir değişiklik yapın, sonra aynı sinyalleri yeniden ölçerek iyileşmeyi doğrulayın ve placebo'yu elersiniz.
Olaylar sırasında herkesin kullandığı paylaşılan bir pano tutun. Sıkıcı ve tutarlı olsun:
Amaç her şeyi grafiklemek değil; ilk gerçeğe ulaşma süresini kısaltmaktır.
En çok önem taşıyan uç noktaları (checkout, giriş, arama) instrument edin, her uç nokta için beklenen p95, maksimum hata oranı ve ana bağımlılığı (DB, cache, üçüncü taraf) belirleyin.
Bir sonraki kesinti öncesi yakalama kitini kararlaştırın:
Bunu kısa bir runbook'ta (ör. /runbooks/latency) belgelen, kimlerin yakalama çalıştırabileceğini ve artefaktların nerede saklanacağını belirtin.
Gregg’in metodolojisi esasen kontrollü değişiklik ve hızlı doğrulama ile ilgilidir. Eğer ekibiniz hizmetleri Koder.ai kullanarak (web, backend ve mobil uygulamalar oluşturup yineleyen sohbet tabanlı bir platform) geliştiriyorsa, iki özellik bu zihniyete doğrudan uyar:
Olay sırasında yeni kod üretmiyor olsanız bile, küçük diff'ler, ölçülebilir sonuçlar ve hızlı geri alabilme alışkanlıkları Gregg’in önerdiği alışkanlıklarla örtüşür.
Saat 10:15 ve panonuz API için p99'un tepe trafik sırasında ~120ms'den ~900ms'ye çıktığını gösteriyor. Hata oranı sabit, ancak müşteriler "yavaş" isteklerden şikayet ediyor.
Servis-odaklı olarak başlayın: Rate, Errors, Duration.
Duration'ı uç nokta bazında dilimlediğinizde tek bir rota p99'u domine ediyor: POST /checkout. Rate 2× artmış, hatalar normal ama Duration özellikle eşzamanlılık artınca yükseliyor. Bu kuyruğa alma veya çatışmaya işaret eder, açık bir arıza değil.
Sonra gecikmenin hesaplama zamanı mı yoksa bekleme zamanı mı olduğunu kontrol edin: uygulama “handler süresi” ile toplam istek süresini karşılaştırın (veya izleme varsa upstream vs downstream span'leri). Handler süresi düşük, toplam süre yüksek—istekler bekliyor.
Muhtemel darboğazları envanterleyin: CPU, bellek, disk ve ağ için Kullanım, Doyma, Hatalar.
CPU kullanımı sadece ~%35, ama CPU run queue ve context switch'ler yükseliyor. Disk ve ağ stabil görünüyor. Bu uyumsuzluk (düşük CPU%, yüksek bekleme) klasik bir ipucu: thread'ler CPU yakmıyor—bloklanıyor.
Spike sırasında alınan off-CPU profili, paylaşılan “promotion validation” cache etrafında yoğun mutex bekleme süresi gösteriyor.
Global kilidi anahtar-bağımlı bir kilitle (per-key lock) veya kilitsiz bir okuma yoluyla değiştirin, dağıtın ve Rate yüksek kalırken p99'un normale döndüğünü izleyin.
Olay sonrası kontrol listesi: