Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

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?

Event Sourcing Nedir? Haydi Gelin Hep Beraber İnceleyelimŞ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…

Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelimYine 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..
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim

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;

  • Olay akışları yalnızca ileriye doğru olmalıdır. Yanlış yazılan yahut geri dönülmesi gereken durumlarda ‘Update/Düzenleme’ tarzı olaylardan çok değişikliği ifade edecek olan ‘İptal’ -> ‘Yeniden Oluşturmak’ gibi olaylar tasarlanmalıdır.
  • Herhangi bir olayla ilgili tüm veriler, bu veriler için mevcut bir iş ihtiyacı olup olmadığına bakılmaksızın saklanmalıdır. İdeal olarak hiçbir veri atılmamalıdır.

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?

  • MeetingRegistered
  • MeetingDateChanged
  • MeetingDateChanged
  • MeetingCancelled
  • MeetingRegistered
  • MeetingCompleted
  • MeetingAddedComment

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
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim
T1
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim
Kullanıcı ad ve soyadını güncelledi
T2
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim
T2
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim
Kullanıcı e-posta hesabını onayladı
T3
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim
T3
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelim

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.
Event Sourcing Nedir Haydi Gelin Hep Beraber İnceleyelimYandaki ş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.

  • İzlenebilirliği ve tarihsel bazda yeniden üretimi kolaylaştırır
    İzlenebilirlik, kayıtlı event’leri analiz ederek mevcut sistem durumunun nasıl bu hale geldiğini adım adım anlayabileceğimiz anlamına gelir. Bu özellik büyük ve karmaşık uygulamalarda gayet kullanışlılık sergilemektedir.
  • Hataların onarımını kolaylaştırır
    Yukarıda bahsettiğimiz izlenebilirlik özelliği sayesinde geçmişteki herhangi bir T anına dönebilme yahut o andaki veriyi oluşturabilme imkanına sahip olduğumuz için, bir hata bulunduğu taktirde iş verilerimizi doğrudan bir araya yeniden getirebilir ve onarım tamamlandıktan sonra verilerimizi tazeleyebiliriz. Geleneksel yaklaşımda ise bu tarz hata durumlarının onarılması oldukça maliyetli ve zahmetli olmaktadır.
  • Güçlü performans sağlanabilir
    Aggregate nesnesi içerisindeki tüm event’ler derlenerek elde edilen veri herhangi bir depolama ihtiyacı hissedilmeksizin hafızada/bellekte oluşturulabilir/tutulabilir.
  • Veri analizi ve diğer sistemleri kullanmak kolaydır
    Event Sourcing’de veriler esas itibariyle bir event olduklarından dolayı bu veriler üzerinde analizler yapmak oldukça kolay olacaktır.

Event Sourcing’in Dezavantajları Nelerdir?

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

  • Geliştirme ve geliştirici düşüncesini değiştirmek
    Sanırım dezavantajlar arasındaki en bariz olanı bu olsa gerek 🙂 En nihayetinde Event Sourcing pattern’ı bir geliştirici tarafından uygulanmalıdır ve geleneksel mimarilere yatkın olanların hızlı bir şekilde kavrayabileceği anatomiye sahip bir pattern değildir! Bu durumda, sindirebilirlik açısından bir nebze zorluk çıkarabilmektedir.
  • Olgun ve genel kabul görmüş bir yol/yordam/tasarım olmaması
    Event Sourcing’i uygulayabilmek için belli başlı teknolojiler eşliğinde tasarımlar sunulmaktadır. Amma velakin her ne olursa olsun genel kabul görmüş bir mimarisel tasarımdan hala söz edememekteyiz ve bunun yanında birçok noktada kendi kişisel kararlarınızla anlık yaratıcı çözümler uygulamanız gerekebilmektedir.
  • Performans tüketimi
    Eee hoca! yukarıda avantajlarından bahsederken ‘Güçlü performans sağlayabilir’ dediğin halde nasıl oluyor da ‘Performans tüketimi’ dezavantaj olabiliyor? diye söylenmeyin 🙂 Elbet performansa dair getirileri olan bu tasarımın belli durumlara istinaden götürüleride olabilir. Misal olarak, veri okuma durumlarında geleneksel yönteme nazaran Event Sourcing performans kıyaslamalarında daha yavaş sonuç verebilir. Çünkü, Event Sourcing yapısal olarak talep edilen veriyi, veriyle ilgili event’lerin dökümü olarak elde eder ve bu dökümden veriyi oluşturmaya çalışır. Ee haliyle bu durumda verinin oluşturma sürecinin, verinin hazır olarak tutulduğu geleneksel yönteme kıyasla daha yavaş sonuç vereceği aşikardı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/

Bunlar da hoşunuza gidebilir...

10 Cevaplar

  1. Hasan URAL dedi ki:

    Sonunda.
    Olayı ıcığı ile cıcığı ile inceleyerek ele alan birisi.
    Cidden çok teşekkür ederim. Ellerinize emeğinize sağlık.
    Temelden anlatmaya başladığınız bu seriye. Konu ile yazılmış çok fazla kaynak olmasına rağmen bir çoğu temeli dikkate almadan sadece tasarımla ilgileniyor. Biz bazı şeylerin neden böyle olduğunu anlayana kadar kurduğumuz yapıların bir kaç kez göçmesine veyahut değiştirmeye gerek duyuyoruz. Özellikle satranç örneğiniz bence çok başarılı olmuş konunun anlaşılması için.
    Merakla serinin diğer yazılarını beklemekteyim.

  2. Caner Yıldız dedi ki:

    Anlatım her zaman olduğu gibi çok başarılı , Teşekkürler Gençay Bey

  3. Alphan dedi ki:

    Süper örnek, elinize sağlık

  4. Uğur dedi ki:

    Hocam merhaba,
    Makaleyi okurken aklıma MSSQL veritabanındaki History(System Versioned) table lar geldi.
    normal mi ? 🙂 Orada event diye bir kayıt yok ancak history table dan eventi veriye bakarak anlayabiliyoruz.

  5. Uğur dedi ki:

    MSSQL veritabanındaki History(System Versioned) table lar event sourcing patternine uygun bir yaklaşım olarak düşünülebilir mi?

  6. kamil yasin ablay dedi ki:

    Teşekkürler

  7. Enes dedi ki:

    Satranç örneği çok başarılı olmuş

  1. 27 Nisan 2021

    […] içeriğimizde bir önceki kaleme aldığımız Event Sourcing Nedir? Haydi Gelin Hep Beraber İnceleyelim başlıklı makalemize basit bir somut örnek teşkil edecek şekilde çalışma […]

  2. 09 Mayıs 2021

    […] önceki Basit Bir Event Sourcing Uygulaması Geliştirelim başlıklı makalemizde Event Sourcing pattern’ının nasıl gerçekleştirilebildiğine pratiksel olarak bir örnek vermeye […]

Bir yanıt yazın

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