Cloud Native Uygulamalarda İzlenebilirlik — 3. Bölüm

Serdar Kalaycı
Intertech
Published in
9 min readSep 1, 2020

Yazımın ilk bölümünde izlenebilirlik başlığı altındaki kavramların neler olduğuna, ikinci bölümünde de bu kavramlardan Gözlemleme, Loglama ve Metrik Toplama konularının nasıl uygulanabileceğinden bahsetmiştik.Bu bölümde ise Metriklerin Analizi, Veri görselleştirme, Takip Etme ve Uyarma konularının nasıl uygulanacağını inceleyerek seriyi kapatacağız.

Metriklerin Analizi

Uygulamalarımız, servislerimiz ve platform hakkında toplayabileceğimiz bir çok metrikten bahsettik, ancak metriklerin toplanması tek başına anlamlı değildir. Bu metriklerin doğru bir şekilde işlenerek aksiyona dönüştürülmesi gerekecektir.

Ortalama, medyan, yüzdebirlik

Zaman serisi olarak toplanan verinin işlenmesi için akla ilk gelen değerlerin ortalamasının alınmasıdır. Ancak istatistikçilerin eski bir şakası ortalamanın ne kadar yanıltıcı olabileceğini çarpıcı bir biçimde vurgular; istatistiksel olarak çoğu insan ortalamadan fazla parmağa sahiptir. Kaza, hastalık vb nedenlerle parmaklarını kaybetmiş olan insanlar nedeniyle toplam nüfusta ortalama parmak sayısı 10’un biraz altında çıkacaktır, bu nedenle 10 parmağa sahip insanlar ortalamadan fazla parmak sayısına sahiptir denebilir.

Ortalama, tüm değerlerin toplanması ve örnek sayısına bölünmesi ile bulunur. Yukarıdaki örnekte bir adet aykırı (outlier) örnek nedeniyle ortalama yükselmekte ve nüfusun %90’ı ortalamanın altında boya sahip olarak görünmektedir.

Bir örnek seti sıralandıktan sonra ortada kalan değer olarak tanımlanan medyan, aykırı değerler konusunda ortalamadan daha başarılı olsa da yine ortalama gibi dağılımın daha iyi olduğu durumlarda iyi sonuçlar vermektedir. Yukarıdaki örnekte grubun ortasındaki sarı renkli birey medyan olarak kabul edilmiş, bu nedenle nüfusun geri kalanından çok daha uzun olmasına rağmen turuncu renkli birey kısa boylu olarak nitelendirilmiştir.

Yüzdebirlik (veya yukarıdaki örnekte olduğu gibi yüzdeonluk) hesabı tüm örnekleri yüzdelik aralıklarla gruplamak temeline dayanmaktadır. Bu sayede hem daha hassas gruplandırılmış veri elde edebilir, hem de p99 veya p95 kayıtları dikkate alarak aykırı değerlerlerin bizi yanıltmasını da engellemiş olabiliriz.

Tabi ki her veri türü farklı yaklaşımlarla incelenmeyi gerektirir. Travis CI (https://travis-ci.org) ekibinden Igor Wielder da bir makalesinde (https://igor.io/latency) latency verisinin nasıl işlenebileceğine dair güzel örnekler sunuyor.

10 dakika boyunca toplanan süre verisi ham olarak bakıldığında çok da aksiyon çıkartılacak halde olmadığından öncelikle 10’ar saniyelik aralıklarla ortalama alınıyor.

Ortalama alındığında 10’ar saniyelik periyotlarda latency 50ms’nin üzerine çıkmıyor gibi görünüyor. Ortalamanın ne kadar aldatıcı olabileceği bu görsel ile de ortaya çıkıyor.

10’ar saniyelik periyotlarda en yüksek çıkan değerin değerlendirme dışında bırakıldığı (outlier olarak görüldüğü) ve bir sonraki en yüksek değerin alındığı (yani ortalama yerine maksimum değerin görselleştirildiği) percentile 99 grafiği aşağıdaki gibi oluşmaktadır.

Bu grafiğe bakıldığında her 10 saniyede en az bir talebin 200ms’nin üzerine çıktığı, 500ms’nin etrafında yoğunluk oluştuğu görülebilmektedir.

Histogram

Histogram bu türden zaman serisi verilerini çok daha efektif tutmamızı sağlayan bir yöntemdir. Histogram verisi, percentile gruplarına giren veri sayısını tutmaya dayalı bir yöntemdir. Yukarıda bahsedilen ham veri histogram olarak aşağıdaki gibi tutulabilir.

Veriler histogram olarak tutulduğunda Counter tipinde bir veriye dönüşmekte, hem kolay tutulabilir hem de kolay görselleştirilebilir hale gelmektedir. Bu türden verinin en kolay okunabileceği format heatmap adı verilen görselleştirme yöntemidir. Yukarıdaki verinin yine 10’ar saniyelik periyotlarla görselleştirildiği bir heatmap grafiği aşağıdaki gibidir;

Bu gösterim sayesinde hem verinin nerelerde yoğunlaştığı kolaylıkla görülebilmekte, hem de zaman içinde yaşanan değişimleri takip etmemizi kolaylaştıracaktır.

Veri Görselleştirme (Data Virtualization)

İzlenebilirlik başlığı altında topladığımız verilerin de kolay anlaşılır, verideki değişimlerin kolay algılanabilir ve alınacak aksiyonun kolaylıkla belirlenebilir olması verilerin toplanması kadar önemlidir. Üzerinde aksiyon alınmayan verinin toplanmasının da bir anlamı olmayacaktır. İnsan beyninin görsel veriyi metinsel veriden çok daha hızlı işlediğini ve daha kolay sakladığını bildiğimize göre sayısal ham verinin görsel veriye çevrilmesi gerekmektedir. Hem doğrudan bağlanabildiği veri kaynaklarının çeşitliliği, hem de zengin görselleştirme seçenekleri nedeniyle Grafana (https://grafana.com) ürünü bu anlamda en yaygın kullanılan ürün haline gelmiştir.

Grafana ile burada örnekleyebileceğimizden çok daha detaylı görselleştirme araçları kullanılabilir, ancak görselleştirmenin gücünü gösterebilmek amacıyla aşağıdaki basit örneğe bir göz atalım.

Uygulamamızın 10’ar saniyelik aralıklarda hizmet verdiği talep sayısını topladığımız aşağıdaki veri kümesini düşünelim:

Tabloya bir göz attığımızda çok anlam çıkartmak mümkün olmayabilir, ancak aşağıdaki şekilde görselleştirildiğinde 20. saniye sonrasında hizmet verdiğimiz talep sayısının düzenli bir düşüşe geçtiğini görebiliriz.

Aynı veriyi biraz daha uzun vadede incelersek

yine insan gözüyle algılayabileceğimiz bir örüntü yakalamak çok mümkün olmasa da bu verinin grafiğinde

uygulamamızın hizmet verebildiği talep sayısının dakikada bir arttığını sonra düzenli bir düşüşe geçtiğini görebiliriz. Bu grafik bile tek başına alınabilecek aksiyonlar hakkında bir fikir verebilir. Örneğin eğer kullandığımız programlama dili garbage collector içeriyorsa onun loglarına bakmamız (bkz: Çalışma Zamanı Metrikleri) benzer bir örüntü ortaya koyabilir, bu da uygulamızda değişkenleri kullanma şeklimizde bir problem olduğuna işaret edebilir.

Weave Works (https://www.weave.works/) firmasından Tom Wilkie, bir blog yazısında (https://www.weave.works/blog/the-red-method-key-metrics-for-microservices-architecture/) tüm servisler için RED metriklerinin tek bir dashboard içinde görselleştirilmesini öneriyor. Bu şekilde tek bir ekranda tüm servislere aynı bakış açısı ile bakmanın metrikleri takip eden insanlar için algılamanın çok daha kolay olduğu iddia ediliyor. Aşağıdaki örnekte her bir servis için soldaki grafikte Rate ve Error verisi, sağdaki grafikte Duration verisi görselleştirilmiş durumdadır.

Ancak yüzlerce servisimizi olduğu bir ortamda tek bir dashboard üzerinde bu kadar servisin takip edilmesi de çok gerçekçi olmayacağından tüm servislerin verilerinin toplamının da merkezi bir dashboard üzerinde toplanması ve bu dashboard görüntüsünün tüm ekip tarafından takip edilebileceği büyük bir ekrana yansıtılması da önerilen bir yöntemdir.

Hem servis bazında hem de toplu dashboard’larımızı hazırlamamız için Grafana, hazır olarak birçok panel tipi destekler halde gelmektedir.

Graph

Line, Bar veya Historgram şeklinde kullanılabilir. Bir verinin bir başka veriye veya zamana göre değişimini göstermek için kullanılır.

Stat

Bir bakışta görülmesi istenen bir veya birden çok değeri göstermek için sıklıkla kullanılır. Özellikle özet bilgiler için idealdir.

Gauge

Bir üst limiti olan veri tiplerinin görselleştirilmesi için idealdir. Standart veya bar modunda kullanılabilir.

Heatmap

Özellikle histogram verisinin zamana bağlı gösteriminde kullanılır. Histogram olarak gruplandırılmış verinin zaman içerisinde hangi gruplarda yoğunlaştığını görmek için idealdir.

Takip Etme (Tracing)

Takip etme konusunda CNCF mezunu bir proje olan Jaeger (https://www.jaegertracing.io) en çok kullanılan uygulamadır. Jaeger tarafından da desteklenen ve takip verilerinin standardize edilmesini amaçlayan bir CNCF projesi olan OpenTracing (https://opentracing.io) ve Google’a ait açık kaynak bir ürün ve onun standarlarını belirleyen proje olan OpenCencus (https://opencensus.io) birleşerek OpenTelemetry (https://opentelemetry.io) adını almıştır. Bu proje kapsamında çeşitli programlama dilleri için (an itibariyle Go, JavaScript, Java, Python, Ruby, PHP, Objective-C, C++ ve C# dilleri için kütüphane mevcuttur) geliştirilen kütüphaneleri kullanarak uygulamanızın bu standartlara uygun telemetri verisini oluşturmasını sağlayabilir ve Jaeger gibi bu standartları destekleyen araçlara bu veriyi iletebiliriz.

OpenTracing standardı her bir servisteki mantıksal bir iş kümesini Span olarak adlandırır. Bir span’in her bir çalışmasına da Trace adı verilir. Span bilgisi context üzerinden servisler arasında paylaşılarak uçtan uca ölçüm yapabilmesini olanaklı kılar.

Service Mesh

Yaptığı tek iş takip olmasa da bu bağlamda Service Mesh araçlarından bahsetmekte yarar olacaktır. En popüler Service Mesh uygulamaları bir CNCF projesi olan Linkerd (https://linkerd.io) ve Google tarafından geliştirilen Istio (https://istio.io) projeleridir. Service Mesh uygulamaları Kubernetes’in bir pod içinde birden fazla container çalıştırabilme imkanından yararlanarak sidecar yaklaşımını uygular. Her pod’un içine enjekte edilen bu sidecar proxy uygulamaları (Linkerd kendi projesi kapsamında geliştirilen bir proxy kullanmakta, Istio ise bir CNCF projesi olan Envoy Proxy (https://www.envoyproxy.io) aracını kullanmaktadır) pod’a giren ve çıkan tüm trafiği kendi üzerinden akıtmak suretiyle takip etmekte ve her iki ürün de bu verileri Prometheus veritabanına yazmaktadır.

Telemetri verilerinin yanı sıra bu trafik verisi bu iş için özel olarak geliştirilmiş ürünlerle topoloji haritası üzerinde görselleştirilmesi için de kullanılabilmektedir. Red Hat tarafından geliştirilen Kiali (https://kiali.io) servislerin topolojisini, anlık olarak hangi servisler arasında iletişim olduğu, servislerin sağlık durumları, servislerin versiyonları arasındaki yük dağılımı gibi verileri topoloji üzerinde gösterebilmektedir.

Uyarma (Alerting)

Prometheus gibi metrik verisi toplayan araçlar bu metrikler üzerinde kural tabanlı uyarılar oluşturulmasına da izin vermektedir. Ancak sistemde oluşan tek bir problem birkaç farklı metrikte uyarı oluşmasına yol açacak veriler üretebilir, veya bir metrik uyarı eşiğinin altında/üstünde belirli bir süre kaldığında belirli aralıklarla aynı uyarıyı tekrar tekrar üretebilir. Ayrıca bu sistemler uyarının kimlere ve nasıl iletileceği hakkında bilgi sahibi değildir. Bu nedenle uyarıları yöneten bir uygulamaya ihtiyaç duyulur. Bu uygulamaların şu özelliklere sahip olması beklenir:

  • Gruplama: Uyarı sistemi, birbiriyle ilgili olduğu bilinen uyarıları gruplayabilmeli ve alıcılarına tek bir bilgilendirme olarak gönderebilmelidir. Örneğin ortak bir veritabanına bağlantı sorunu yaşayan birden fazla servisten gelen uyarılar ilgili veritabanı bilgisi ve ulaşamayan servislerin bir listesini içeren tek bir bilgilendirmeye dönüştürülebilmelidir.
  • Engelleme: Uyarı sistemi halihazırda bilgilendirme yapılmış bir uyarı ile ilgili olduğunu bildiği diğer uyarılarda bilgilendirme yapmamalıdır. Örneğin bir cluster’ın çalışmadığı konusunda bir uyarı hakkında bilgilendirme yapılmışsa o cluster üzerinde çalışan servislerden gelen uyarılar, cluster hakkındaki uyarı çözülene kadar engellenebilmelidir.
  • Susturma: Her bir uyarı için uyarının bilgilendirmesinin yapılmasından sonra belirli bir süre susturulabilmesine izin vermelidir. Örneğin bir sistemin yeniden çalıştırılması yarım saat sürüyor ve bu bilinen ve kabul edilen bir durum ise, ilk uyarından sonra yarım saat boyunca gelen uyarılarda bilgilendirme yapılmamalıdır.

Genellikle altyapı sistemleri sunan ürünlerin/firmaların (Microsoft, Vmware vb) uyarma sistemleri kendi içinde geldiğinden ve bu ürünler de dışarıdan aldıkları uyarıları da dağıtabildiğinden şirketler ellerindeki uyarı sistemleri ile entegre etmek eğilimde olmaktadır. Ancak elimizde böyle bir ürün yoksa Prometheus Alertmanager (https://prometheus.io/docs/alerting/alertmanager) Prometheus içinde yukarıdaki fonsiyonaliteyi (hatta daha fazlasını) sağlayan bir bileşen olarak kullanılabilir.

Uyarı sistemlerinde hedefimiz mümkün olduğunca az bilgilendirme göndermektedir. Aksi halde uyarı sistemimiz “yalancı çoban” durumuna düşebilir ve gerçekten önemli olan uyarıların gözden kaçmasına neden olabilir. Burada kendimize gönderilmesi gereken hiçbir uyarıyı atlamamak, ama kimseye de “bunun bana gelmesine gerek yoktu” dedirtmemek gibi bir kural koyabiliriz.

Uyarı sisteminde asla atlanmaması gereken bir konu da uyarı sisteminin yedekli olması ve uyarı sisteminin de izlenebilirliğinin tam olması gerektiğidir.

Sonuç

Uygulamaların dağıtık mimariye geçirilmesi için oldukça fazla sayıda geçerli neden var. Yatayda genişletilebilirlik, kaynakların etkin kullanımı, kesintisiz canlıya alım, A-B testleri yapma imkanı bunlardan birkaçı. Ancak uygulamalar dağıtıklaştıkça karmaşıklığı da artmakta, monolitik uygulamalarda karşılaşmadığımız bazı zorluklar da bizi beklemekte. Örneğin monolitik uygulamada yöntemden bağımsız olarak zaten bir arada olan log kayıtlarını dağıtık uygulamalarda bir araya getirmek veya monolitik uygulamalarda hiç ihtiyaç duymadığımız izleme gibi teknikleri devreye almak zorundayız. Gerçek anlamda “izlenebilirlik” tek bir araçla ve bir kaç tuşa basarak ulaşabileceğimiz bir hedef değil artık. Ancak CNCF gibi oluşumlar ve bu oluşumları destekleyen firmalar sayesinde ulaşılamaz bir hedef de değil. Bu amaçla geliştirilmiş bir çok açık kaynak araç ve bu araçları geliştiren ve kullanan açık kaynak topluluklarının destekleri sayesinde doğru araç ve doğru taktiklerle uygulamalarımızı izlenebilir kılmak ve dolayısıyla kullanıcı memnuniyetimizi üst seviyelere taşımak mümkün.

--

--