SDTR
Published in

SDTR

Event Sourcing

Selamlar herkese,

Umarım iyisinizdir. Bu makalede, son zamanlarda üzerinde durduğum Event Sourcing konsepti üzerinde duracağız.

Özellikle belirtmeliyim ki, bu makalede kod içeren herhangi bir implementasyon bulunmayacak. Event Sourcing yaklaşımının özüne, içerisinde barındırdığı kavramlara değineceğiz.

CRUD

Birçok developer’ın kariyerinin başından itibaren aşina olduğu, veri ile ilgili işlemler yaparken sıkça kullanılan bir yaklaşımdır Crud yöntem. Esasında veri işlemlerini dört ana grup altında toplar, ve ismi bu grupların baş harflerinden oluşur.

Create olmayan bir veriyi oluşturma, delete bir veriyi silme, update ise var olan bir veri üzerinde değişiklik yapma işlemleridir. Read verileri okuma işlemlerine verilen genel isimlendirmedir.

Bir online eğitim platformu düşünelim. Bu platform üzerinde eğitmenler kurslar oluşturuyor, kullanıcılar da ilgilerini çeken kurslara kayıt olup sistem üzerinden eğitimleri izleyebiliyor olsunlar.

Bu platform üzerindeki kusrlara odaklanacak olursak, Eğitmenin yeni bir kurs oluşturması create işlemidir. Kurs üzerindeki bilgileri güncellemesi update, bir kursu silmesi ise delete işlemidir. Kullanıcıların kursları listelemeleri ise read işlemidir.

Peki, veriyi işleme yaklaşımı olarak, Crud yöntem tek yöntem midir? Alternatifi var mıdır? Bu soruların cevabını arayalım.

Event Sourcing

Event sourcing, bir veri saklama yaklaşımıdır ve Crud yöntemin bir alternatifi olarak karşımıza çıkar. Yeni bir yaklaşım olmamasına karşılık, günümüzde popüler olmaya başlamıştır.

Event sourcing derinliklerine dalmadan önce, Crud yöntemden farklı olarak savunduğu yaklaşımı benimsemeye çalışalım. Yukarıda vermiş olduğum online eğitim platformu üzerinden ilerleyelim.

Bu platformdaki eğitimlere kullanıcılar kayıt olabiliyor, kayıtlı kullanıcılar yorumlar yapabiliyor, eğitimi puanlayabiliyor ve eğitmenler de kurslarına videolar ekleyebiliyor olsunlar. Peki, Crud yaklaşımdan farklı olarak, veri üzerindeki işlemlere daha farklı bir yaklaşım ile yaklaşabilir miyiz?

Platform üzerinde yeni bir kurs oluşturma işlemini bir create işlemi, bir kursu silme işlemini de bir delete işlemi dışında nasıl ele alabiliriz? Eğitmenin platform üzerindeki bir kursun bilgilerini değiştirmesine update işlemi diyorsak,

Bir kullanıcının bir kursa kayıt olması bir update işlemi midir?

Peki ya bir kullanıcının bir kursa yorum yapması?

Kullanıcıların kursu puanlaması?

Eğitmenin kursa yeni bir video eklemesi de mi bir update işlemidir?

Kendinize bu soruları sorduğunuzda ve bakış açınızı değiştirmeye başladığınızda, Event Sourcing’in arkasındaki mentaliteyi de yakalamaya başlıyorsunuz demektir.

Event Sourcing, bir sistem üzerinde değişikliğe sebep olan tüm işlemleri bir “event” olarak saklamayı öneren bir yaklaşımdır.

Her bir event, sistem üzerinde etki eden bir olayı temsil eder. Böylece, sistem üzerinde gerçekleşen tüm operasyonların bir geçmiş kaydına sahip oluruz. Bu eventler sayesinde, sistemde yer alan herhangi bir kavramın, t zamanındaki durumuna erişebiliriz.

Şimdi, Event Sourcing içerisindeki kavramlara değinelim.

Event

Event, Event Sourcing yaklaşımının temelini oluşturan, sistem üzerindeki gerçekleşmiş her bir operasyonu temsil eden bir kavramdır. Gerçekleşmiş bir işlemi belirttiği için, geçmiş zaman takısıyla isimlendirmeler kullanılır.

CourseCreated

CoursePictureChanged

CourseCommented

CourseRatedByUser

Her bir event, bir aggregateId (ilerde ne olduğuna değineceğiz), Oluşma tarihi, event tipi ve sistemde değiştirdiği bilgileri içeren bir alana sahiptir.

Event Store

Sistem üzerindeki eventlerin tutulduğu veri kaynağına event store denmekte. Event store herhangi bir veri tabanı veya başka bir veri kaynağı olabilir.

Aggregate

Aggregate kavramı, esasında Domain Driven Desing prensiplerinde karşımıza çıkmış bir kavram, ancak Event Sourcing içerisinde de sık sık kullanılmaktadır.

Aggregate, bir araya getiren, toplayan anlamına gelmektedir. Yukarıdaki online eğitim platformu örneğimize geri dönelim.

Kurslar üzerine kullanıcıların kayıt olabildiğini, yorumlar yapabildiğini ve puanlamalar yapabildiğini, eğitmenlerin de videolar ekleyebildiğini belirtmiştik. Bu durumda, tüm bu işlemlerin karşılığı olan, “Comment”, “Rate”, “Section” sınıfları birer entity, “Course” sınıfı ise tüm bu entityleri kendi altında toplayan, yani Aggregate’dir.

Avantajları

Event Sourcing veri kaybı yaşamadığınız tek veri yaklaşımıdır.

Crud yaklaşımda, bir entity üzerinde güncelleme işlemi yapıldığında, veri kaynağında o entitynin yeni güncel değeri saklanacak şekilde güncelleme yapılır. Bu durumda, o entitynin bir önceki state’ini kaybettiniz.

Ayrıca, sistemi tasarlarken sizin için önemsiz olduğunu belirlediğiniz kısımları veri kaynağında saklamayacağınız için, bu önemsiz kısımlardan bazıları sizin için önemli hale geldiğinde, erişme şansınız olmayacaktır.

Event Sourcing sayesinde, elinizde sistemde yaşanmış her bir işlemin tam kaydı bulunur. Bu veriler ile istediğiniz şekilde işlemlerinizi gerçekleştirebilirsiniz.

Event Sourcing, Zahmetli Veri Modellemelerinden Kurtarır.

Crud yaklaşımda, veritabanında tabloların birbirleri ile nasıl bir ilişki içerisinde olacağı ve hangi alanları tutacağı gibi bilgileri saptamak amacıyla, tasarım yapmanız gerekmektedir. Zaman içerisinde, sistem değişikliğe uğradıkça, bu modellemeler de değişikliğe uğrar. Bu da, sürekli bir SQL script yazma, migration uygulama, veriyi sürekli yeniden tasarlama zorunluluğu doğurur.

Event Sourcing’de, büyük ihtimalle Event Store’da bir adet tablo olacaktır, O da Eventleri tutan tablodur. Böylece, veri modellemelerinden, veri odaklı düşünmeden sizi kurtarır, ve Use-Case’ler üzerine odaklanmanızı sağlar.

Dezavantajlar

Yukarıda bahsettiğim hiç bir veriyi kaybetmeme, veri modelleme üzerine olan eforu azaltma gibi avantajlarının yanında, Event Sourcing ciddi dezavantajlar barındırmakta. Bunlara değinecek olursak;

Karmaşıklık

Event Sourced sistemler, Crud sistemlere göre belli bir karmaşıklığa sahiptir. Eventlerin nasıl saklanacağı, sistem üzerinde nasıl yönetileceği üzerinde durulması gereken ciddi bir konudur.

Current State (Güncel Durum)

Event Sourcing’de entitylerinizin güncel durumunu tutan tablolarınızın olmadığını, tüm bilgiyi eventler şeklinde sakladığınızı hatırlayın. Sistem içerisinde bir entitynin güncel durumuna ulaşmak istersek ne yapacağız? Bunun için “Projection” ve “Snapshot” kavramlarına bakalım.

Projection, özünde bir grup kod parçasıdır. Bir Entity-Aggregate’in güncel durumuna ulaşabilmek için, eventlerin sırasıyla işlenmesini sağlayan kod bloklarıdır.

Event Store’da eventlerin oluşma bilgisiyle ve bir versiyon numarasıyla tutulduğundan bahsetmiştik. “1” id numarasına sahip kursun güncel bilgisine erişmeye çalışalım.

Bu işlem için, Event Store’dan AggregateId değeri 1 olan tüm eventlerin okunarak, versiyon numarasına göre projection işlemine tabi tutulması gerekmektedir. Projection aşamasında, gelen eventin tipine göre Aggregate üzerindeki bilgiler güncellenir, böylece son event project edildiğinde, Aggregate objesi güncel değerine kavuşmuş olur.

Snapshot, projection işlemini hızlandırmak amacıyla kullanılan bir yöntemdir.

Çok trafik alan bir uygulamada, günde binlerce event oluşabilir. Sistem üzerinde bir Aggregate’in güncel değerine ulaşmak istediğimizde event sayısı arttıkça, bu işlemin süresi artar. Snapshotlar, bir bir aggregate’e ait olan belli bir sayıda eventi üzerinde tutarak bir “checkpoint” görevi görür.

Bir kursa ait 100 adet eventin olduğunu düşünelim. Bu kursun güncel bilgilerine ulaşmak istediğimizde, aggregate üzerinde bu 100 eventin projection işlemine tabi tutulması gerekmektedir.

Peki , bir obje üzerinde, bu kursa ait 100 eventin 75 tanesi projection edilip saklansaydı, ve kursun güncel durumuna ulaşmak için bu objenin üzerine kalan 25 eventi projection etseydik nasıl olurdu? Event Store’dan 100 event yerine 25 event okumuş, ve daha hızlı bir şekilde güncel state’e erişmiş olurduk.

Snapshotlar, güncel state’e ulaşma konusunda bize yardımcı olurlar. Ancak, Event Sourcing üzerine çalışmış bir çok kişi, eğer ciddi bir performans sorunu yaşanmıyor ise kesinlikle snapshot kullanılmaması gerektiğini savunuyor.

Bunun sebebi, Snapshot objeleri, O Aggregate’in ilişkili olduğu tüm entityleri de barındırmak zorundadır. Böylece, bu objeler arasındaki modellemeleri ve tasarımları tekrar yapmak zorunda kalacak, Event Sourcing’in “Veri Modellemelerinden Kurtarır” avantajını büyük ölçüde kaybedeceksiniz.

Filtreleme İşlemleri

“Current State” problemindeki aynı durumdan kaynaklı olarak, Event Sourcing sistemlerde okuma ve filtreleme işlemleri çok zahmetlidir.

Eğitim platformumuzda binlerce eğitim olduğunu düşünelim. Bir kullanıcı tüm kursları listelemek istediğinde, Event Store’da yer alan tüm eventlerin çekilip projection edilmesi, ve tüm Kurslarda Current State’e erişildikten sonra kullanıcıya gösterilmesi gerekmekte. Bu oldukça masraflı bir işlem. Peki, bu sorunu nasıl çözebiliriz?

CQRS’e hoşgeldiniz.

Event Sourcing — CQRS

CQRS, Command ve Query işlemlerinin ayrılmasını savunan bir tasarım desenidir. (CQRS hakkındaki makaleme buradan erişebilirsiniz) CQRS ile Event Sourcing’in bir çok sorununu çözebilmekteyiz.

Sistemi Command ve Query Olarak 2 ayrı projeye ayırdığımızı, Command tarafında Event Sourcing uyguladığımızı varsayalım. Query tarafında ise, Crud yaklaşımı uygulayabiliriz.

Böylece, Command tarafında Event Sourcing uygulayabilirken, Query tarafında çok rahat bir şekilde okuma ve filtreleme işlemlerimizi yapabiliriz. Command tarafında yapılan her bir işlem, bir event aracılığıyla query tarafına da yansıtılmalıdır.

Bu durumda, Sistem karmaşıklığının iyice arttığını, ve sistemin “Consistent” yapıdan “Eventual Consistent” yapıya dönüştüğünü anlayabiliriz. Bu tasarımın bir diğer avantajı da, Query tarafının istenildiği şekilde birden fazla tasarlanabilmesidir.

Her Query projesi, Command tarafından gönderilen eventlere subscribe olur, ve her biri bu eventleri kendi iç yapısına göre consume eder. Böylece, istenildiği gibi Read Modeller tasarlanabilir ve modellenebilir.

Event Sourcing yaklaşımını elimden geldiğinde size aktarmaya ve bir çok kavrama değinmeye çalıştım. Genel olarak toplayacak olursak, aşağıdaki resimde Event Sourcing’in çok güzel bir özetini görebilirsiniz.

Eğer bu konuda daha detaylı bilgi edinmek istiyorsanız, Bu alanda uzman olan Greg Young, Martin Fowler ve David Schmitz gibi isimleri takip etmenizi, topluluk konuşmalarını dinlemenizi öneririm. Aşağıda bir kaç video paylaşacağım.

Tüm bunların dışında, makalenin en sonunda değindiğim Event Sourcing ve CQRS yaklaşımının beraber kullanıldığı bir örnek proje görmek isterseniz, .NET 6 ile geliştirdiğim projeye buradan göz atabilirsiniz.

Bir sonraki makalede görüşmek üzere, kendinize çok iyi bakın.

Kaynaklar:

--

--

Yetenekli ve bilgili geliştiricilerden oluşan bir topluluk!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store