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

Event Sourcing Nedir? Haydi Gelin Hep Beraber İnceleyelim

Merhaba,

Bu içeriğimizde, bir veri üzerinde meydana gelen tüm değişiklikleri kayıt altında tutmamızı öneren ve böylece ilgili verinin sadece güncel ham vaziyettinden ibaret tutulmasından ziyade o verinin süreçte yaşadığı değişikliklerinde esasında ilgili verinin bir parçası olduğunu savunan ve bundan kaynaklı kayıt altına alınmasını söyleyen Event Sourcing pattern’ından bahsediyor olacağım.

Konuya dair içeriğimiz esas olarak tahminen dört parça makaleden oluşacaktır. Bu ilk makalemizde Event Sourcing üzerine detaylı teorik bir incelemede bulunacak; ikinci, üçüncü ve dördüncü makalelerde ise Event Sourcing’e dair farklı türlerde pratiksel çözümler getirmeye çalışacağız.

O halde ennn temelden mevzuya girelim ve Event Sourcing Nedir? sorusunu sorarak içeriğimizin seyrine başlayalım…

Event Sourcing Nedir?

Şimdi biraz bilenlere hitap ediyor olsakta benim çok sevdiğim bir oyundan bahsederek başlamak istiyorum. Satranç! Satranç çok güzel oyun değil mi? Görme ve mantık duyularının bir araya gelip ortaya analitik bir sonuç çıkardığı nadir sanatsal oyunlardan biri…

Eğer satrancı biliyorsanız, elbet bir iki turnuvasını izlemiş yahut internetten bi kaç el oyun atmışlığınız vardır kanaatindeyim. Anımsarsanız eğer her iki durumda da satrançta tarafların yaptıkları hamleler kayıt altına alınmakta ve oyun nihayete vardığında bu kayıtlar sayesinde nasıl bir seyrin yapılabildiği rahatlıkla görülebilmektedir. Hatta bu hamlelerin kayıt altına alınması sayesinde oyunun herhangi bir T anına geri dönebilmekte mümkündür. Öyle değil mi?

İşte satranç’ta ki bu hamleleri kaydetme durumu yazılımsal açıdan bir Event Sourcing‘dir diyebiliriz. Olayı yazılımsal perspektiften yorumladığımızda her bir hamle bir Event’tir. Yani olaydır.

Peki event nedir?
Event, istek neticesinde olayın/işin/işlemin gerçekleşmesi durumudur. Örneğin; bir kullanıcının sistem üzerinde hesap açması yazılımsal açıdan “KullaniciOlusturuldu” şeklinde event olarak tanımlanabililir.

Event’ler; olmuş, bitmiş olayları tarif ederler. Bundan dolayı isimlendirmelerde geçmiş zaman eki olmalıdır!

ÖRNEĞİN;
WhitePawnMove | WhitePawnMoved✓
BlackPawnMove | BlackPawnMoved✓
BlackPawnTake | BlackPawnTaken✓
KapiAciliyor | KapiAcildi✓
vs…

Yine satranç örneğinden devam edersek eğer her bir hamle bir olaydır. Çünkü yapılmış, olmuş, bitmiştir ve artık kayıt altına alınmıştır. Yukarıdaki görsele göz atarsanız eğer oyun başlamıştır. Bunu sağdaki tahtadan görebilmekteyiz. Hemen yan tarafa bu tahtanın T anındaki bir görselini alalım ve olay seyrini aşağıdaki gibi modelleyelim.

AGGREGATE/MAÇ
Hamle Numarası Hamle Event
PROJECTION 1 Beyaz Piyon Bir Adım Öne WhitePawnMoved
2 Siyah Piyon Bir Adım Öne BlackPawnMoved
3 Beyaz Piyon Bir Adım Öne WhitePawnMoved
4 Siyah Piyon Bir Adım Öne BlackPawnMoved
5 Beyaz Piyon Siyah Piyonu Yer BlackPawnTaken

Dikkat ederseniz bu satranç oyununun tamamı bu hamlelerin bütününden meydana gelmektedir. Yani yapılan değişiklikler/olaylar/hamleler tekil olarak oyunu yansıtmamakta, bir bütün olarak o oyunu temsil etmektedirler. İşte bu yazılımsal süreçlerde bir veri içinde geçerlidir.

Yazılımsal süreçlerde, bir veri üzerinde yapılan değişiklerin tümü o veriyi temsil etmektedir. Yani veri, salt olarak son değişikliğin yapıldığı hali olarak değil daha fazlasını ifade etmektedir. Bu durumu içeriğimizin ileriki satırlarında daha da net bir şekilde izah ediyor olacağım…

Ayrıca dikkat ederseniz her bir meydana gelen hamle sıra numarasıyla işaretlenmektedir. Bu durumda da istenilen hamleye hızlıca geri dönüş yapılabilir ve oyuna oradan devam edilebilir. Bunu, yazılımsal açıdan bir veri içinde gerçekleştirebiliriz. İlgili verinin süreçte yaşadığı değişiklikleri kayıt altında tutarsak eğer herhangi bir T zamanındaki halini hızlıca öğrenebilir yahut geri dönebiliriz. Hıı tabi bunu önceki satırlarda söylemiştim 🙂 Olsun ziyanı yok! Lakin burada eklemem gereken bir husus var. O da şu ki, diyelim ki satrançta deneyimsiz bir oyuncunun hamlesini cömertçe geri almasına müsaade ediyorsunuz. Evet, satrançta bu durum mümkündür ve hamle geri alınabilir. Ama yazılımsal açıdan bir verinin üzerinde yapılan değişikliği herhangi bir T zamandaki haline geri döndürmek istiyorsanız bu durumda yeni bir olaydır. Yani buradan -bir olay akışından hiçbir olay silinemez!- kanısını çıkarabiliriz. Bu nedenle bu tarz bir durumu yazılımsal açıdan ‘ReversePreviousMoved’ gibi isimde bir event’le karşılayabiliriz..

Ve son olarak bir satranç oyununa dair olan olayları başka satrançtan ayırmak için buna ‘Maç’ diyoruz. Değil mi? Yazılımsal açıdan bir veriye dair olabilecek tüm olayları, diğer verilerin olaylarına karşı ayırabilmek için bunları Aggregate olarak nitelendiriyoruz. Her bir event’e de Projection diyoruz.

Aggregate, bir veriye ait olan ve birbiriyle ilişkisel olayların meydana geldiği bütündür. Projection ise bir verinin durumunu belirlemek için gerçekleştirilen olaylardır.

Tüm bunlardan yola çıkarak, yazılım süreçlerinde veriler üzerindeki yapılan işlemlerin/olayların kayıtlarında kabul edeceğimiz ön prensipler şunlardır diyebiliriz;

Yazılım Süreçlerinde Event Sourcing Nasıl Çalışır?

Yazılım süreçlerinde Event Sourcing’i anlayabilmek için geleneksel yazılım geliştirme yöntemini incelememiz gerekmektedir. Geleneksel yazılım geliştirme yönteminde, bir veri üretilir ve sonrasında herhangi bir saklama ortamında depolanır. Süreçte bu veri üzerinde yapılacak herhangi bir değişiklik(CRUD) doğrudan ilgili verinin bulunduğu saklama ortamındaki kopyası üzerinde gerçekleştirilir. Yani her bir değişiklik ilgili verinin fiziksel olarak değişikliğe uğramasına sebebiyet verecektir ve nihai olarak veri yapılan en son değişikliğin etkisiyle depolanmaya devam edecektir.

Peki sizce bir veri bundan ibaret midir? Yani her şey bir CRUD neticesinde oldu bitti midir? Değil dir! Dimi…
Buna şöyle bir örnek verebiliriz. Misal bir iş toplantısı planladığımızı düşünürsek…

Event CRUD
İş toplantısı x tarihine planlandı Bu bir insert‘dir
İş toplantısı y tarihine değiştirildi Bu bir update‘dir
İş toplantısı z tarihine değiştirildi Bu da bir update‘dir
İş toplantısı iptal edildi Ve bu da bir update‘dir
İş toplantısı w tarihine planlandı Ve bu da bir insert‘dir
İş toplantısı tamamlandı Veeee bu da bir update‘dir
İş toplantısına katılanların yorumları alındı Veeee bu da bir insert‘dir

Yani dikkat ederseniz bir veri için her şeyin CRUD’dan ibaret olmadığını anlıyoruz! Veri CRUD’dan daha fazlasıdır. Yukarıdaki iş toplantısına dair olan veri bu eventlerin bütünüyle bir anlam kazanmakta değil midir? ve esasında bu veri aşağıdaki event’lerden ibarettir diyebilir miyiz?

Haliyle verilerin anlamı birden fazla event toplamıysa klasik yaklaşımlardaki gibi saklama ortamlarında veriyi tutmaktan ziyade bu event’leri tutmak daha mantıklıdır.

Event Sourcing pattern’ı, verilerin son durumlarını tutmaktan ziyade, verilerin son durumlarını etkileyen olaylar zincirinin kaydedilmesini ve gerektiği taktirde istemci tarafından sorgu gönderilip verinin son durumuna dair sistemdeki var olan tüm event’ların bilgilerini birleştirilerek istemciye sunulmasını önerir.

Geleneksel Yaklaşım vs Event Sourcing Örneklendirmesi

Şimdi geleneksel yaklaşım ile Event Sourcing arasındaki farkı ortaya net koyabilmek için teorik bir örneklendirme üzerinden seyredelim.

Not : Bu senaryo https://ademcatamak.medium.com/event-sourcing-6683f3f28b5d adresindeki makaleden alıntılanmıştır.

SENARYO
Geliştirilen bir uygulamada kullanıcıya dair ‘Ad’, ‘Soyad’, ‘Şifre’, ‘EPosta’, ‘EPostaOnaylandı’ vs. gibi bilgilerin tutulduğunu düşünelim.
Ve bu uygulama üzerinde sırasıyla aşağıdaki olayların cereyan ettiğini varsayalım;
  • Kullanıcı e-posta ve şifre bilgisi ile hesap açtı
  • Kullanıcı ad ve soyadını güncelledi
  • Kullanıcı e-posta hesabını onayladı
Geleneksel Yaklaşım Event Sourcing
Geleneksel yaklaşım ile kullanıcı verileri depolandığında aşağıdaki gibi bir çalışma sergilenecektir. Event Sourcing ile kullanıcı verileri depolandığında aşağıdaki gibi bir çalışma sergilenecektir.
Kullanıcı e-posta ve şifre bilgisi ile hesap açtı
T1
T1
Kullanıcı ad ve soyadını güncelledi
T2
T2
Kullanıcı e-posta hesabını onayladı
T3
T3

Görüldüğü üzere… Önceki satırlarda da değindiğimiz gibi artık Event Sourcing ile verilerimizin herhangi bir T zamanındaki durumunu tekrar elde etmek mümkün bir haldedir diyebiliriz.

Event Sourcing & CQRS – Veri Sorgulaması Nasıl Yapılır?

Haliyle artık şu kanıya vardık ki, istemciden gelen ‘Command’ istekleri neticesinde verileri yukarıdaki gibi event olarak kaydedeceğiz. Fakat bu event’ler belirli şartlara göre sorgulanabilir yapılar olmadığından dolayı istemciden gelen ‘Query’ isteklerine karşılık farklı bir veritabanından sonuç dönmemiz gerekecektir. İşte böyle bir durumda CQRS pattern‘ı Event Sourcing ile uygulayarak muhteşem ikiliyi sahneye sürebiliriz.
Yandaki şemayı incelerseniz eğer ‘Query’ ve ‘Command’ isteklerini farklı veritabanların da karşılayacak ve işlem gerçekleştireceğiz. Eğer ki bir event oluşturulacaksa bunu ‘Command Bölgesi’nde olduğu gibi Event Sourcing olarak depolayacağız. Bunun için MSSQL gibi farklı veritabanları yahut farklı tasarımlar kullanabiliriz. Amma velakin özellikle sonraki yazılarımda değineceğim ‘Event Store’ adında bir teknolojiyi kullanarak, uygulamadaki event’leri rahatlıkla depolayabilecek ve yönetebileceğiz. Velhasıl, event olarak depolanan bu veriler aynı zamanda bir kuyruk sistemiyle(misal RabbitMQ) ‘Query’lerin depolandığı veritabanına(Query Store) yansıtılırlar. Yansıtılırlar çünkü gelen ‘Command’ler ile ‘Query’ler arasındaki tutarsızlığı ancak bu şekilde ortadan kaldırabiliriz. İşte bu işlem ‘Projection Bölgesi’nde geçerlidir. ‘Query Bölgesi’nde ise gerekli sorgulamalar gerçekleştirilerek sonuç istemciye döndürülecektir.

Bir veri, veri satırı olarak değil de, bu satırı oluşturacak event’lerin toplamı olarak ifade edilirse bize Eventual Consistency(Nihai Tutarlılık) bir yapı sunabilir.

Event Sourcing’in Avantajları Nelerdir?

Event Sourcing’in geleneksel yaklaşıma nazaran aşağıda sıraladığımız üzere bir takım avantajları vardır.

Event Sourcing’in Dezavantajları Nelerdir?

Elbet her yapılanmada olduğu gibi Event Sourcing’de de aşağıdaki gibi dezavantajlar vardır.

Evet… Böylece Event Sourcing’e dair teorik olarak sağlam temeller attık kanaatindeyim. İçeriğimizin ilk paragraflarında bahsedildiği üzere artık pratik çalışmaları sonraki devam niteliğindeki yazılarımıza ayıralım kanaatindeyim. Hem bu süre zarfında sizler bu içeriği okuyup sindirirken, bende diğer içerikleri klavyeye alıyor olacağım 🙂

O halde sonraki yazılarımda görüşmek üzere diyelim…
İlgilenenlerin bol bol faydalanması dileğiyle..
İyi çalışmalar…

Kaynaklar

https://ademcatamak.medium.com/event-sourcing-6683f3f28b5d
https://www.codeproject.com/Articles/872089/Event-Sourcing-Overview
www.ahmetkucukoglu.com/event-sourcing-nedir/

Mobil sürümden çık