4 puan yazan GN⁺ 2025-12-09 | 1 yorum | WhatsApp'ta paylaş
  • Scala 2.13'ten Scala 3'e kod tabanı geçişi sırasında beklenmedik bir performans düşüşü yaşandı
  • İlk test ve dağıtım ortamlarında tüm metrikler normaldi, ancak birkaç saat sonra Kafka gecikmesi (lag) arttı
  • Yük testlerinde mesajın ayrıntılı işlenmesi sırasında throughput düşüşü net biçimde tespit edildi
  • async-profiler analizi, sorunun Quicklens kütüphanesindeki zincir değerlendirme verimsizlik hatası olduğunu ortaya koydu
  • Kütüphane güncellemesinden sonra performans geri geldi; Scala sürümleri arasındaki kütüphane davranış farklılıklarına dikkat edilmesi gerektiği vurgulandı

Servis Geçiş Süreci

  • Mevcut servis, Scala 2.13'ten Scala 3.7.3'e taşındı
    • Makro kullanmayan veri toplama odaklı bir servis olup performansı kritik bir bileşendi
    • Bağımlılıklar, derleyici seçenekleri, tip ve sözdizimi değişiklikleri uygulandıktan sonra derleme başarılı oldu
  • Test ortamı ve kademeli dağıtım sürecinde de loglar ve metrikler normal göründü
    • Altyapı, JVM ve uygulama seviyesindeki ölçümler de sağlıklı durumdaydı
Reklam

Sebebi Belirsiz Performans Düşüşü

  • Dağıtımdan yaklaşık 5-6 saat sonra Kafka lag artışı görüldü
    • Veri spike'ı olmayan durumda bile örnek başına işleme oranında düşüş
    • Geri alma sonrası işleme oranı anında toparlandı ve nedenin kod değişikliği olduğu doğrulandı

Performans Analizi ve Kök Neden Tespiti

  • Yük testlerinde başlangıçta performans regresyonu yeniden üretilemedi
    • Yalnızca mesajın parçalanması ve heterojen yüklerde işlemde throughput hızla düştü
  • Bağımlılık kütüphanelerini (seri hale getirme, DB SDK, Docker image, konfigürasyon kütüphanesi vb.) tek tek geri alarak test ettiler, ancak değişiklik görülmedi
  • async-profiler ile CPU profillemesi sonucunda
    • Scala 3'te JIT derleyicisi ve decode aşamasında CPU kullanımının ciddi biçimde artması
    • Flamegraph'ın üst satırlarında Quicklens çağrılarının toplam CPU zamanının yarısını oluşturduğu görüldü
    • Scala 2.13'te aynı çağrılar yalnızca %0.5 seviyesindeydi
    Reklam

Sorunun Kök Nedeni

  • Quicklens kütüphanesinde zincir değerlendirme verimsizlik hatası, Scala 3'te ortaya çıkıyordu
    • İlgili düzeltme GitHub PR #115'te yer aldı
    • Kütüphane güncellemesinden sonra Scala 3 ile 2.13 arasındaki performans farkı giderildi

Dersler ve Öneriler

  • Kütüphanelerin metaprogramlama bağımlılığı Scala sürümleri arasındaki performans farklarını tetikleyebilir
  • Geçiş tamamlanmış görünse bile, hotspot ve darboğazları benchmark etmek gerekir
  • Performansın kritik olduğu hizmetlerde “çalışıyor” varsayımı yerine ölçüme dayalı doğrulama şarttır
  • Darboğazı sadece kodla değil, benchmark'ın açığa çıkardığı senaryoları engellemek için ön kontrol gerekir

1 yorum

 
GN⁺ 2025-12-09
Hacker News yorumu
  • Scala hayranı değilim ama sorunun derinlemesine analiz edilmesi ve debug süreci etkileyiciydi
    Teknik bloglar böyle yazılmalı. Yapay zekanın bu düzeyde bir düşünce sürecinin yerini alması zor
    • Servislerimizden birini yenilerken Scala 2.13'ten Scala 3'e migration yaptık
      İlk soru basitti — “neden yükseltmemiz gerekiyor?”
  • Scala 3'te inline anahtar sözcüğü makro sisteminin bir parçası olarak çalışıyor
    Parametrede inline kullanırsanız derleyiciye ifadeyi çağrı noktasında inline etmesini söylersiniz
    Ama bu büyükse JIT derleyici için ciddi bir yük oluşturur
    Scala 2'de @inline sadece bir öneriydi, ama 3'te zorunlu uygulanıyor
    Bu yüzden @inline'ı doğrudan inline ile değiştirmek büyük bir hata
    • Bu fark, eski C/C++'taki register anahtar sözcüğünün yaşadığı şeye benziyor
      Başta zorunluydu ama optimizasyonlar geliştikçe sadece bir öneri haline geldi ve sonunda göz ardı edildi
      C++'taki inline da benzer bir süreçten geçti
    • Kotlin inline'ı neredeyse her yerde agresif biçimde kullanıyor
      map gibi fonksiyonlarda lambda overhead'ini kaldırmak için
      Neredeyse hiç performans sorunu olmadı ama Scala'nın makro sistemiyle birleşince karmaşık ifadeler oluşup sorun yaratabiliyor gibi görünüyor
  • Kütüphaneleri yükselttikten sonra Scala 3 performansı Scala 2.13 ile neredeyse aynı hale geldi
    Ruby 2→3 yükseltmesinde de benzer bir deneyim yaşamıştım
    Sadece dili yükseltmek değil, tüm bağımlılıkları güncellemek sistemi daha stabil hale getiriyor
  • Scala 3'ün sorunu, kimsenin bunu istememiş olması
    Scala 2'nin type inference sorunları hâlâ çözülmedi, onun yerine dil değiştirildi
    Pazarın talepleri göz ardı edilip kimsenin istemediği bir ürün yapılmış oldu
    PS: Derleyici için gerçekten düzgün bir unit test suite yapılmalı
    • Üzücü ama katılıyorum. Scala 2010~15 civarında umut vericiydi
      Ama Scala 3 rewrite'ı derleme hızı ve tooling sorunlarını çözmedi, projeyi tamamen momentum kaybına uğrattı
      2025'te yeni bir projeye Scala ile başlayacak biri olur mu emin değilim
    • Scala'yı birkaç kez öğrenmeye çalıştım ama sonunda hep Clojure'a geri döndüm
      Scala bana akademisyenlerin yaptığı bir dil gibi geliyor ve endüstride bir süre popüler olması aslında daha da tuhaf
    • Esası iyi yakalamış
      Artık tüm araçların Scala 3'e uyum sağlaması gerekiyor ve IntelliJ bile hâlâ tam destek veremiyor
      Keşke Scala 2 kademeli olarak geliştirilseydi; sanki sadece akademik başarıya odaklanılmış
      Örneğin tpolecat'in yazısında early return konusunda çok tartışma var ama Kotlin bunu sorunsuz destekliyor
    • “Test yok” demek yanlış bilgi
      Scala derleyicisinde binlerce, on binlerce test var ve
      resmî test dizini ile
      community build sistemi üzerinden milyonlarca LOC doğrulanıyor
    • Yazıyı düzgün okumamış gibisin. Ana argüman tamamen kaçırılmış
  • Bu yazıda en ilginç bulduğum şey, otomatik performans testleri ve flamegraph analizinin varsayılan olarak kurulmuş olması gerektiği
    Özellikle dil sürümü yükseltmesi gibi büyük değişikliklerde bu şart
    • Benchmark testleri sıradan testlerden farklı olarak ince ayarlı kurulum ister
      Biz C++ ile yazılmış araçları sürekli benchmark ediyoruz ama ortam gürültüsü yüzünden tutarlı sonuç almak zor
      Aynı makinede birden çok kez çalıştırıp karşılaştırma yöntemini düşünüyoruz
    • JVM tarafında bugünlerde hangi performans test araçlarının kullanıldığını merak ediyorum
  • Scala 3'ün tek sorunu Python kıskançlığı
    İkinci bir sözdizimi üretip bunu gelecek diye dayatmaları asıl problemdi
    Bu yüzden tooling ekosistemi de yavaşladı
    • Artık araçların çoğu yeni sözdizimini destekliyor
      Derleyici veya scalafmt ile stil otomatik dönüştürülebiliyor
    • Scala'ya uygun şekilde aynı şeyi yapmanın birden fazla yolu oldu
      Şimdi süslü parantez sözdizimiyle girintili sözdizimi iki katına çıkmış oldu
    • Keşke Haskell ile kıyaslansaydı, daha çekici olabilirdi
    • Eski bir Scala hayranı olarak yeni sözdizimi örneklerini görünce şaşırmıştım
      match ifadesi fazla ayrıntılı ve Python taklidi gibi duruyor
  • Eskiden Scala 2.x migration'ı yapmıştım ve bağımlılıkları beklemek en zor kısımdı
    O dönemde Spark sayesinde Scala ilgi görmüştü ama ticari bir dil olarak büyüme fırsatını kaçırdı
    Şimdi Spark Python'a, JVM'in modern dil alanı da Kotlin'e kaymış durumda
    Sonuçta Scala yeniden akademik bir dil gibi hissettiriyor
    • Ama Scala hâlâ büyük şirketlerde yaygın biçimde kullanılıyor
      Scala Adoption Tracker bunu gösteriyor
      Scala 3'ün yeni özellikleri dil ekosistemini yeniden yenileme potansiyeline sahip
      Örn: Capture Checking açıklaması
    • Kotlin'in gerçekten JVM'e hâkim olup olmadığı tartışılır
      Java fonksiyonel özellikler ekleyerek Scala'nın çekiciliğinin bir kısmını absorbe etti
    • Server-side JVM dünyasında Kotlin'in varlığı neredeyse yok
      Benim deneyimimde piyasa talebi de çok düşük
    • Kotlin fiilen Android'e özel bir dil
      Google Java desteğini sınırladığı için böyle oldu
      Genel JVM pazarında payı ancak %10 civarında
  • Kütüphane sürümlerini yükseltmeden Scala 3'e geçmeleri bana tuhaf geldi
    Güvenlik denetimlerinden (PCI-DSS vb.) geçiyorsanız kütüphaneleri güncel tutmak zaten zorunlu
    • “Güncel tutmak iyi bir alışkanlıktır” sözü tartışmayı kapatan bir ifade
      Ben ise çoğu zaman bağımlılıkları eski durumda tutmayı tercih ederim
      Yeni sürümler yeni bug'lar getirir; bakım ekibinin değişmesi ya da güvenlik riskleri de olabilir
    • Ben de karışık buldum. Yazıda “bağımlılıkları güncelledik” deniyor ama sonra “güncelledikten sonra performans eşitlendi” deniyor
      Muhtemelen önce sadece bir kısmını yükseltmişlerdi. Küçük adımlara bölmek normal ama bu sefer şanssız olmuşlar
    • Bug'ın nedenini öğrenince daha az etkileyici geldi
      Sorun Scala 3'ün kendisinden çok birden fazla etkenin etkileşimi idi
    • Dil sürümü yükseltmesi gibi büyük değişikliklerde aynı anda tek şey değiştirmek daha iyi
    • Maven/Gradle/SBT'de sürüm kısıtları koyarsanız bu, dil sürümünden bağımsız korunur
      Ama Scala'ya özel kütüphanelerde sürüme Scala sürümü de dahil olduğu için dikkat etmek gerekir
  • SoftwareMill ve Scala GitHub'daki bug report'lar küçük ama isabetli düzeltmelerdi
    Scala'nın ifade gücü ve type safety öne çıkıyordu
    Li Haoyi'nin yazısında olduğu gibi Python alternatifi olarak da yeterince çekici
  • Asıl ders şu: dil veya framework'te major upgrade yaparken kütüphaneleri de birlikte güncellemek gerekir
    Özellikle sihirli özellikleri aşırı kullanan kütüphaneler ne kadar fazlaysa bu o kadar önemli