Saga Pattern: Distributed Transaction Yönetimi

Saga Pattern Distributed Transactions

Microservice mimarisini kullanmanın bir çok avantajı var. Ancak bu avantajlar bir takım zorlukları da beraberinde getiriyor. Bu zorluklardan bir tanesi de servislere yayılmış distributed transaction‘ları yönetirken veri tutarlılığının sağlanmasıdır. Bu zorluğun üstesinden gelmek için Saga Pattern kullanılır.

Örneğin: bir e-commerce uygulamasında müşteri sepetindeki ürünleri siparişe çevirdiğinde bu istek Order mikroservisine giderek siparişi işliyor. Ancak bu işlemden sonra Inventory mikroservisininde stoğu güncellemesi gerekiyor. Bu durumda iki mikroservisinde kendi verisini tek bir istekte işlemesi gerekiyor. Mikroservis mimarisi yerine monolithic bir yapıyla çalışıyor olsaydık tek bir veritabanı kullanıyor olacak ve işlemlerimizi tek bir transaction ile gerçekleştirebilecektik. Her bir mikroservis dağıtık ve kendi veritabanını kullandığı için bu noktada distributed transaction kavramı devreye giriyor.

Ayrıca bu işlemler gerçekleşirken veri tutarlılığının da sağlanması gerekiyor. Sipariş işlendikten sonra stok miktarının da düşürül(e)mediği durumlarda veriler arasında tutarsızlıklar oluşmaya başlayacak. Buna göre gerçekleşen bir transaction’un başarılı sayılabilmesi için ACID yani, Atomic, Consistent, Isolated ve Durable özelliklerini taşıyor olması gerekiyor.

  • Atomicity: tüm transaction’lar ya başarıyla gerçekleşmeli ya da hiç biri gerçekleşmemeli,
  • Consistency: transaction sonucunda tüm veriler consistent olmalı, veriler arasında bir tutarsızlık olmamalı,
  • Isolation: transaction bir diğer transaction tarafından etkilenmemeli,
  • Durability: transaction sırasında bir hata alınması durumunda veriler bir önceki haline döndürülebilmelidir.

Saga Pattern Nedir?

Saga tasarım deseni, kendi local transaction’ları bulunan birden çok mikroservise yayılan transaction’ları yönetmek için kullanılır. Gelen istek doğrultusunda her adım bir önceki adımın başarılı olmasıyla birlikte silsile şeklinde tetiklenir. Bu süreç boyunca bir hata alınması durumunda daha önceden işlenmiş transaction’lar rollback (Compensable Transaction) edilerek geri alınmalıdır. Böylece atomicity tarafından sistemin tutarlı (consistent) olmasını sağlanır.

Saga Pattern Implementation

Saga tasarım desenini uygulamak için Choreography-Based Saga ve Orchestration-Based Saga olmak üzere iki temel yaklaşım vardır.

Choreography Implementation

Bu yaklaşımda distributed transaction‘un parçası olan tüm mikroservisler kendi local transaction’unu tamamladığında sıradaki mikroservise bir event publish ederek haberleşir. Merkezi bir koordinatöre (orchestrator) ihtiyaç duymaz. Distributed transaction’a katılacak mikroservis sayısının 2 ila 4 arasında olduğu durumlarda tercih edilmelidir.

Saga Choreography Implementation

Bu yaklaşım kullanılarak bir e-commerce uygulamasıyla sipariş oluşturulduğunu düşünelim. Buna göre Order servisi bir POST isteği sonucunda PENDING durumunda bir sipariş oluşturup ORDER_CREATED_EVENT isminde event publish (1) ediyor. Bu eventi, subscriber rolündeki Payment servisi consume ederek ödemeyi aldıktan sonra BILLED_ORDER_EVENT isminde bir event publish (2) eder. Bu eventi Stock servisi consume ederek gerekli stok düzenlemelerini yaptıktan sonra ORDER_PREPARED_EVENT isminde bir event publish (3) eder. Delivery servisi tarafından consume edilecek olan bu event işlendikten sonra ORDER_DELIVERED_EVENT isminde bir event publish (4) edilerek Order servisine iletilir. Order servisi oluşturduğu siparişin durumunu APPROVED olarak günceller.

Bu işlem basamaklarından birinde bir hata alınması durumunda sistemin consistent olması için rollback yapılmalıdır. Compensable Transaction olarak da adlandırabileceğimiz bu işlemde transaction içerisinde yapılan işlemin tam tersi yapılır. (Ör: +10 eklenmişse, -10 çıkartılır)

Saga Choreography Error Rollback

Ödeme işleminin başarıyla sonlanması durumunda BILLED_ORDER_EVENT isimli event’in publish (2) edilmesiyle Stok servisi yetersiz stok sebebiyle PRODUCT_OUT_OF_STOCK_EVENT isminde bir event publish (3) eder. Bu queue’e subscribe olan Payment servisi geri ödeme yaparak, Order servisiyse sipariş durumunu REJECTED olarak güncelleyerek işlemleri tersine uygulayarak rollback yapar.

Bu konu ile ilgili yazıya Saga Choreography Implementation linkinden ulaşabilirsiniz.

Pros/Cons

  • Merkezi bir koordinatöre (orchestrator) ihtiyaç duymadığından başlamak çok kolaydır.
  • Bir koordinatör olmadığı için tek bir hata noktası olmayacaktır.
  • Mikroservis sayısı 4’ü aştığında yönetilmesi çok güç hale gelecektir.
  • Integration test için tüm servislerin çalışıyor olması gerektiğinden zordur.

Orchestration Implementation

Bu yaklaşımda adından da anlaşılacağı üzere tüm işlemleri yöneten merkezi bir koordinatör (orchestrator) vardır. Saga Orchestrator ya da Saga State Machine her bir mikroservise hangi işlemi gerçekleştireceğini bildirir. Bir sorun olması durumunda aynı şekilde distributed transaction dahilindeki mikroservislere rollback mesajı gönderir. Her transaction state’ini State Machine aracılığıyla yönetir. Distributed transaction’a katılacak mikroservis sayısı 4’ü aştığı durumlarda tercih edilmelidir.

Saga Orchestration Implementation

Bu yaklaşım kullanılarak yine bir e-commerce uygulamasıyla sipariş oluşturulduğunu düşünelim. Buna göre Order servisi bir POST isteği sonucunda PENDING durumunda bir sipariş oluşturarak Saga Orchestrator’a CreateOrderTX komutunu göndererek transaction’u başlatır. Saga Orchestrator ödeme alınması için Payment servisine bir komut gönderir ve ödeme alındıktan sonra tekrar Orchestrator’a durum bilgisiyle (başarılı veya başarısız) döner. Saga Orchestrator sıradaki transaction’a geçerek Stock servisine komut göndererek işlem sonunda durum bilgisini tekrar alır. Delivery servisi içinde aynı süreç işletilerek transaction sonucuna göre sipariş durumu ya APPROVED ya da REJECTED olarak güncellenir.

Bu servislerden herhangi birinde hata oluşması durumunda sistemin consistent olması için rollback yapılmalıdır.

Saga Orchestrator Error Rollback

Ödeme alındıktan sonra Stock servisi içerisinde stok miktarı yetersiz gelirse Saga Orchestrator‘a başarısız durum bilgisi dönülecek ve rollback işlemlerine başlanacaktır.

Bu konu ile ilgili yazıya Saga Orchestration Implementation linkinden ulaşabilirsiniz.

Pros/Cons

  • Bağımsız mikroservislerin birbiriyle konuşması gerekmediğinden highly-scalable’dir.
  • Mikroservisler arasında dependency-cycle oluşma imkanı yoktur
  • Merkezi Orchestrator dolayısıyla tek bir hata noktası vardır.
  • Implementasyonu state yönetimi ve transaction yönetiminden dolayı zordur.

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir