Yazılım Mimarileri ve Tasarım Desenleri Üzerine

Microservice Mimarisinde Two-Phase Commit(2PC) Pattern İle Transaction Yönetimi – Nedir? Nasıl Uygulanır? Saga’dan Farkı Nedir?

Merhaba,

Bu içeriğimizde microservice yaklaşımını uyguladığımız mimarilerde veri tutarlılığını sağlamanın davranışlarından biri olan Two-Phase Commit(2PC) modelini ele alacak, nasıl ve hangi durumlarda kullanıldığını değerlendiriyor olacağız. Ayrıca neden Saga pattern’ına nazaran daha az tercih edilmesi gerektiğine dair gerekli istişarede bulunacak ve içeriğimizin en önemli bölümü olarak pratiksel olarak ilgili konuyu bir senaryo üzerinden tecrübe ediyor olacağız. O halde buyurun başlayalım…

Öncelikle microservice mimarisinde transaction yönetimi için uyguladığımız Saga pattern’ına dair önceden klavyeye aldığımız makaleleri şöyle okunma sırasına göre aşağıda listeleyelim;

Two-Phase Commit(2PC) Modeli Nedir?

Two-Phase Commit(2PC) modeli, tıpkı Saga gibi distributed sistemlerdeki transaction yönetimini sağlayabilmek ya da verisel tutarsızlığa karşın çözüm getirebilmek için kullanılan bir senkronizasyon protokolüdür. Bu protokol sayesinde dağıtık sistemde rol oynayacak olan tüm düğümlerin(node) yani servislerin, bir işlemi atomik olarak gerçekleştirmesini veyahut o işlemin komple iptal edilmesini sağlamak için kullanılan bir bütünsel algoritma görevi görmektedir.

Two-Phase Commit pattern’ında, davranışsal olarak bir rolü ifade eden, sürecin bir parçası olarak katılım gösteren ve protokolün gerektirdiği görevleri yerine getiren katılımcılara(yani servislere) node denmektedir.

Atomik olarak diyoruz çünkü Two-Phase Commit modeli ile ya işlem tamamen başarılı olacaktır ya da hiçbir şey yapılmamış gibi esasında geri alınacaktır. Böylece bu protokol sayesinde, distributed yapılanmanın gereği olarak birden fazla serviste söz konusu olan veritabanı işlemleri sanki tek bir bütünmüş gibi başarılı bir şekilde tamamlanmış olacaktır.

2PC Modelinin Temel İlkeleri

Two-Phase Commit pattern’ının temel ilkesi aşağıdaki gibi iki aşamaya dayanmaktadır.

Bu ilkeler doğrultusunda 2PC davranışını atomik olarak sağlamış olacaktır.

2PC’nin Terminolojik Aktörleri

Yukarıdaki satırlarda 2PC modelinin tasarım sürecinde ‘Koordinatör’, ‘Katılımcı’ vs. gibi terminolojik aktörlerin olduğunu görüyoruz. Ee haliyle içeriği rahatça takip edebilmek ve ortak bir dil ortaya koyabilmek için bu protokol sürecinde kullanılan aktörleri tam olarak tanımlamakta fayda vardır;

2PC Protokolü Ne Amaçla Kullanılmalıdır?

Two-Phase Commit protokolü, yukarıdaki satırlardan anlaşılacağı üzere dağıtık sistemlerdeki veritabanı işlemlerini ya kümülatif olarak başarılı kılacak ya da hiçbiri gerçekleşmeyecek şekilde yani atomik bir yaklaşımla koordine etmek için kullanılmaktadır. Haliyle buradaki en büyük gayenin, microservice’lerin aralarındaki verisel tutarlılığın bütünsel olarak sağlanması veyahut korunması olduğunu söyleyebiliriz. Ayrıca microservice mimarisinin söz konusu olduğu senaryolarda, servisler arası işlem koordinasyonunun 2PC ile merkezi bir nokta üzerinden gerçekleştirilmesi ve böylece süreç yönetiminin de kolaylaştırılması amaçlanmaktadır diyebiliriz.

Ne Zaman Saga & Ne Zaman 2PC Kullanılmalıdır?

Eğer ki, distributed transaction’ın tüm katılımcılar açısından bütünsel olarak commit edilmesi ve gerektiği taktirde de rollback edilmesi durumları söz konusuysa tabi ki de buradaki ihtiyacın güvenliğini sağlayabilmek için 2PC protokolünden istifade edilebilir. Ancak içeriğimizin devamındaki satırlarda da göreceğimiz üzere 2PC, kullanıcıdan gelen talebe karşın atomik bir tutarlılık sağlayabilmek için servislerin kümülatif hareket edebilmesi amacıyla topyekün bir kilitlenmeye mahal verecek ve bu durum da yüksek oranda performans sorunlarına sebebiyet verecektir. Bu nedenle az sayıdaki katılımcının olduğu ve bu protokolün yaratacağı kilitleme neticesindeki gecikmelerin ve bu gecikmelerin de yaratacağı ölçeklenebilirlik sınırlarının yönetilebileceği senaryolarda 2PC modelinin tercih edilmesi en doğrusu olacaktır.

Saga ise yapılacak işlemin tek bir 2PC protokolü tarafından yönetilemeyecek kadar büyük olduğu durumlarda tercih edilebilir. Saga, kullanıcı tarafından talep edilen işlem her ne ise, bu işlemi her bir microservice tarafından bağımsız olarak yönetilebilecek ve işlenebilecek küçük local işlemlere bölecektir. Böylece her bir service ihtiyaç doğrultusunda daha rahat ölçeklendirilebilecek ve herhangi bir gecikme vs. olmaksızın, yüksek hata toleransı eşliğinde gayet performanslı bir süreç sonucu beklenen netice elde edilebilecektir. Ayrıca özellikle 2PC protokolü ile işlemin geri alınma durumunun oldukça maliyetli olabileceği karmaşık senaryolarda, Saga pattern’ı ile daha basit ama etkili çözümler getirilebilecektir.

2PC’nin Pratiksel Örneklendirilmesi

Şimdi 2PC protokolünü pratiksel olarak baştan sona bir örnek senaryo üzerinden tecrübe edelim istiyorum. Bunun için bir e-ticaret sisteminin klasik ‘Order.API’, ‘Stock.API’ ve ‘Payment.API’ servislerinden oluşan sipariş sürecini senaryo olarak değerlendiriyor olacağız. O halde vakit kaybetmeksizin adım adım örneğin geliştirilmesine başlayalım;

İşte bu kadar 🙂 Görüldüğü üzere 2PC protokolü bu şekilde, bu mantıkta uygulanmaktadır 🙂 Şimdi gelin bu tecrübe ettiğimiz protokolün avantajlarını ve dezavantajlarını değerlendirerek içeriğimize devam edelim.

2PC Protokolünün Avantaj ve Dezavantajları

2PC protokolü, görüldüğü üzere oldukça güçlü data consistency modeli sağlayan bir pattern’dır. İşlenecek distributed transaction’ın atomik olmasının garantisini sağlamakta ve tüm microservisler açısından kümülatif olarak ya başarıyla sonuç alınmasını ya da topyekün rollback ile işlemlerin geri alınmasını sağlamaktadır. Lakin bunu yaparken tüm servisler üzerinde bir senkronizasyon sağlayacağından dolayı sistemi kilitleme/engelleme durumu söz konusu olacaktır. İşte bu durumdan dolayı microservices mimarilerde data consistency süreçlerinde pek önerilen yaklaşım değildir diyebiliriz.

Ayrıca fark ettiyseniz 2PC protokolünde büyük ölçüde koordinatör tarafından gönderilen mesajlara bağımlılık söz konusudur. Yani net kriz yaratabilecek tek bir hata noktası mevcuttur ki bu noktada bir problem ya da sorun yaşanırsa sistemin kontrolden çıkması içten bile değildir.

2PC Protokolünün Tercih Edilebileceği Senaryolar

2PC protokolü aşağıdaki senaryolara uygun davranış sergileyebilir;

Nihai olarak;
Two-Phase Commit(2PC) pattern’ı nispeten basit bir prensibe sahip olsa da, performans ve maliyet açısından pek avantajlı diyemeyeceğimiz bir protokoldür. Transaction süreci boyunca sistemin kitlenmesi ve tüm işlemlerin bağlı olduğu koordinatörün olası hataları durumunda tüm sistemin krize girmesi 2PC protokolünün optimizasyonunu da zorlaştırdığı görülmektedir. Bizler bu içeriğimizde mevzu bahis pattern’ı tam teferruatlı bir şekilde artıları ve eksileri eşliğinde değerlendirmiş ve yazıya aktarmış bulunmaktayız. Artık ihtiyaçlar doğrultusunda tercih edip etmemek, sizlerin kritiğine, gereksinimlerine ve tercihlerine kalmıştır 🙂

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmaya aşağıdaki github adresinden erişebilirsiniz.
https://github.com/gncyyldz/Two.Phase.Commit.Example

Mobil sürümden çık