MİMARİ ÖRÜNTÜLER

Saga Pattern (Saga Örüntüsü)

Onur Dayıbaşı
Architectural Patterns
4 min readJan 21, 2021

--

Flux Mimarisi yazımda Redux Async işlemlerin side effectlerinden kurtarmak için 2 tip Middleware kullanıldığından bahsetmiştik.

Bu 2 middleware arasında ne gibi farklar olduğunu daha sonraki yazımda anlatacağım. Bu yazıda bu Saga Pattern neymiş nerden geliyormuş onu anlamaya çalışalım.

Saga Örüntüsü aslında veri tabanındaki uzun transaction işlemleri sırasında oluşacak hataları engellemek için geliştirilmiş Hata Yönetim Örüntüsü’dür Yani uzun bir transaction işlemini parçalara bölerek T(all)

T(all) = T1,T2,T3 ......Tn

Aynı zamanda her bir transaction parçasında olabilecek hataları sonrasında Kompanse edecek mekanizmaların yazılması anlamına gelir.

C(all) = C1,C2,C3 .....Cn

Burada Kompanse edecek mekanizma bazen rollback olurken bazende üzerine yazma anlamına gelebilir. Örneğin eposta attınız bunu geri alabilme şansınız yok bunun yerine onun üzerine bir öncekinin geçerli olmadığına dair yeni bir eposta atabilirsiniz mesala.

Saga Örüntüsü konusunu aşağıdaki video üzerinden çok implementasyon detaylarına girmeden anlamaya çalışırsak

GOTO 2015 • Applying the Saga Pattern • Caitie McCaffrey

Halo Oyunu Microsoft tarafından XBox üzerine getirilirken çok büyük tek SQL veritabanı üzerinde milyonlarda transaction yönetmenin imkansız olması ve ölçekleneMEmesi yüzünden NoSQL ve dağıtık yapılara web servislerini taşıma ve bu taşıma sırasında Atomicity ve Serialization kaybetmenin önüne nasıl geçtiklerinin üzerine bir konuşma.

İlişkisel veritabanlarında transaction yapısı için tanımlanmış özellik seti olan ACID . sayesinde işlemleri birbirine karıştırmadan veya herhangi bir problem olduğunda geri (rollback) yapabilme imkanı bulabiliriz. Yönetimi dağıtık sisteme göre daha basit olan bir yöntem.

Single DB (Mono)

İşler kompleks hale geldikçe CAP Teoremi ve buna uygun hazırlanmış dağıtık veritabanlarında bu işleri nasıl yöneteceğiz. Çünkü dağıtık bir sistemde Transaction’dan söz etmek pek de mümkün değil. Burda Servisler bölümmüş Car, Hotel ve Airline Reservason sistemleri ayrı ayrı hizmet veren servisler hale gelmiş durumda burada oluşacak Hata Durumunu yönetmek bir önceki Single DB göre oldukça zor.

Dağıtık DB

2PC (Two Phase Commit)

Bu durumu yönetmek için değişik teknikler kullanılıyor. Bunlardan bir tanesi 2PC (Two Phase Commit) Protokolü. Burada öncelikle Coordinator gibi bir yapıya ihtiyaç duyulur. Coordinator

  1. Safha(Prepare Phase): Tüm kaynaklardan bir işlem yapmasını ister.
  2. Safha(Commit Phase): Tüm kaynaklardan olumlu sonuç dönüldüyse Commit mesajı gönderir. Eğer resource en az bir tanesinden olumsuz bir sonuç gelmiş ise bu durumda Abort mesajı göndererek işlemi sonlandırır.
Two Phase Commit

Bu yöntem probleme bir çözüm getiriyor ama ölçeklenmiyor. Nedeni mesaj sayısı kompleksitesini arttırıyor, Throughput azaltıyor ve Coordinator Single Point of Failure durumu oluşturuyor

Spanner (Google Globally-Distributed DB)

Google dağıtık veritabanları arasında özel fiber kabloları ve TrueTimerAPI(Atomic Clock) ve GPS ile veri merkezleri arasında o kadar küçük zaman aralıklarında yapabiliyor ki bu CAP Teoremindeki problemleri bir şekilde egale edebiliyor. Tabi çok pahalı ve tam anlamıyla synchronization sağlamış değil. Olay zaman kapsüllerini ne kadar küçük yapabildiğiniz ile ilgili . Örneğin TV ve Bilgisayar ekranı 40 Frame Per Second ile render edilirken insan gözüne bu problem oluşturmadığı için hiç bir takılma vs hissetmiyoruz. Ama saniye/40 da bir ekrandaki resim değişiyor. Aynısı Google Veritaban senkranizasyonları içinde geçerli.

Saga

Dağıtık sistemler ve CAP teoreminden vazgeçemiyorsak diğer bir yöntemde belki Serializability ve ACID gibi kavramlardan vazgeçerek bu durumu kod/uygulama business mantığı çözmeye çalışmak olabilir. Yukarıda bahsettiğim Transaction parçalara bölme ve her işlem için bir Kompanse sistemi oluşturmak gerekiyor. Bu durumda aşağıdaki gibi Tüm Transaction bölümlememiz gerekiyor

Saga Pattern

Öncelikle Transaction bütünümüzü parçalara ayırmamız gerekiyor.

T: T(rentcar), T(bookhotel),  T(bookflight)

Şimdide herhangi bir aşamada ortaya çıkacak hata durumunda Companse adımlarını tanımlamamız gerekiyor

C: C(cancelcar), C(cancelhotel), C(cancelflifht)

Görüldüğü gibi istediğimiz gibi birbirinden bağımsız ölçeklenebilir sistemler tasarlayabiliriz artık. Bu sistemleri tasarlarken ya kendimizin yazacağı DB üzerinde persist yöntemi ile bu süreci yönetebiliriz veya AWS Step Functions gibi hazır mekanizmaları kullanabiliriz.

Referanslar

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara(JS Async Programlama) erişmek için bu linke tıklayabilirsiniz.

Bu yazının devamı veya yazı grubundaki diğer yazılara(Mimari Örüntüler) erişmek için bu linke tıklayabilirsiniz.

--

--