2015 yıllarında bir yerlerde, stored procedure'ları ölü ilan etmek moda oldu. İş mantığı uygulama katmanına aitti. Veritabanları sadece aptal birer kalıcılık katmanıydı. ORM'ler bizi kurtaracaktı. Microservice'ler her şeyi orkestre edecekti.
Sonra bir Solvency II raporlama hattının 14 saat sürdüğünü gördüm; çünkü biri 80 milyon poliçe kaydını bir Python servisine çekip teknik karşılıkları satır satır hesaplamakta ısrar etmişti. Önceki PL/SQL uygulaması 22 dakikada çalışıyordu.
Soru, stored procedure'ların iyi mi kötü mü olduğu değildir. Soru, verinin nerede yaşadığı, ne kadarının hareket ettiği ve düzenleyici sunumu kimin imzaladığıdır.
Veriyi Taşımanın Maliyeti
Mimari tartışmaların çoğu fiziği göz ardı eder. Oracle'da 50 milyon işleminiz varsa ve bunları karşı taraf, para birimi ve risk sınıfına göre toplulaştırmanız gerekiyorsa, iki seçeneğiniz vardır:
- Toplulaştırmayı verinin bulunduğu yerde hesaplayın, birkaç bin satır döndürün
- 50 milyon satırı ağ üzerinden uygulama sunucusuna akıtın, bellekte toplulaştırın, geri yazın
İkinci seçenek sadece daha yavaş değildir. Mertebeler düzeyinde daha yavaştır ve daha önce var olmayan arıza modları ekler: akış ortasında ağ zaman aşımları, kısmi okumalar, uygulama katmanında bellek baskısı, idempotent olabilen veya olmayabilen yeniden deneme semantiği.
BDDK ve EIOPA raporlamasında, geriye dönük test için aynı hesaplamanın yıllarca tarihsel veri üzerinde gecelik çalıştırılması gerekebildiği durumlarda, bu fark akademik değildir. Düzenleyici son tarihten önce biten bir hat ile bitmeyen bir hat arasındaki farktır.
Stored Procedure'lar Ne Zaman Doğru Cevaptır
Bankalar ve sigortacılar için 13 yıldır raporlama altyapısı kurmanın ardından, örüntü tutarlı. Mantığı veritabanına ittiğiniz durumlar:
- İşlem küme tabanlıdır ve veri zaten oradadır. Toplulaştırmalar, büyük tablolar arası join'ler, zaman serileri üzerinde pencere fonksiyonları. Oracle'ın optimizer'ı bunda iyi olmak için 40 yıl harcadı. Sizin Python döngünüz harcamadı.
- Sonuç kaynak karşısında denetlenebilir olmalı. Bir düzenleyici bir sayının neden o sayı olduğunu sorduğunda, sürümlü DDL ve net yürütme günlüğü olan tek bir prosedüre işaret edebilmek, herhangi bir temiz mimari diyagramından daha değerlidir.
- Okuma ile yazma arasındaki gecikme önemlidir. Bir karşılık hesaplamak, sonra geri yazmak, sonra ondan türetilmiş bir rakamı hesaplamak. Her adımı bir uygulama sunucusu üzerinden gidip gelmek, tam bir çalıştırma boyunca saatlere kadar birikecek milisaniyeler ekler.
- İşlem sınırı sıkı olmalı. Bir hesaplama ve onun kalıcı hale getirilmesi birlikte başarılı veya başarısız olmak zorundaysa, bunu tek bir PL/SQL bloğunda yapmak, servisler arası dağıtık işlemleri koordine etmekten daha temizdir.
Veritabanından Ne Zaman Çıkmalı
Tersi de eşit derecede önemlidir. Mantığı dışarı çekin:
- Mantık dış sistemlere bağlıysa. Bir derecelendirme API'sini çağırmak, bir mesaj kuyruğuna ulaşmak, dosya sisteminden okumak. Bunu PL/SQL'den yapmayın. Dış sistem ilk donduğunda ve veritabanı oturumlarınız birikmeye başladığında pişman olacaksınız.
- Hesaplama küme tabanlı değilse. Yinelemeli simülasyonlar, Monte Carlo çalıştırmaları, makine öğrenimi çıkarımı. Bunlar cursor döngülerine değil, Python veya Scala'ya aittir.
- Mantık veritabanı sürüm döngünüzden daha hızlı değişiyorsa. İş kuralları haftalık değişiyor ve DBA ekibiniz üç ayda bir dağıtım yapıyorsa, stored procedure'lar darboğaza dönüşür. Bu mantığı daha hızlı dağıtım kadansına sahip bir yere taşıyın.
- Veritabanının size verebileceğinden daha fazla yatay ölçek gerekiyorsa. Gerçekten 200 worker arasında dağıtmanız gerekiyorsa, veritabanı doğru yer değildir. Ama bu ölçeğe gerçekten ihtiyacınız olup olmadığı veya sadece istediğiniz konusunda dürüst olun.
Gerçekten İşe Yarayan Hibrit
Uygulamada, düzenleyicilerle teması sağ atlatan raporlama hatları şöyle görünür:
- Ham veri Oracle'a veya karşılaştırılabilir bir warehouse'a iner
- Küme tabanlı dönüşümler, toplulaştırmalar ve mutabakatlar tam loglama ile PL/SQL paketlerinde gerçekleşir
- Sonuçlar view'lar veya materialized view'lar üzerinden açığa çıkar
- Python veya Airflow'taki bir orkestrasyon katmanı zamanlama, dış sistem entegrasyonu ve bildirimleri ele alır
- Nihai rapor üretimi, biçimlendirme ve sunum uygulama katmanında gerçekleşir
Veritabanı, veritabanlarının iyi olduğu şeyi yapar. Uygulama katmanı, iyi olduğu şeyi yapar. Kimse tek bir aracın her sorunu çözdüğünü iddia etmez.
Gece 2 Testi
Gerçek karar kriteri şudur: gecelik çalıştırma sabah 2'de başarısız olduğunda ve birinin bunu sabah 8'deki düzenleyici sunumdan önce düzeltmesi gerektiğinde, nereye bakar?
Cevap "Veritabanı iş günlüğüne bakarım, başarısız prosedürü bulurum, hatayı okurum ve hangi 50 satırlık PL/SQL'i inceleyeceğimi tam olarak bilirim" ise, sürdürülebilir bir sisteminiz vardır.
Cevap "İsteği altı microservice üzerinden izlerim, dört sistemdeki günlükleri ilişkilendiririm, hangi container'ın öldüğünü çözerim ve sonra veri durumunu yeniden üretmeye çalışırım" ise, beyaz tahtada temiz görünen ama işletmesi düşmanca olan bir şey inşa etmişsiniz demektir.
Düzenleyici raporlama, mimari zarafet uğruna işletilebilirlikten ödün verilecek bir yer değildir. Denetçi sizin hexagonal architecture'ınızla ilgilenmez. Denetçi sayının doğru olup olmadığını ve nasıl hesaplandığını kanıtlayıp kanıtlayamadığınızı önemser.
Dürüst Çerçeve
Stored procedure'ların modern olup olmadığını sormayı bırakın. Şunları sormaya başlayın:
- Veri şu an gerçekten nerede yaşıyor?
- Cevabı hesaplamak için ne kadarının hareket etmesi gerekiyor?
- Sayı yanlış olduğunda kim sorumlu?
- Bu mantığın ne kadar hızlı değişmesi gerekiyor?
- Gece 2'de arıza modu nasıl görünüyor?
Bunları yanıtlayın, mantığın doğru yeri genellikle açık hale gelir. İdeoloji, sorunu yeterince düşünmediğinizde başvurduğunuz şeydir.