MİMARİ~5 dakika okuma süresi

Single-Tenant ve Multi-Tenant: SaaS Mimarinde Hangi Tarafı Seçmelisin?

Single-tenant ve multi-tenant mimari modelleri arasındaki farkları, avantajlarını, risklerini ve hangi senaryoda hangi modelin daha uygun olduğunu Spring Boot örnekleriyle birlikte bu yazıda bulabilirsiniz.

Single-Tenant ve Multi-Tenant: SaaS Mimarinde Hangi Tarafı Seçmelisin?

Bir SaaS (Software as a Service) projesi geliştirirken vermeniz gereken en temel ve en kritik kararlardan biri “tenant” (kiracı) modelidir. Bu karar, uygulamanızın maliyetini, ölçeklenebilirliğini, güvenliğini ve hatta pazar stratejinizi doğrudan etkiler. Bu seçimi bir emlak yatırımı gibi düşünebilirsiniz: Her müşterinize özel bir villa mı (Single-Tenant) tahsis edeceksiniz, yoksa herkesin ortak altyapıyı paylaştığı lüks bir rezidansta (Multi-Tenant) daireler mi sunacaksınız?

Bu yazıda, her iki modelin ne anlama geldiğini, teknik olarak nasıl uygulandığını ve en önemlisi, projeniz için hangi modelin daha doğru olduğuna nasıl karar verebileceğinizi inceleyeceğiz.

Single-Tenant (Tek Kiracılı): Her Müşteriye Özel Bir Villa 🏡

Single-Tenant modelinde, her bir müşteri (tenant) için tamamen bağımsız bir yazılım örneği (instance) ve altyapı (veritabanı, sunucu vb.) sağlanır. Tıpkı her ailenin kendine ait, bahçesiyle, havuzuyla tamamen izole bir villada yaşaması gibi. Bir müşterinin verileri, diğerlerininkine asla karışmaz.

Avantajları:

  • ✅ Maksimum Güvenlik ve İzolasyon: Her müşteri kendi kalesindedir. Bir müşterinin verilerinin diğerine sızma riski teorik olarak sıfırdır. Bu, özellikle bankacılık, sağlık gibi regülasyonların sıkı olduğu sektörler için kritiktir.
  • ✅ Sınırsız Özelleştirme: Müşteri, kendi villasına istediği gibi ek kat çıkabilir veya rengini değiştirebilir. Yani, yazılımı kendi özel ihtiyaçlarına göre tamamen özelleştirebilirler.
  • ✅ Garantili Performans: "Gürültülü komşu" (noisy neighbor) problemi yoktur. Bir müşterinin sistemi aşırı yüklemesi, diğerlerini etkilemez çünkü kaynaklar paylaşılmaz.

Dezavantajları:

  • ❌ Yüksek Maliyet: Her müşteri için ayrı bir altyapı kurmak, yönetmek ve bakımını yapmak hem başlangıçta hem de operasyonel olarak çok daha pahalıdır.
  • ❌ Karmaşık Yönetim: Yeni bir güncelleme yayınladığınızda, bunu her müşteri için tek tek yapmanız gerekir. Bu, yüzlerce müşteriniz olduğunda bir kabusa dönüşebilir.

Multi-Tenant (Çok Kiracılı): Lüks Bir Rezidans 🏢

Multi-Tenant modelinde ise, tek bir yazılım örneği ve altyapı, birden fazla müşteri tarafından paylaşılır. Tıpkı büyük bir rezidanstaki daireler gibi. Herkesin kendi özel dairesi (verileri) vardır, ancak binanın su tesisatı, elektrik altyapısı ve güvenlik sistemi (sunucu, veritabanı, uygulama) ortaktır.

Avantajları:

  • ✅ Düşük Maliyet: Altyapı maliyetleri tüm müşterilere bölündüğü için birim başına maliyet ciddi oranda düşer. Bu, rekabetçi fiyatlandırma yapmanızı sağlar.
  • ✅ Kolay Bakım ve Güncelleme: Tek bir tuşla tüm müşterileriniz için güncelleme yayınlayabilirsiniz. Bu, çevikliği ve hızı artırır.
  • ✅ Hızlı Ölçeklenebilirlik: Yeni bir müşteriyi sisteme dahil etmek, sadece yeni bir daire anahtarı vermek kadar kolaydır. Altyapı zaten hazırdır.

Dezavantajları:

  • ❌ Daha Karmaşık Güvenlik: Tüm müşterilerin verileri aynı yerde durduğu için (farklı mantıksal ayrımlarla), veri izolasyonunu kusursuz bir şekilde sağlamak zorundasınız. En ufak bir hata, bir müşterinin diğerinin verisini görmesine neden olabilir.
  • ❌ Sınırlı Özelleştirme: Rezidans yönetimi, tüm binayı etkileyecek büyük değişikliklere izin vermez. Müşteriler genellikle sadece konfigürasyon seviyesinde özelleştirme yapabilir.

Şimdi bu iki modelin Spring Boot ile nasıl hayata geçirilebileceğine dair basit örneklere bakalım.

Single-Tenant Uygulama Örneği (Dinamik Veritabanı Bağlantısı)

Buradaki fikir, gelen isteğin hangi müşteriye ait olduğunu anlayıp o müşterinin özel veritabanına bağlanmaktır. Müşteri kimliğini genellikle bir X-Tenant-ID HTTP header'ı, bir subdomain (customer1.yourapp.com) veya bir JWT token içerisinden alırız.

Önce, gelen istekten müşteri kimliğini (tenant ID) çözen bir bileşen yazalım:

// TenantIdentifierResolver.java
@Component
public class TenantIdentifierResolver {
    public String resolveTenant(HttpServletRequest request) {
        String tenantId = request.getHeader("X-Tenant-ID");
        if (tenantId == null || tenantId.isEmpty()) {
            throw new RuntimeException("Tenant ID bulunamadı!");
        }
        return tenantId;
    }
}

Bu kod, her isteğin header'ından X-Tenant-ID'yi okuyarak hangi müşteriye hizmet verileceğini belirler.

Ardından, bu kimliğe göre dinamik olarak doğru veritabanı bağlantısını (DataSource) oluşturan bir yapı kurarız:

// DataSourceConfig.java
@Configuration
public class DataSourceConfig {
    private final Map<String, DataSource> dataSources = new HashMap<>();

    public DataSource getDataSource(String tenantId) {
        // Eğer bu tenant için daha önce bağlantı oluşturulmadıysa, yenisini yarat ve sakla.
        return dataSources.computeIfAbsent(tenantId, this::createNewDataSource);
    }

    private DataSource createNewDataSource(String tenantId) {
        // tenantId'ye göre dinamik veritabanı URL'i oluşturuluyor.
        return DataSourceBuilder.create()
                .url("jdbc:mysql://localhost:3306/" + tenantId) // Örn: "jdbc:mysql://localhost:3306/customer_a_db"
                .username("root")
                .password("password")
                .driverClassName("com.mysql.cj.jdbc.Driver")
                .build();
    }
}

Bu yapı sayesinde her müşteri, kendi veritabanına tamamen izole bir şekilde bağlanır.

Ne zaman Single-Tenant kullanmalıyım?

  • 🏦 Bankacılık, sağlık gibi verinin kutsal olduğu ve yüksek izolasyon gerektiren sektörlerde.
  • 🏢 Her biri milyonlarca dolar ödeyen ve tamamen kendilerine özel bir çözüm isteyen büyük kurumsal müşterilere hizmet verirken.

Multi-Tenant Uygulama Örneği (Satır Bazında İzolasyon)

Multi-Tenant modelinin en popüler uygulaması, tüm müşterilerin aynı tabloyu paylaştığı ama her satırın bir tenant_id kolonu ile hangi müşteriye ait olduğunun belirtildiği yöntemdir.

Burada en büyük zorluk, her veritabanı sorgusuna otomatik olarak WHERE tenant_id = 'current_tenant_id' koşulunu eklemeyi unutmamaktır. Neyse ki Hibernate gibi ORM'ler bu işi bizim için otomatikleştirebilir.

Hibernate Filter kullanarak her entity için bir "tenant filtresi" tanımlayabiliriz:

// Customer.java
@Entity
@FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantId", type = "string"))
@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
public class Customer {
   @Id
   private Long id;
   private String name;
   private String tenantId; // Her satırın hangi müşteriye ait olduğunu belirten kolon.
}

Bu @Filter anotasyonu sayesinde, bu Customer entity'si için yapılan tüm sorgulara otomatik olarak tenant_id kontrolü eklenir. Böylece A müşterisi, B müşterisinin verilerini asla göremez. Geliştiricinin her sorguda bunu manuel olarak hatırlamasına gerek kalmaz.

Ne zaman Multi-Tenant kullanmalıyım?

  • 🚀 Hızlı büyümeyi hedefleyen ve birim maliyetleri düşük tutmak isteyen çoğu SaaS startup'ı için.
  • 🛍️ CRM, e-ticaret platformları, proje yönetim araçları gibi standart bir hizmet sunan uygulamalarda.

Sonuç: Karar Anı - Villa mı, Rezidans mı? 🎯

Peki, hangi modeli seçmelisiniz? Bu sorunun "doğru" bir cevabı yok; sadece projenizin hedeflerine ve müşterilerinizin beklentilerine "uygun" bir cevap var. Karar verirken kendinize şu soruları sorun:

  1. Müşterilerim Kim? Müşterileriniz, veri güvenliği için milyonlar ödemeye hazır büyük bankalar mı, yoksa uygun fiyatlı bir çözüm arayan küçük işletmeler mi? İlk senaryo Single-Tenant'a, ikincisi Multi-Tenant'a işaret eder.
  2. Ne Kadar Özelleştirme Sunacağım? Her müşterinin kendine özel talepleri mi olacak, yoksa herkese standart bir paket mi sunacaksınız? Yoğun özelleştirme ihtiyacı Single-Tenant'ı gerektirebilir.
  3. Büyüme Stratejim Ne? Ayda binlerce yeni müşteriyi hızlıca sisteme dahil etmeyi mi hedefliyorsunuz? Öyleyse Multi-Tenant'ın getirdiği operasyonel kolaylık hayat kurtarır.
  4. Bütçem Ne Kadar? Başlangıç maliyetlerini düşük tutup pazara hızlıca girmek istiyorsanız, Multi-Tenant en mantıklı yoldur.

Unutmayın, bu iki model arasında hibrit çözümler de mevcuttur. Örneğin, standart müşterilerinize Multi-Tenant bir altyapı sunarken, en büyük kurumsal müşterilerinize (Enterprise plan) Single-Tenant bir seçenek sağlayabilirsiniz.

Hangi yolu seçerseniz seçin, bu karar projenizin temelini oluşturur. Geriye dönmesi zor, maliyetli ve karmaşık bir karardır. Bu yüzden acele etmeyin, iş modelinizi ve teknik kapasitenizi masaya yatırın ve en bilinçli seçimi yapın.

Umarım bu yazı, bu önemli karar sürecinde yolunuzu aydınlatmıştır. Kendi projelerinizde hangi modeli neden seçtiğinizi yorumlarda paylaşırsanız, herkes için faydalı bir tartışma ortamı yaratabiliriz! 🚀

Tüm Mimari yazıları