Mimari

Multi-tenant SaaS mimarisi: kiracı izolasyonunu nerede kurmalı?

Tek veritabanı mı, şema başına kiracı mı, veritabanı başına kiracı mı? Üç modelin maliyeti, riski ve hangi durumda hangisinin doğru olduğu — NFC menü platformumuzdan çıkan derslerle.

Anıl Yücel11 dk okuma

Bir SaaS ürününde en pahalı yanlış karar, kiracı izolasyonunun nerede kurulacağıdır. Yanlış seçim ürünü öldürmez ama iki yıl sonra göç etmek altı aylık bir iş haline gelir. Bu yazı üç modeli, gerçek maliyetleriyle karşılaştırıyor.

Kiracı (tenant) nedir, neden zor?

Kiracı, verisi diğerlerinden ayrı tutulması gereken müşteri hesabıdır. Zorluk şurada: aynı kodu çalıştırıyorsunuz, aynı veritabanına bakıyorsunuz, ama bir kiracının sorgusu asla diğerinin satırını görmemeli. Bunu sağlamanın üç yolu var ve üçü de farklı yerde bedel ödetiyor.

Model 1: Tek veritabanı, satır seviyesi izolasyon

Tüm kiracılar aynı tablolarda oturur, her satırda bir tenant_id vardır. En yaygın ve çoğu ürün için doğru başlangıç.

Kritik nokta: filtrelemeyi uygulamaya bırakmayın, veritabanına yaptırın. PostgreSQL'de Row Level Security tam olarak bunun içindir.

-- Kiracı bazlı satır güvenliği: filtre veritabanı seviyesinde zorunlu
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
ALTER TABLE orders FORCE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON orders
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

-- Her istekte, işlem başında kiracı bağlamı kurulur
SET LOCAL app.tenant_id = '3f1c...';

-- Artık WHERE unutulsa bile başka kiracının satırı dönmez
SELECT * FROM orders;

FORCE ROW LEVEL SECURITY'yi atlamayın: onsuz tablo sahibi rolü politikayı baypas eder ve uygulamanız genelde tablo sahibi olarak bağlanır.

  • Artı: tek göç (migration), tek yedek, tek bağlantı havuzu. Yüzlerce kiracıda bile işletme maliyeti sabit.
  • Artı: kiracı oluşturmak bir satır eklemek kadar ucuz — self-servis kayıt akışı mümkün.
  • Eksi: "gürültülü komşu" riski. Bir kiracının ağır raporu diğerlerini yavaşlatabilir.
  • Eksi: tek bir kiracının verisini dışa aktarmak veya silmek ayrı iş gerektirir.
  • Eksi: bazı kurumsal müşteriler ve bazı düzenlemeler fiziksel ayrım ister; bu model onu karşılamaz.

Model 2: Kiracı başına şema

Aynı veritabanı, her kiracı için ayrı şema. PostgreSQL'de search_path ile kiracıya göre yönlendirilir.

  • Artı: veri ayrımı yapısal, sorgu filtresine bağlı değil.
  • Artı: tek kiracının yedeğini almak ve geri yüklemek kolay.
  • Eksi: göçler kiracı sayısı kadar tekrarlanır. 300 kiracıda bir kolon eklemek uzun süren ve kısmen başarısız olabilen bir işleme dönüşür.
  • Eksi: bağlantı havuzu ve search_path yönetimi hata kaynağıdır; yanlış bağlamda çalışan bir sorgu sessizce yanlış şemaya yazar.

Bu modeli, kiracı sayısı düşük ve öngörülebilir olduğunda (onlarca, yüzlerce değil) tercih ediyoruz.

Model 3: Kiracı başına veritabanı

Tam ayrım. Genelde büyük kurumsal müşteriler, veri ikametgâhı gereklilikleri veya sözleşmesel izolasyon şartı olduğunda gerekir.

  • Artı: en güçlü izolasyon; performans da kiracılar arasında yalıtılır.
  • Artı: veri ikametgâhı (bölgeye göre barındırma) doğal olarak çözülür.
  • Eksi: altyapı maliyeti kiracı sayısıyla doğrusal artar.
  • Eksi: göç ve izleme ciddi otomasyon gerektirir; bu otomasyon ürünün kendisi kadar bakım ister.

Karar tablosu

  1. Çok sayıda küçük kiracı ve self-servis kayıt bekliyorsanız → tek veritabanı + RLS. Neredeyse her zaman doğru başlangıç.
  2. Az sayıda büyük kiracı ve kiracı bazlı yedek/geri yükleme ihtiyacı → şema başına kiracı.
  3. Sözleşmede fiziksel ayrım veya veri ikametgâhı şartı → veritabanı başına kiracı.
  4. Emin değilseniz → tek veritabanı + RLS ile başlayın. Buradan diğerlerine göç etmek, tersine göç etmekten çok daha kolaydır.

Modelden bağımsız üç kural

Kiracı bağlamı tek yerden kurulmalı

Middleware katmanında bir kez belirlenip isteğin geri kalanına taşınmalı. Controller içinde req.user.tenantId okuyan her satır, bir gün unutulacak bir satırdır.

Arka plan işleri en tehlikeli yer

HTTP isteğinde kiracı bağlamı doğaldır; kuyruktan çıkan bir işte değildir. Kuyruğa yazılan her mesaj kiracı kimliğini taşımalı ve işleyici bağlamı kurmadan hiçbir sorgu çalıştırmamalı. Sızıntıların çoğu burada oluyor.

Silme işlemini baştan tasarlayın

Bir kiracı ayrıldığında verisini ne kadar sürede, hangi kapsamda sileceğinizi baştan belirleyin. KVKK ve GDPR bunu talep ediyor, üstelik sonradan eklenmesi en zor özelliklerden biri.

Uygulamada

Arzuio NFC menü platformunda çok sayıda küçük kiracı (restoran) ve self-servis kurulum beklendiği için tek veritabanı + satır seviyesi izolasyon seçtik. Süperadmin paneli, partner panosu ve müşteri arayüzü aynı veri katmanını farklı bağlamlarla kullanıyor. Kararı belirleyen şey teknoloji tercihi değil, kiracı profiliydi.

Kendi ürününüz için bu kararı verirken sorulacak tek soru şu: kaç kiracı bekliyorsunuz ve her biri ne kadar büyük? Cevap mimariyi belirler.

  • saas
  • multi-tenant
  • mimari
  • postgresql

45 dakika · ücretsiz · taahhütsüz

Bu konuda yardıma mı ihtiyacınız var?

Yazıda anlattığımız işleri müşterilerimiz için yapıyoruz. 45 dakikalık ücretsiz görüşmede sizin durumunuza bakalım.

Ücretsiz görüşme planla
WhatsApp