Skip to content

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

28 Commits

Folders and files

Repository files navigation

Takım Adı: Data-X

Performans ve Analiz Raporu

Bu dosya, ödevinizin raporunu oluşturmanız için bir şablondur. Aşağıdaki başlıkları doldurarak kendi bulgularınızı, karşılaştırmalarınızı ve analizlerinizi ekleyin.


1. Depolama Sistemi Seçimi

Alan Açıklama
Seçtiğim Depolama Sistemi HDFS (Hadoop Distributed File System)
Gerekçem Büyük hacimli log veriler (5 milyon kayıt) dağıtık ortamda güvenli ve ölçeklenebilir şekilde saklanılabiliyor. Apache Spark ile doğal entegrasyonu sayesinde analitik sorgular yüksek performansla çalıştırılabiliyor.
Kurulum Notları Bir sorun yaşanmamıştır.
Erişilebilirlik Testi Hem docker exec namenode hdfs dfs -ls /logs/raw komutu ile hem de Namenode UI ile dosyaların başarıyla yüklendiğini doğruladım.
Alan Açıklama
Seçtiğim Depolama Sistemi MinIO
Gerekçem Veriler S3 uyumlu, hafif ve yüksek performanslı bir ortamda saklanabiliyor. Container tabanlı ortamlara uyumlu ve Parquet/ORC gibi sütun tabanlı dosya formatlarını doğrudan destekliyor.
Kurulum Notları Bir sorun yaşanmamıştır. HDFS zaten docker compose -f docker-compose-hdfs.yml stop komutu ile önceden durdurulup MinIO kurulumu yapılmıştır. Çakışma olsaydı bile yine bu komutu çalıştırarak çözüm bulurdum.
Erişilebilirlik Testi docker exec minio-client1 mc ls myminio komutu ile dosyaların başarıyla yüklendiğini doğruladım. Ayrıca docker exec minio-client1 mc stat myminio/logs/logs_***.json (logs_000.json, logs_001.json gibi) şeklinde komutlar yazarak nesnelerin bazı bilgileri de görüntüledim.

2. Spark Analiz Sonuçları

Endpoint Bazında Yanıt Süresi & Hata Oranı Tablosu

Endpoint İstek Sayısı Ortalama Yanıt Süresi (ms) Median (50%) 95. Yüzdelik (ms) 99. Yüzdelik (ms) Min (ms) Max (ms) Hata Oranı
/login 2,250,531 163.44 155 277 295 50 299 %7.74
/checkout 1,249,082 396.00 348 713 979 200 1499 %7.76
/cart 750,327 213.88 199 363 392 80 399 %7.77
/pay 599,878 496.99 448 816 1097 306 2985 %7.82
/inventory 150,182 296.02 247 613 887 107 2477 %7.82

Servis Bazında Hata Oranı Tablosu

Servis Toplam İstek Hata Sayısı Hata Oranı Uyarı Sayısı Uyarı Oranı
order-service 1,249,192 99,859 %7.99 249,209 %19.94
auth-service 1,251,388 63,039 %5.03 188,067 %15.03
payment-service 1,249,698 187,806 %15.02 311,876 %24.95
inventory-service 1,249,722 37,470 %2.99 124,278 %9.94

Bölgeye Göre Trafik Dağılımı Tablosu

Bölge İstek Sayısı Ortalama Yanıt Süresi (ms)
us-east 1,249,955 273.11
eu-central 3,000,474 273.11
ap-south 749,571 273.14

En Çok İstek Yapan Kullanıcılar Tablosu

Kullanıcı ID İstek Sayısı
38 50,401
33 50,311
35 50,282
48 50,239
30 50,225
11 50,212
32 50,206
49 50,176
17 50,138
3 50,128
37 50,102
16 50,101
8 50,098
29 50,098
1 50,094
44 50,085
20 50,064
19 50,062
6 50,035
43 50,017

En Çok İstek Yapan IP Adresleri Tablosu

IP Adresi İstek Sayısı Benzersiz Kullanıcı
192.168.1.6 200,837 1000
192.168.1.4 200,758 1000
192.168.1.1 200,189 1000
192.168.1.10 200,133 1000
192.168.1.9 200,133 1000
192.168.1.3 200,100 1000
192.168.1.7 200,090 1000
192.168.1.8 199,552 1000
192.168.1.5 199,507 1000
192.168.1.2 198,737 1000
192.168.1.18 44,228 1000
192.168.1.26 44,202 1000
192.168.1.34 44,186 1000
192.168.1.12 44,111 1000
192.168.1.28 44,008 1000
192.168.1.35 44,000 1000
192.168.1.48 43,936 1000
192.168.1.47 43,929 1000
192.168.1.23 43,898 1000
192.168.1.46 43,881 1000

3. Format Karşılaştırması

Format Dosya Boyutu Sorgu Süresi Açıklama
JSON 1.19 GB 3.46 sn (HDFS) / 6.75 sn (MinIO) Satır bazlı yapı, sıkıştırma yok
Parquet 58 MB 0.13 sn (HDFS) / 0.21 sn (MinIO) Kolon bazlı sıkıştırma,dictionary encoding, seçmeli okuma
ORC 50 MB 0.12 sn (HDFS) / 0.18 sn (MinIO) Kolon bazlı, bloom filter, en hızlı okuma
  • Hangi formatın neden daha verimli olduğunu açıklayın. -> Parquet ve ORC, Json'daki gibi satır bazlı değil de sütun bazlı arama yapıyor ve gereksiz sütun bloklarını atlıyor bu sayede Json a göre daha hızlıdır. Metadata sayesinde işine yaramayan kolonları gezmekten kurtuluyor.

    -> Parquet: örneğin tekrar eden 10 farklı istatistik değeri varsa dictionary enoding diye bir yöntemle bu 10 değeri sözlüğe yazıyor. Milyonlarca satırda uzun uzun tüm verileri değil de sadece sözlükteki kısacık kodları saklıyor. Veri boyutunu inanılmaz küçültüyor. Bu da çok verimli hale getiriyor.

    -> ORC: Önce şerit seviyesindeki istatistiklere bakarak alakasız şeritleri toptan atlıyor. Sonra okuması gereken şeritin içine girdiğinde dahili satır indeksini kullanarak o şeridin içindeki onbinlerce satırlık küçük blokları da atlıyor. Bu şekilde iki aşamalı eleme yapıyor ve elde ettiğim sorgu süresine de bakacak olursak ORC daha verimli görünüyor.

  • Sıkıştırma ve bölümleme etkisini belirtin. -> Bu projede Parquet ve ORC formatları Snappy sıkıştırma ile yazılmıştır. Snappy hızlı sıkıştırma sağlar ve özellikle analitik sorgular için en verimli codec’lerden biridir.


4. Optimizasyon Sonuçları

Sorgu Tipi Süre (sn) Bellek Kullanımı Yanlış Pozitif Oranı
Standart Sorgu 0.3244 - -
Bloom Filter ile 0.4116 122.07 KB 0.00%
Bitset ile 0.5833 0.25 KB 0.00% (ama farklı subnet nedeniyle 1 uyumsuzluk görüldü)

-Bloom Filter 5 milyon log içinde 1000 farklı user_id olduğu için bu yapı çok verimli oldu.

Bloom Filter 122 KB bellek kullandı.

1000 kullanıcıyı ekledi ve yanlış pozitif oranı 0% olarak gerçekleşti.

Ancak bu veri setinde Spark’ın kendi filtresi zaten çok hızlı olduğu için Bloom Filter klasik filtreleme hızını geçemedi (0.79x speedup).

🔍 BLOOM FILTER OPTİMİZASYONU

  1. Bloom Filter oluşturuluyor ve user_id'ler ekleniyor...

➡ Toplam farklı user_id sayısı : 1000

➡ Bloom Filter oluşturma süresi : 1.6722 sn

➡ Bloom Filter bit boyutu : 1,000,000 bit (~122.07 KB)

➡ Set edilen bit sayısı : 2,996

➡ Doldurma oranı (fill_ratio) : 0.30%

  1. Bloom Filter üyelik testleri...

user_id= 1 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 5 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 10 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 25 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 50 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 100 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 200 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 500 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 999 -> Bloom: True , Gerçek: True [✅ Doğru Pozitif]

user_id= 9999 -> Bloom: False, Gerçek: False [✅ Doğru Negatif]

user_id=10000 -> Bloom: False, Gerçek: False [✅ Doğru Negatif]

user_id=50000 -> Bloom: False, Gerçek: False [✅ Doğru Negatif]

➡ Yanlış Pozitif Sayısı : 0 ➡ Yanlış Pozitif Oranı (≈) : 0.00%

  1. Performans Karşılaştırması: Standart Sorgu vs Bloom Filter Destekli Sorgu

➡ Standart Sorgu Süresi : 0.3244 sn (count=267381)

➡ Bloom Filter Destekli Sorgu : 0.4116 sn (count=267381)

➡ Hızlanma Oranı (speedup) : 0.79x

-Bitset IP adresi filtrelemesinde Bitset çok daha etkili çalıştı:

Sadece 0.25 KB bellek kullandı

200 IP’yi anında işaretledi

Sorgu süresini 0.7916 sn -> 0.5833 sn seviyesine düşürdü

1.36x hızlanma elde edildi

Bitset yapısında yanlış pozitif/negatif olmaz ancak: Veri setindeki bazı IP adresleri 192.168.1.xxx dışında olduğu için 1 yanlış eşleşme görüldü.

🎯 BITSET OPTİMİZASYONU

  1. IP Bitset oluşturuluyor ve IP'ler ekleniyor...

➡ Toplam farklı IP sayısı : 200

➡ Bitset oluşturma süresi : 0.5081 sn

➡ Slot sayısı (0-255) : 256

➡ Kayıtlı IP sayısı : 200

➡ Tahmini bellek kullanımı : 256 byte (~0.25 KB)

  1. Bitset üyelik testleri... ip=192.168.1.1 -> Bitset: True , Gerçek: True ✅

ip=192.168.1.5 -> Bitset: True , Gerçek: True ✅

ip=192.168.1.10 -> Bitset: True , Gerçek: True ✅

ip=192.168.1.100 -> Bitset: True , Gerçek: True ✅

ip=192.168.1.200 -> Bitset: True , Gerçek: True ✅

ip=10.0.0.1 -> Bitset: True , Gerçek: False ❌ (Tutarsız!)

  1. Performans Karşılaştırması: Standart Filtre vs Bitset Destekli Sorgu

➡ Standart Filtre Süresi : 0.7916 sn

➡ Bitset Destekli Filtre Süresi : 0.5833 sn

➡ Hızlanma Oranı (speedup) : 1.36x

Join Optimizasyonu

Join Tipi Süre (sn)
Normal Join 2.0434
Broadcast Join 0.6583

Normal Join -> 2.0434 sn

Broadcast Join -> 0.6583 sn

3.10x hızlanma gerçekleşti.

Spark, küçük tabloyu tüm nod’lara dağıtarak shuffle maliyetini ortadan kaldırdı.

📡 BROADCAST JOIN OPTİMİZASYONU

  1. Servis Metadata Lookup Tablosu oluşturuluyor...
service description
auth-service Authentication & Login
order-service Order Management
payment-service Payment Gateway
inventory-service Stock & Inventory
  1. Normal Join (Broadcast YOK)... ➡ Normal Join Süresi : 2.0434 sn (count=5000000)

  2. Broadcast Join (Küçük tablo broadcast ediliyor)... ➡ Broadcast Join Süresi : 0.6583 sn (count=5000000)

  3. Performans Karşılaştırması: ➡ Hızlanma Oranı (speedup) : 3.10x

⏱️ Toplam Çalışma Süresi: 27.94 saniye

📊 ÖZET TABLO İÇİN METRİKLER

Standart user_id sorgu süresi : 0.3244 sn

Bloom Filter ile user_id sorgusu : 0.4116 sn

Bloom Yanlış Pozitif Oranı (≈) : 0.00%

Bloom Bellek Kullanımı (≈) : 122.07 KB

Standart IP filtre süresi : 0.7916 sn

Bitset ile IP filtre süresi : 0.5833 sn

Bitset Bellek Kullanımı (≈) : 0.2500 KB

Normal Join Süresi : 2.0434 sn

Broadcast Join Süresi : 0.6583 sn


5. HBase Tablo Tasarımı

  • Satır anahtarı yapısı ve kolon aileleri hakkında kısa açıklama:

Tasarımımız, Spark'tan gelen analiz sonuçlarını sorgu verimliliğini artırmak amacıyla boyutlara göre ayırır. Satır Anahtarı Amacı: En kritik sorgu boyutuna (Endpoint, Servis, Saat veya Kullanıcı ID) göre belirlenir. HBase'in ilgili verileri disk üzerinde sıralı tutmasını sağlayarak hızlı okuma (Point Reads) işlemlerini optimize eder.

  1. response_metrics Tablosu: Row Key: endpoint (Örn: endpoint_00001) Amaç: "Hangi endpoint yavaş çalışıyor?" veya "Endpoint 1'in performansı nasıl?" sorusuna anında cevap vermek. Mantık: Biz bu tabloda her endpoint için tek bir özet satırı tutuyoruz. Anahtar olarak endpoint adını (veya ID'sini) verdiğimizde, Spark veya API get('endpoint_00001') diyerek mili saniyeler içinde o veriyi çekebilir.

  2. service_errors Tablosu: Row Key: service (Örn: auth-service, payment-service) Amaç: Servis bazlı sağlık durumunu görmek. Mantık: Bir dashboard yaptığını düşünelim; "Auth servisi çöküyor mu?" diye bakılır. Anahtar direkt servis adı olduğu için, HBase milyonlarca satırın arasından auth-service ismini eliyle koymuş gibi bulur. İsimler (String) burada doğal bir benzersiz kimliktir.

  3. region_traffic Tablosu: Row Key: region (Örn: us-east, eu-west) Amaç: Coğrafi analiz yapmak. Mantık: Veriler Spark tarafında zaten bölgeye göre gruplandı (aggregate edildi). HBase'e yazarken her bölge için tek bir satır yazıyoruz. "Amerika bölgesinin verisini getir" dediğimizde get('us-east') komutuyla doğrudan o satıra ulaşırız.

  4. hourly_traffic Tablosu: Row Key: hour (Örn: hour_00, hour_14) Amaç: Zaman serisi analizi yapmak ve grafiği sırayla çizdirmek. Sıralama Avantajı: HBase veriyi anahtara göre sıralı tutar. hour_00, hour_01, hour_02... şeklinde anahtar verirsek, veriyi çekerken saatleri karışık değil, kronolojik sırayla alırız. Bu da çizgi grafiği çizerken işimizi çok kolaylaştırır. Not: Ham veride sadece saat kullanmak "Hotspotting" (tek sunucuya yük binmesi) yapar ama biz burada özetlenmiş (aggregate) veri tuttuğumuz için (günde sadece 24 satır), bu anahtar en performanslı ve okunaklı yöntemdir.

  5. top_users Tablosu: Row Key: user_id (Örn: user_105, user_999) Amaç: Belirli bir kullanıcının aktivitesini bulmak. Mantık: Kullanıcı ID'leri benzersizdir (Unique). Eğer "En çok istek atan kullanıcılar kim?" listesini Spark'ta hazırlayıp buraya yazarsak, anahtarın User ID olması, ileride "User 105 ne yapmış?" diye sorguladığımızda nokta atışı yapmamızı sağlar.

Kolon Aileleri Amacı: Birbiriyle ilişkili sütun gruplarını ayırarak disk yerleşimini düzenler ve okuma maliyetini düşürür.

  1. Tablo: response_metrics Kolon Ailesi: metrics İçindeki Veriler: request_count, avg_response_time, median, p95, p99. Ne İşe Yarıyor: Bu aile, Performans Ölçümlerini bir arada tutar.

  2. Tablo: service_errors Kolon Ailesi: stats (İstatistikler) İçindeki Veriler: total_requests, error_count, warn_count, oranlar. Ne İşe Yarıyor: Bu aile, Sağlık Durumu İstatistiklerini saklar.

  3. Tablo: region_traffic Kolon Ailesi: traffic İçindeki Veriler: request_count, avg_response_time (Bölge bazlı). Ne İşe Yarıyor: Bu aile, Coğrafi Yük Bilgisini tutar.

  4. Tablo: hourly_traffic Kolon Ailesi: traffic İçindeki Veriler: request_count, avg_response_time (Saat bazlı). Ne İşe Yarıyor: Bu aile, Zaman Serisi (Time-Series) Akışını tutar.

  5. Tablo: top_users Kolon Ailesi: user İçindeki Veriler: request_count, user_id. Ne İşe Yarıyor: Bu aile, Kullanıcı Profil/Aktivite Verisini saklar.

  • Veri yükleme adımları: Veri yükleme işlemi (hbase/load_data.py), HDFS'teki (Dağıtık Dosya Sistemi) işlenmiş Spark sonuçlarını alıp HBase tablolarına toplu olarak aktarır.

1.Bağlantı Kurulumu: hbase konteynerine HappyBase üzerinden bağlantı kurulur.

2.Şema Yönetimi: Gerekli 5 tablo, harici hbase/schema.py dosyasında tanımlanan CF'ler ile oluşturulur (varsa silinir).

3.Veri Transferi: Spark, HDFS'teki /analytics/results/ dizininden Parquet formatındaki büyük hacimli analiz sonuçlarını okur.

4.Toplu Yükleme (Batch Put): Veriler, performans için optimize edilmiş Row Key formatına dönüştürülür ve HappyBase'in table.batch().put() fonksiyonu kullanılarak tek bir ağ isteği ile toplu halde HBase'e yazılır. Bu, yüksek hacimli veri transferinde performansı kritik ölçüde artırır.

  • Sorgu örnekleri:
Amaçlanan Sorgu Kullanılacak Tablo Row Key Stratejisi Örnek HappyBase Sorgusu (Mantıksal)
Belirli bir Endpoint'in P95 yanıt süresini alma. response_metrics Tam Row Key Eşleşmesi table.row(b'endpoint_00002', columns=[b'metrics:p95_response_time'])
Hata oranı en yüksek servisin metriklerini çekme. service_errors Tam Row Key Eşleşmesi (Servis Adı) table.row(b'order-service', columns=[b'stats:error_rate'])
Belirli bir saat aralığındaki tüm trafiği listeleme. hourly_traffic Sıralı Tarama table.scan(row_start=b'hour_14', row_stop=b'hour_16')

6. Dashboard ve Görselleştirme

  • Hangi grafikler ve görselleştirmeler kullandınız? Projenin görselleştirme aşamasında Streamlit kütüphanesi ve Plotly grafik motoru kullanılmıştır. Veriler HBase'den anlık olarak çekilerek aşağıdaki grafik türleri ile sunulmuştur:

Metrik Kartları : Genel bakış sayfasında toplam istek sayısı, toplam hata, ortalama hata oranı ve benzersiz bölge sayısı gibi kritik özet bilgileri göstermek için kullanıldı.

Pasta Grafik : Trafiğin coğrafi bölgelere dağılımı, toplam hata dağılımı,bölgeye göre istek sayısını oransal olarak göstermek için kullanıldı.

Çubuk Grafik :Servislerin hata oranlarını ve bölge bazlı ortalama gecikme karşılaştırmak ve en çok istek alan endpoint'leri hacimlerine göre sıralamak için kullanıldı.

Veri Tabloları: Analiz sonuçlarının sayısal detaylarını ve ham verileri incelemek için etkileşimli tablolar kullanıldı.

  • Dashboard'un ekran görüntüsünü ekleyin (reports/ klasörüne görsel ekleyin ve buraya referans verin) 1. Genel Bakış: Genel Bakış

2. Yanıt Süresi Analizleri: Ortalama Yanıt Süresi P95 vs P99 Karşılaştırması   Veri Tablosu   En Yoğun Endpointler

3. Hata Analizleri: Servis Hata Oranları Toplam Hata Dağılımı

4. Trafik ve Kullanıcı Analizleri: Bölgesel Trafik Dağılımı Saatlik İstek Sayısı En Çok İstek Yapan Kullanıcılar En Çok İstek Yapan Kullanıcılar Veri Tablosu

5. Ham Veri: Ham Veri İnceleyici

  • Dashboardda sunduğunuz filtreleme ve dışa aktarma özelliklerini açıklayın Navigasyon ve Görünüm Filtreleme: Sol menüde yer alan Radio Button yapısı sayesinde kullanıcılar "Genel Bakış", "Yanıt Süreleri", "Hatalar" gibi farklı analiz boyutları arasında hızlıca geçiş yapabilir. Her sayfa sadece ilgili veriyi HBase'den çeker.

Veri Yenileme : Veriyi Yenile butonu, Streamlit'in cache temizleyerek HBase'den en güncel verilerin tekrar çekilmesini sağlar. Bu sayede yeni loglar işlendiğinde dashboard anında güncellenebilir.

Ham Veri İnceleme ve Dışa Aktarma : "Ham Veri" sekmesinde kullanıcılar incelemek istedikleri HBase tablosunu açılır menüden seçebilirler. Yüklenen veriler, tablonun altında beliren "CSV Olarak İndir" butonu sayesinde lokal bilgisayara raporlama amacıyla indirilebilir.


7. Karşılaşılan Sorunlar ve Çözümler

  • Kurulumda, kodda veya analizde yaşadığınız teknik sorunlar (varsa) Sorun1: HBase tabloları henüz doluyken Dashboard açıldığında AttributeError: 'NoneType' hatası alındı.

Sorun2: Veri yükleme aşamasında java.net.UnknownHostException: namenode hatası alındı.

Sorun3: MinIO ve HDFS servisleri aynı anda çalıştırılırken Docker üzerinde 9000 port çakışması yaşandı ve MinIO servisi başlatılamadı.

Sorun4: Spark üzerinden HDFS’e erişilmeye çalışıldığında java.net.UnknownHostException: namenode hatası alındı.

  • Nasıl çözdüğünüzü ve öğrendiklerinizi yazın

Çözüm1: Veri çekme fonksiyonlarına try-except blokları eklendi. Veri yoksa hata vermek yerine boş bir DataFrame döndürülmesi sağlanarak Dashboard'un çökmesi engellendi

Çözüm2: Python scriptinin çalıştığı ortamın, HDFS konteynerine ağ üzerinden erişemediği tespit edildi.Docker Compose ile namenode, datanode yeniden başlatıldı ve ağ bağlantısı doğrulandıktan sonra işlem tekrarlandı.

Çözüm3: 9000 portunun HDFS NameNode tarafından kullanıldığı tespit edildi. MinIO için farklı bir port atanarak port çakışması giderildi ve Spark–MinIO bağlantı ayarları güncellendi.

Çözüm4: Spark ortamının HDFS servislerinin bulunduğu Docker ağına dahil olmadığı belirlendi. Docker Compose ile namenode ve datanode servisleri yeniden başlatıldı, ağ bağlantıları doğrulandıktan sonra Spark HDFS’e başarıyla bağlandı.



About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages