İçeriğe Atla
Mustafa Erbay
Kariyer · 8 dk okuma · görüntülenme Read in English

ERP'de Multi-Tenant Mimarisi: Doğru Trade-off Nasıl Yapılır?

ERP sistemlerinde multi-tenant mimarisi seçimi ve uygulanmasında dikkat edilmesi gereken trade-off'ları Mustafa Erbay'ın deneyimleriyle öğrenin. Maliyet,…

100%

Bir üretim ERP’sini geliştirdiğim dönemde, birden fazla müşteriye aynı yazılımı sunma ihtiyacı doğmuştu. Bu, kaçınılmaz olarak multi-tenant mimarisini gündeme getirdi. İlk başta basit bir fikir gibi görünse de, doğru trade-off’ları yapmak, projenin hem teknik hem de ticari başarısı için kritik önem taşıyordu. Bu yazıda, ERP sistemlerinde multi-tenant mimarisi kurarken karşılaştığım zorlukları ve aldığım kararları, somut örneklerle paylaşacağım.

Multi-Tenant Mimarisine Neden İhtiyaç Duyarız?

Kurumsal kaynak planlama (ERP) sistemleri, genellikle işletmelerin çekirdek operasyonlarını yönettiği karmaşık yazılımlardır. Tek bir müşteriye özel olarak geliştirilen monolitik yapılar, zamanla bakım ve güncelleme zorlukları yaratabilir. Özellikle hizmet sağlayıcılar için, her müşteriye ayrı bir sunucu ve veritabanı kurmak hem maliyetli hem de operasyonel olarak yönetilmesi güç bir senaryodur. İşte tam bu noktada multi-tenant mimarisi devreye girer.

Tek bir yazılım örneğini, birden fazla müşterinin (tenant) erişimine açarak kaynakları verimli kullanmayı hedefleriz. Bu, hem yazılımın geliştirme ve bakım maliyetlerini düşürür hem de operasyonel yükü azaltır. Örneğin, bir üretim firmasının ERP’sini geliştirirken, 5 farklı müşteriye hizmet vermek istediğimizde, her biri için ayrı bir deploy süreciyle uğraşmak yerine, tek bir sistem üzerinden hizmet verebiliriz. Bu durum, özellikle başlangıç aşamasında veya ölçeklenmesi gereken projelerde büyük bir avantaj sağlar.

Veritabanı Seviyesinde Multi-Tenancy Yaklaşımları

Multi-tenant mimarisinin en temel ve kritik kararlarından biri, veritabanı katmanında nasıl bir strateji izleneceğidir. Genellikle karşımıza üç ana yaklaşım çıkar:

  1. Tek Veritabanı, Tek Schema: Tüm tenant’ların verileri tek bir veritabanı içinde, ancak her tenant için ayrı bir schema kullanılarak saklanır. Bu, mantıksal bir ayrım sağlar.
  2. Tek Veritabanı, Tek Schema (Shared): Tüm tenant’ların verileri aynı veritabanı ve aynı schema içinde tutulur. Veri ayrımı, her tablodaki bir tenant_id sütunu ile yapılır.
  3. Ayrı Veritabanları: Her tenant için tamamen ayrı bir veritabanı örneği oluşturulur.

Bu yaklaşımların her birinin kendine göre avantajları ve dezavantajları bulunmaktadır.

Ayrı Veritabanları: İzole Ama Maliyetli

Bu yaklaşımda, her müşteri için tamamen bağımsız bir veritabanı oluşturulur. Bu, veri izolasyonu açısından en güçlü seçenektir. Bir tenant’ın verilerinin diğerine sızma riski minimumdur. Ayrıca, bir tenant’ın veritabanında yaşanacak bir performans sorunu veya hata, diğer tenant’ları doğrudan etkilemez. Bir üretim ERP’sinde, yüksek güvenlik gerektiren finansal veriler için bu yaklaşım tercih edilebilir.

Ancak, bu yaklaşımın en büyük dezavantajı maliyettir. Her müşteri için ayrı bir veritabanı sunucusu veya en azından veritabanı örneği yönetmek, kaynak tüketimini ve operasyonel maliyetleri ciddi şekilde artırır. Örneğin, 100 müşteriye hizmet verirken, her biri için ayrı bir PostgreSQL instance’ı yönetmek, hem donanım hem de lisans maliyetleri (eğer ticari bir veritabanı kullanılıyorsa) açısından kabarık bir fatura çıkaracaktır. Ayrıca, veritabanı bakımı, yedekleme ve güncelleme işlemleri de her bir veritabanı için ayrı ayrı yapılmak zorunda kalır, bu da operasyonel karmaşıklığı artırır.

Tek Veritabanı, Tek Schema (Shared): Kaynak Verimliliği ve Risk

Bu yaklaşımda, tüm tenant’ların verileri aynı veritabanı ve aynı schema içindeki tablolarda saklanır. Veri ayrımı, her tablodaki tenant_id sütunu ile sağlanır. Örneğin, bir orders tablosunda her satırın hangi müşteriye ait olduğunu belirten bir tenant_id alanı bulunur. Bu, kaynak kullanımı açısından en verimli yöntemdir. Tek bir veritabanı örneği, birden fazla müşteriye hizmet verebilir. Bu, özellikle başlangıç aşamasındaki SaaS (Software as a Service) ürünleri için maliyet avantajı sağlar.

Ancak bu yaklaşımın en büyük riski, veri izolasyonunun zayıf olmasıdır. Eğer uygulama katmanında yeterli güvenlik önlemleri alınmazsa, bir tenant’ın diğerinin verilerine erişmesi mümkün olabilir. Hatalı bir WHERE tenant_id = X filtresi unutulduğunda, tüm müşterilerin verileri listelenebilir. Bu durum, özellikle finansal verilerle uğraşan bir ERP sisteminde felaketle sonuçlanabilir. Ayrıca, bir tenant’ın yoğun veritabanı kullanımı, diğer tüm tenant’ların performansını olumsuz etkileyebilir. Bir üretim ERP’sinde, bir müşterinin yoğun raporlama isteği, diğer müşterilerin sipariş girişlerini yavaşlatabilir.

-- Örnek: Shared Schema'da Veri Sorgulama
SELECT
    order_id,
    product_name,
    quantity,
    order_date
FROM
    orders
WHERE
    tenant_id = 'musteri-abc-123'; -- Mutlaka tenant ID ile filtreleme yapılmalı!

Bu yaklaşımda tenant_id filtrelemesi kritik öneme sahiptir. Yanlışlıkla bu filtreyi kullanmadan yapılan bir sorgu, tüm verilerin açığa çıkmasına neden olabilir. Bu nedenle, uygulama katmanında sıkı kontroller ve testler yapılmalıdır.

Tek Veritabanı, Farklı Schemalar: Dengeli Bir Yaklaşım

Bu yaklaşım, yukarıdaki iki yöntemin bir nevi ortasıdır. Tüm tenant’lar tek bir veritabanı örneğini paylaşır, ancak her tenant’ın verileri kendi özel schema’sında tutulur. Örneğin, musteri_abc schema’sı altında orders, products gibi tablolar bulunurken, musteri_xyz schema’sı altında da aynı isimde tablolar yer alır. Bu, hem kaynakları verimli kullanmayı sağlar hem de veri izolasyonunu bir nebze olsun güçlendirir.

Bu yöntem, veri güvenliği açısından shared schema’dan daha iyidir. Çünkü sorgular, doğrudan ilgili tenant’ın schema’sına yapılır ve tenant_id gibi ek filtrelemelere daha az ihtiyaç duyulur. Ancak, veritabanı yönetimi karmaşıklığı artar. Her schema’nın bakımı, yedeği ve güncellenmesi ayrı ayrı planlanmalıdır. Ayrıca, birden fazla schema yönetimi, bazı veritabanı operasyonlarını (örneğin, tüm tenant’lar için toplu bir güncelleme yapmak) daha karmaşık hale getirebilir.

Uygulama Katmanında Tenant Yönetimi

Veritabanı stratejisi ne olursa olsun, uygulama katmanında tenant’ı doğru bir şekilde tanımlamak ve yönetmek hayati önem taşır. Bir HTTP isteği geldiğinde, hangi tenant’a ait olduğunu bilmemiz gerekir. Bu bilgi, genellikle isteğin başlıklarından (örneğin, X-Tenant-ID gibi özel bir başlık), alt alan adlarından (örneğin, musteri-abc.erp.com) veya kullanıcı oturum bilgilerinden alınır.

Bu tenant kimliği, daha sonra veritabanı sorgularında kullanılacak doğru veritabanı bağlantısını veya schema’yı seçmek için kullanılır. Eğer shared schema yaklaşımı benimsendiyse, gelen tenant kimliği, her sorguya otomatik olarak eklenmelidir. Bu genellikle bir middleware veya request interceptor aracılığıyla yapılır. Örneğin, FastAPI kullanıyorsak, bir Depends fonksiyonu ile request’ten tenant bilgisini alıp, ORM’imize (Object-Relational Mapper) bu bilgiyi iletebiliriz.

# FastAPI örneği: Tenant bilgisini request'ten almak
from fastapi import FastAPI, Request, Depends

app = FastAPI()

async def get_current_tenant(request: Request) -> str:
    tenant_id = request.headers.get("X-Tenant-ID")
    if not tenant_id:
        raise HTTPException(status_code=400, detail="X-Tenant-ID header is missing")
    # Burada tenant ID'nin geçerliliğini kontrol edebiliriz
    return tenant_id

@app.get("/orders")
async def read_orders(current_tenant: str = Depends(get_current_tenant)):
    # Veritabanı sorgusunu current_tenant ile yap
    orders = await db.fetch_all(f"SELECT * FROM orders WHERE tenant_id = '{current_tenant}'")
    return orders

Bu kod parçacığı, gelen her isteğin X-Tenant-ID başlığını kontrol eder ve bu başlık olmadan gelen isteklere izin vermez. Ardından, alınan tenant kimliği, veritabanı işlemlerinde kullanılır. Bu, uygulama katmanında tenant izolasyonunu sağlamanın temel adımlarından biridir.

Ölçeklenebilirlik ve Performans Trade-off’ları

Multi-tenant bir mimari tasarlarken, ölçeklenebilirlik ve performans her zaman öncelikli konular olmalıdır. Özellikle yoğun veri işleyen ERP sistemlerinde, bir tenant’ın performansı diğerlerini etkilememelidir.

Shared veritabanı veya schema yaklaşımlarında, tüm tenant’lar aynı veritabanı kaynaklarını paylaşır. Bu, bir tenant’ın aşırı kaynak tüketmesi durumunda diğerlerinin yavaşlamasına neden olabilir. Örneğin, bir müşteri, büyük bir veri setini işleyen karmaşık bir rapor çalıştırdığında, sistem genelinde performans düşüşleri yaşanabilir. Bu tür durumları yönetmek için kaynak sınırlamaları (resource limiting) ve izleme mekanizmaları kritik önem taşır.

Ayrı veritabanı yaklaşımı, doğal olarak daha iyi ölçeklenebilirlik ve performans izolasyonu sunar. Ancak, bu durumda da her veritabanı örneğinin kendi başına ölçeklenmesi gerekir. Binlerce tenant’ınız olduğunda, her birini ayrı ayrı ölçeklendirmek operasyonel bir kabusa dönüşebilir. Bu nedenle, ölçeklendirme stratejisi, iş yükünün türüne ve maliyet kısıtlamalarına göre dikkatlice planlanmalıdır.

Güvenlik ve Uyumluluk (Compliance)

Multi-tenant sistemlerde güvenlik, en hassas konulardan biridir. Veri ihlalleri, sadece finansal kayıplara değil, aynı zamanda itibar kaybına ve yasal sorunlara da yol açabilir. ERP sistemleri genellikle hassas finansal, üretim ve müşteri verilerini barındırdığı için, güvenlik önlemleri üst düzeyde olmalıdır.

Veri izolasyonu, güvenlik stratejisinin temel taşıdır. Yukarıda bahsedilen veritabanı yaklaşımları, bu izolasyonu farklı seviyelerde sağlar. Ayrı veritabanları en yüksek izolasyonu sunarken, shared schema en düşük izolasyonu sunar. Uygulama katmanındaki kontrollerin doğruluğu, bu izolasyonun ne kadar etkili olacağını belirler.

Ayrıca, GDPR, CCPA gibi veri gizliliği düzenlemelerine uyum da multi-tenant mimariler için önemli bir faktördür. Her tenant’ın verilerinin nerede saklandığı, nasıl işlendiği ve kimlerin erişebildiği gibi konuların net bir şekilde belirlenmesi gerekir. Bu, özellikle farklı coğrafi bölgelerdeki müşterilere hizmet verirken daha da karmaşık hale gelir.

Maliyet Analizi ve Trade-off’lar

Son olarak, tüm bu kararların maliyet üzerindeki etkisini göz ardı etmemek gerekir.

  • Ayrı Veritabanları: Yüksek başlangıç ve işletme maliyeti, ancak en iyi izolasyon ve potansiyel olarak en iyi performans.
  • Tek Veritabanı, Tek Schema (Shared): En düşük başlangıç ve işletme maliyeti, ancak en düşük izolasyon ve performans riskleri.
  • Tek Veritabanı, Farklı Schemalar: Maliyet ve izolasyon arasında iyi bir denge.

Bir üretim ERP’sini geliştirirken, ilk başta maliyetleri düşük tutmak adına shared schema ile başlamayı düşünebiliriz. Ancak, müşteri tabanı büyüdükçe ve veri hassasiyeti arttıkça, schema bazlı ayrım veya hatta bazı kritik tenant’lar için ayrı veritabanları gibi daha güvenli ve izole çözümlere geçiş yapmayı planlamak akıllıca olacaktır. Bu tür geçişler, mimarinin esnekliği ve modülerliği ile mümkün olur.

Örneğin, başlangıçta 5 küçük müşteriye hizmet verirken shared schema ile yola çıkıp, zamanla 50 müşteriye ulaştığımızda ve bu müşterilerden biri büyük bir kurumsal firma olduğunda, bu firmayı ayrı bir veritabanına taşımak mantıklı olabilir. Bu, stratejik bir karardır ve projenin büyüme aşamasına göre şekillendirilir. Bu tür kararlar, sadece teknik değil, aynı zamanda iş hedefleriyle de uyumlu olmalıdır.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

Sıkça Sorulanlar

Bu makale ile ilgili okurların sorduğu yaygın sorular.

ERP projemde multi-tenant mimarisine nasıl başladım ve hangi araçları kullandım?
Ben ilk adım olarak mevcut monolitik kod tabanını modüler hale getirdim ve Docker ile konteynerizasyon yaptım. CI/CD sürecini GitHub Actions üzerinden otomatikleştirerek her yeni tenant için aynı pipeline'ı tekrar kullanabildim. Veritabanı izolasyonu için PostgreSQL şemalarını tercih ettim; bu sayede tek bir veri kümesi içinde tenant bazlı ayrım sağladım. ORM olarak TypeORM'i, konfigürasyon yönetimi için ise dotenv ve config paketlerini kullandım. Bu kombinasyon, kod değişikliklerini hızlıca test edip, yeni bir müşteri eklemek istediğimde sadece konfigürasyon dosyasına bir satır ekleyerek ortamı ayağa kaldırmamı sağladı.
Tek veritabanı‑tek şema mı, yoksa çok şema yaklaşımı mı daha avantajlıydı?
Ben projenin ilk aşamasında tek veritabanı‑tek şema modelini denedim; başlangıç maliyeti düşük ve sorgular daha basitti. Ancak tenant sayısı arttıkça veri izolasyonu ve performans sorunları ortaya çıktı. Şema başına ayrı veri kümesi oluşturduğum çok şema modeline geçince, her tenant için indeks ve yedekleme politikalarını bağımsız olarak ayarlayabildim; bu da güvenlik ve ölçeklenebilirliği artırdı. Dezavantajı ise şema yönetiminin karmaşıklaşması ve migration süreçlerinin daha titiz bir planlama gerektirmesi oldu. Sonuçta, orta ve büyük ölçekli projelerde çok şema tercih etmenin uzun vadeli bakım maliyetini azalttığını gördüm.
Multi-tenant mimarisinde bir hata alırsam nasıl ilerlemeliyim?
Ben hatayla karşılaştığımda öncelikle log seviyesini DEBUG yapıp, tenant ID'siyle ilişkilendirilen tüm SQL sorgularını izledim. Sorun genellikle ortak kodda bir veri modeli değişikliği sonrası tüm şemalarda aynı migration'ın uygulanamamasından kaynaklanıyordu. Bu durumda, hatalı tenant'ı izole edip, migration'ı manuel olarak o şemada çalıştırıyorum ve ardından otomatik test setini tekrar çalıştırıyorum. Sabit bir kural değil; fakat ben her bir hatayı güvenilir şekilde tekrar üretmeyi ve çözümün tüm tenant'larda tutarlı çalıştığını doğrulamak için bütün entegrasyon testlerini çalıştırmayı alışkanlık haline getirdim.
Genel kanı, multi-tenant sistemlerin performansının tek‑tenant sistemlerden düşük olduğu doğru mu?
Ben bu görüşün kısmen doğru, kısmen yanıltıcı olduğunu söyleyebilirim. Tek‑tenant mimaride her müşteri için ayrı bir veri tabanı ve uygulama örneği olduğu için kaynaklar doğrudan o müşteriye tahsis edilir; bu da teorik olarak daha yüksek performans anlamına gelir. Ancak ben birden fazla tenant'ı aynı altyapı üzerinde koordine ettiğimde, paylaşılan cache, connection pool ve sorgu optimizasyonları sayesinde performans kaybını minimal seviyeye indirdim. Kritik yolculuklarda, özellikle yüksek I/O gerektiren raporlamalarda, izolasyon maliyetini önceden ölçüp, gerektiğinde tenant başına ayrı bir micro‑service eklemek daha akıllıca oluyor.
ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Yeni yazılardan haberdar olun

Yeni içerikler ve teknik notlar e-postanıza gelsin.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar