12 puan yazan xguru 2024-09-26 | 7 yorum | WhatsApp'ta paylaş
  • Wafris, Rails middleware istemcisi sunan açık kaynaklı bir web uygulaması güvenlik duvarı şirketidir
  • v1 istemcisi yerel bir Redis veri deposu gerektiriyordu, ancak v2'de SQLite kullanılıyor
  • Redis'ten SQLite'a geçiş kararı alınmasının arka planını, performans değerlendirmelerini ve mimari değişiklikleri açıklıyor

TL;DR

  • SQLite'ın iyi yaptığı ve iyi yapmadığı şeyler vardır
  • Redis'in iyi yaptığı ve iyi yapmadığı şeyler vardır
  • Geleneksel RDBMS'lerin (Postgres/MySQL) iyi yaptığı ve iyi yapmadığı şeyler vardır
  • Bu veri depoları bire bir değiştirilemez; bunu yapmaya çalışırsanız sorun yaşarsınız
  • Bu yazı, Redis tabanlı v1 istemcisinden SQLite tabanlı v2 istemcisine yeniden mimarileştirme sırasında yapılan testleri ve alınan kararları anlatıyor

Değişimi zorlayan etkenler

  • Wafris'in hedefi, geliştiricilerin sitelerini kolayca koruyabilmesini sağlamaktır
  • Redis dağıtım sorunları nedeniyle v1 bu hedefe tam olarak ulaşamadı
  • Heroku gibi Redis'in kolayca kullanılabildiği ortamlarda çalışıldığı için Redis seçildi, ancak birçok kullanıcı Redis dağıtım sorunları yaşadı
  • Kullanıcıları Redis gibi ayrı bir veritabanı kullanmaya zorlamak kullanıcı yararına değildir

"Hız" nedir?

  • Redis, geleneksel RDBMS'lerden "daha hızlı"dır, ancak yine de bağlantı, bellek, süreç gibi şeylerin yönetilmesi gerekir
  • Bulut ortamlarında ağ gecikmesi büyük bir sorun olabilir
  • Gelen her HTTP isteğinde Wafris kurallarının değerlendirilmesi gerektiğinden, ağ gecikmesi uygulamayı yavaşlatabilir

Monolitimsi varsayım

  • Tamamen dağıtık uygulamalar vardır, ancak çoğu Rails uygulaması bir "Majestic Monolith"tir
  • Birden çok bölgeye dağıtılan, işlevleri çakışan sunuculara bölünen ya da yalnızca kısmen Rails olan uygulamalarda Redis kullanımı daha fazla sorun çıkarır

Mimarinin yeniden düşünülmesi

  • Wafris, Rails middleware olarak kurulan bir web uygulaması güvenlik duvarıdır
  • Basitçe iki aşamaya ayrılır: 1) HTTP isteğini kurallarla karşılaştırmak, 2) işleme sonucunu raporlamak
  • Kural "okuma"sı (1. aşama), "yazma"dan (2. aşama) çok daha önemlidir
  • Okumalar sıralı işlenmelidir, başarısız olmamalıdır ve kullanıcının hissettiği performansı etkiler
  • Yazmalar daha yavaş, toplu ya da asenkron yapılabilir

SQLite sahnede

  • SQLite'ın hangi kullanım alanlarına uygun olduğu başkaları tarafından iyi şekilde anlatılmıştır
  • SQLite, istemci/sunucu veritabanlarıyla değil, fopen() ile rekabet eder
  • Ağ gidiş-dönüşlerini ortadan kaldırmanın onu Redis'ten çok daha hızlı yapması bekleniyordu
  • SQLite ve Redis için benchmark değerlendirmesi yapmaya karar verildi

SQLite ve Redis benchmark'ı

  • Benchmark, insanın kendini hassas sayılarla kandırdığı karanlık bir sanattır
  • Veri depolarında benchmark yapmak daha da zordur
  • Amaç mutlak hızı bulmak değil, kendi veri yapımıza ve kullanım senaryomuza özel bir benchmark oluşturmaktı
  • Optimizasyon ayarları göz ardı edildi. Amaç, Wafris'in uygulamaya eklenir eklenmez çalışmasıydı
  • Teorik benchmark'lar yerine uygulamanın kritik yolu ve en kötü sorguları test edildi
  • En kötü sorgu, IP aralıklarını (IPv4, IPv6) kategorilere eşleyen karmaşık bir "lexical decimal" veri yapısı isteğidir
  • Aralık sorguları önceden hesaplanıp SQLite tablolarına ve Redis sıralı kümelerine yazıldı
  • Her gelen HTTP isteğinde, istek IP'si izin/ver engel özel aralıklar, GeoIP aralıkları ve IP itibar aralıklarıyla karşılaştırılmalıdır

Test protokolü

  • Testler, M2 MacBook Air üzerinde Homebrew ile kurulu Redis ve yerel SQLite veritabanıyla yapıldı
  • Mevcut aralık veri kümesi (1,2 milyon öğe) üzerinde test edildi
  • Birden fazla IP kümesi, SQLite ve Redis üzerinde aynı sırayla çalıştırıldı
  • Her çarpan için test 5 kez çalıştırıldı ve ortalaması alındı

Test sonuçları

  • SQLite, Redis'i açık ara geçti (bizim özel kullanım senaryomuzda)
  • SQLite, yerel Redis örneğinden yaklaşık 3 kat daha hızlıydı
  • Bu sonuç, ağ gecikmesi hesaba katılmadan elde edildi
  • SQLite, Redis'le sadece başa baş bile olsa ağ süresini ortadan kaldırdığı için yine avantaj sağlayacaktı

Grafikte olmayanlar

  • SQLite performansı benchmark'ta 2 kat daha kötü olsa bile, pratikte ağ gecikmesi yüzünden yine daha hızlı olabilir
  • Redis sunucusunu ne kadar güçlendirirseniz güçlendirin, ağ bant genişliği, bağlantılar ve bölgeler arası gecikme gibi sınırlar vardır
  • SQLite ile neredeyse sınırsız yatay ölçekleme "ücretsiz" olarak elde edilebilir
  • SQLite ile onboarding çok daha iyi hale gelir. Kullanıcılar muhtemelen kullanıldığını bile fark etmez
  • Redis'ten daha fazla performans çıkarılabilirdi, ancak kullanıcıları Redis ayarlarını değiştirmeye ikna etmek zordu

Sonuç sadece başlangıç

  • SQLite'ın Redis'ten daha hızlı olduğu gösterildi, ancak gerçek ödünleşimler vardır
  • Yukarıdaki testlerde yazma işlemleri hesaba katılmadı
  • Okuma ve yazma rekabetini yönetmek için veritabanı bağlantıları, bağlantı havuzu, transaction'lar vb. gerekir
  • Tıpkı elektrikli bir süper otomobilin beton blok taşımaya uygun olmaması gibi, SQLite da uygun olmadığı rollerde kullanılmamalıdır

Senkronizasyon mimarisinin kurulması

  • v1'de (Redis), kullanıcı Wafris Hub üzerinden kuralları güncellediğinde, Redis veri deposundaki kurallar da güncelleniyordu
  • SQLite'ta web sunucusuna "push" yapılamadığı için bu yaklaşım çalışmıyor
  • v2'de (SQLite): 1) kullanıcı Wafris Hub'da kuralları günceller, 2) istemci belirli aralıklarla güncellenmiş kuralları kontrol eder, 3) kurallar güncellenmişse tamamen yeni bir SQLite veritabanı indirilir
  • Bu, kullanıcının kurulum ve yapılandırma sorumluluğunu büyük ölçüde azaltır
  • v2 istemcisinin kurulum başarı oranı 3 kat arttı

SQLite'ın dağıtık mimarisi

  • Otomatik ölçeklemenin etkin olduğu bir bulut sağlayıcısına dağıtılmış bir Rails uygulamasını düşünün
  • İstekler 100 req/s'den 10.000 req/s'ye çıktığında, işlem örnekleri ölçeklenir ama veritabanı ölçeklenmez
  • Bu, pratikte Rails uygulamalarının aşırı yük nedeniyle çökmesinin başlıca nedenidir
  • SQLite veritabanını her işlem örneğine senkronize etmek, tüm çağrıları yerelde tutarak bu sorunu çözer

Peki ya yazmalar?

  • Uygulama okuma (kural değerlendirme) ve yazma (raporlama) yollarına ayrıldı, ardından yazma yolu göz ardı edildi
  • Yazma yolu şu şekilde yeniden tasarlandı: 1) Wafris Hub'a asenkron bağlanıp raporlama, 2) raporları toplu gönderme, 3) istemcide veritabanına yazmayı tamamen kaldırma
  • Bu yaklaşım herkes için işe yaramayabilir, ancak bizim önemsediğimiz kullanıcılar yalnızca dağıtımı kolay ve hızlı bir Wafris istemcisi istiyor

Sonuç

  • SQLite kullanan v2 mimarisinden çok memnunlar
  • Şimdiden birçok sitenin saldırılara dayanmasına ve çevrimiçi kalmasına yardımcı oluyor
  • Başlamak çok daha kolay hale geldi; bu da hem destek yükünü hem de kullanıcı zahmetini azalttı
  • Bunun daha güvenli ve emniyetli bir internet için bir kazanım olduğunu düşünüyorlar

7 yorum

 
aer0700 2024-09-26

SQLite yeterince iyi ama, bu durumda sanki sadece Redis’e uygun olmayan bir kullanım senaryosuymuş gibi... geliyor bana.

 
kandk 2024-09-26

Benchmark’in M2’de yapılmış olması biraz şey..

 
colossus 2024-09-29

O zaman her bir AWS instance'ı için ayrı ayrı ölçüm mü yapmak gerekiyor? Açık kaynaktan beklentiniz biraz fazla gibi görünüyor.

 
toru123 2024-09-27

Aynı sunucu ortamında yapılmış ama bu sorun olur mu?
Benchmark için belirli bir CPU mu kullanmak gerekiyor...?

 
superwoou 2024-09-26

M2 üzerinde yapılan şeyin hangi yönleri sorun yaratabilir? (Gerçek hizmet ortamının M2 işlemcisi olmaması dışında)

 
kandk 2024-09-26

Sorun da bu zaten. Laboratuvarda deney yapıp, bunun ticari kullanım için mükemmel olduğunu iddia etmek!

 
[Bu yorum gizlendi.]