7 dk

Kafka etkinlik akışı: ne zaman bir kuyruk yeterli, ne zaman bir log kazandırır

Kafka etkinlik akışı, olayları sıralı bir kayıt olarak ele alarak sistem tasarımını değiştirdi. Basit bir kuyruk ne zaman yeterli, log ne zaman avantaj sağlar öğrenin.

Kafka etkinlik akışı: ne zaman bir kuyruk yeterli, ne zaman bir log kazandırır

Neden ekipler geleneksel entegrasyonlarda tıkanır

Çoğu ürün basit nokta-ile-nokta entegrasyonlarla başlar: Sistem A, Sistem B'yi çağırır veya küçük bir betik verileri bir yerden başka bir yere kopyalar. Ürün büyüyene, ekipler ayrılana ve bağlantı sayısı çoğalana dek bu çözüm işe yarar. Yakında her değişiklik birkaç servisi koordine etmeyi gerektirir; çünkü küçük bir alan veya durum güncellemesi bağımlılık zincirinde dalgalanma yaratabilir.

Hız genellikle ilk bozulan şeydir. Yeni bir özellik eklemek birden fazla entegrasyonu güncellemeyi, birkaç servisi yeniden dağıtmayı ve eskiden buna bağlı başka bir şeyin olmadığını ummayı gerektirir.

Sonra hata ayıklama acı verir. UI'da bir şey yanlış göründüğünde temel soruları cevaplamak zorlaşır: ne oldu, hangi sırayla oldu ve gördüğünüz değeri hangi sistem yazdı?

Eksik parça genellikle bir denetim izi (audit trail)dir. Veri bir veritabanından diğerine doğrudan itiliyorsa (veya yol boyunca dönüştürülüyorsa), geçmişi kaybedersiniz. Nihai durumu görebilirsiniz ama oraya hangi olaylar zinciriyle gelindiğini göremezsiniz. Olay incelemeleri ve müşteri desteği, geçmişi yeniden oynatamadığınız için zarar görür.

Bu aynı zamanda “gerçeğin sahibi kim” tartışmasının başladığı yerdir. Bir ekip der ki: “Faturalama servisi gerçek kaynaktır.” Başkası der: “Sipariş servisi.” Gerçekte her sistem kısmi bir görüşe sahiptir ve nokta-ile-nokta entegrasyonlar bu anlaşmazlığı günlük sürtüşmeye dönüştürür.

Basit bir örnek: bir sipariş oluşturulur, sonra ödenir, sonra iade edilir. Üç sistem birbirini doğrudan güncelliyorsa, yeniden denemeler, zaman aşımı veya manuel düzeltmeler olduğunda her biri farklı bir hikâyeye sahip olabilir.

Bu da Kafka etkinlik akışının arkasındaki temel tasarım sorusuna götürür: sadece işi bir yerden başka bir yere mi taşımanız gerekiyor (kuyruk), yoksa birçok sistemin okuyup geri sarıp güvenebileceği paylaşılan, kalıcı bir olay kaydına mı (log) ihtiyacınız var? Cevap nasıl inşa edeceğinizi, hata ayıklayacağınızı ve sistemi nasıl evrilterek büyüteceğinizi değiştirir.

Jay Kreps, Kafka ve log fikri

Jay Kreps, Kafka'yı şekillendirmede ve daha da önemlisi birçok ekibin veri hareketini düşünme şeklini değiştirmede etkili oldu. Faydalı kayma zihniyettedir: mesajları tek seferlik teslimatlar olarak ele almayı bırakın ve sistem aktivitelerini bir kayıt olarak görmeye başlayın.

Temel fikir basittir. Önemli değişiklikleri değiştirilemez gerçekler akışı olarak modelleyin:

  • Bir sipariş oluşturuldu.
  • Bir ödeme yetkilendirildi.
  • Bir kullanıcı e-postasını değiştirdi.

Her olay, sonradan düzenlenmemesi gereken bir gerçektir. Daha sonra bir şey değişirse, yeni gerçeği belirten yeni bir olay eklersiniz. Zamanla bu gerçekler bir log oluşturur: eklenebilir, sadece-okunur sistem geçmişi.

İşte Kafka etkinlik akışı birçok temel mesajlaşma düzeninden farklıdır. Birçok kuyruk “gönder, işle, sil” üzerine kuruludur. Bu, iş sadece bir teslimat ise yeterlidir. Log görüşü ise "geçmişi sakla ki birçok tüketici bunu şimdi ve ileride kullanabilsin" der.

Geçmişi yeniden oynatmak pratik bir süper güçtür.

Bir rapor yanlışsa, aynı olay geçmişini düzeltilmiş bir analiz işinden geçirebilir ve sayılar nerede değiştiğini görebilirsiniz. Bir hata yanlış e-postalara neden olduysa, olayları bir test ortamına yeniden oynatıp tam zaman çizelgesini yeniden üretebilirsiniz. Yeni bir özellik geçmiş veriye ihtiyaç duyarsa, başlangıçtan itibaren okuyacak ve kendi hızında yakalanacak yeni bir tüketici oluşturabilirsiniz.

Somut bir örnek: fraud kontrollerini, aylarca ödeme işledikten sonra eklediğinizi hayal edin. Ödeme ve hesap olaylarının bir logu varsa, geçmişi yeniden oynatıp gerçek sıralar üzerinde kuralları eğitebilir veya kalibre edebilir, eski işlemler için risk puanları hesaplayabilir ve veritabanını yeniden yazmadan “fraud_review_requested” olaylarını doldurabilirsiniz.

Bu yaklaşımın sizi ne yapmaya zorladığına dikkat edin. Log tabanlı bir yaklaşım olayları açıkça adlandırmanızı, onları sabit tutmanızı ve birçok ekip ile servisin bunlara bağımlı olacağını kabul etmenizi sağlar. Ayrıca faydalı soruları zorunlu kılar: Gerçek kaynağı nedir? Bu olay uzun vadede ne anlama geliyor? Hata yaptığımızda ne yapacağız?

Değer kişilikte değil. Paylaşılan bir logun sisteminizin hafızası haline gelebileceğini fark etmektir ve hafıza, sistemlerin yeni bir tüketici eklediğinizde kırılmadan büyümesini sağlar.

Kuyruk vs log: en basit zihinsel model

Bir mesaj kuyruğu yazılımınız için yapılacaklar hattı gibidir. Üreticiler işe bir şey koyar, tüketiciler bir sonraki öğeyi alır, işi yapar ve öğe kaybolur. Sistem esas olarak her görevin mümkün olan en kısa sürede bir kez ele alınması hakkındadır.

Bir log farklıdır. Olanların sıralı kaydıdır ve kalıcı bir dizide tutulur. Tüketiciler olayları “alıp” ortadan kaldırmaz. Kendi hızlarında logu okurlar ve daha sonra tekrar okuyabilirler. Kafka etkinlik akışında bu log temel fikirdir.

Farkı hatırlamanın pratik bir yolu:

  • Kuyruk = yapılacak iş. Bir işçi onayladığında kaybolur.
  • Log = ne olduğunu gösteren tarihçe. Olaylar bir tutulma süresi boyunca kalır.

Tutulma (retention) tasarımı değiştirir. Bir kuyrukla, daha sonra eski mesajlara ihtiyaç duyan yeni bir özellik (analizler, fraud kontrolleri, hatadan sonra yeniden oynatma) eklerseniz, genellikle ayrı bir veritabanı eklemek veya ekstra kopyalar yakalamak zorunda kalırsınız. Bir log ile yeniden oynatma normaldir: bir türetilmiş görünümü baştan (veya bilinen bir kontrol noktasından) okuyarak yeniden oluşturabilirsiniz.

Fan-out (çoklu okuyucu besleme) başka büyük bir farktır. Bir checkout servisi “OrderPlaced” yayınlasa, kuyruğunda genellikle bir işçi grubunu seçersiniz veya işi çoklu kuyruklara kopyalarsınız. Bir log ile faturalama, e-posta, stok, arama indeksleme ve analiz aynı olay akışını bağımsız olarak okuyabilir. Her ekip kendi hızında ilerleyebilir ve yeni bir tüketici eklemek üreticiyi değiştirmeyi gerektirmez.

Zihinsel model basittir: işi taşımak için bir kuyruk kullanın; şirketin birçok bölümü şimdi veya ileride okumak isteyebilecek olayları kaydetmek için bir log kullanın.

Olay akışı sistem tasarımında neyi değiştirir

Olay akışı varsayılan soruyu tersine çevirir. “Bu mesajı kime göndermeliyim?” diye sormak yerine “Ne oldu?” kaydını tutmaya başlarsınız. Bu küçük bir değişiklik gibi görünse de sisteminizi modelleme şeklini değiştirir.

OrderPlaced veya PaymentFailed gibi gerçekleri yayınlarsınız; sistemin diğer parçaları ne zaman, nasıl tepki vereceklerine karar verir.

Kafka etkinlik akışıyla üreticiler doğrudan entegrasyon listesini tutmak zorunda kalmaz. Checkout servisi bir olay yayınlayabilir ve bunun analytics, e-posta, fraud kontrolleri veya gelecekteki öneri servisi tarafından kullanılıp kullanılmayacağını bilmesine gerek yoktur. Yeni tüketiciler daha sonra ortaya çıkabilir, eskileri duraklatılabilir ve üretici aynı şekilde davranmaya devam eder.

Bu aynı zamanda hatalardan kurtulma biçiminizi değiştirir. Sadece mesajlaşmaya dayalı bir dünyada, bir tüketici bir şeyi kaçırdığında veya hatalı çalıştığında veriler sıklıkla “gitmiş” olur; özel yedekler oluşturmadıysanız geri getirilemez. Bir log ile kodu düzeltebilir ve geçmişi yeniden oynatarak doğru durumu yeniden oluşturabilirsiniz. Bu genellikle el ile veritabanı düzenlemelerinden veya güvenilmeyen tek seferlik betiklerden daha iyidir.

Pratikte bu değişim birkaç güvenilir şekilde ortaya çıkar: olayları kalıcı kayıt olarak kabul edersiniz, üreticileri değiştirmek yerine abone olarak özellik eklersiniz, okuma modellerini (arama indeksleri, panolar) sıfırdan yeniden inşa edebilirsiniz ve hizmetler arası ne olduğunu gösteren daha net zaman çizelgeleri elde edersiniz.

Gözlemlenebilirlik gelişir çünkü olay logu ortak bir referans olur. Bir şey ters gittiğinde iş sırasını takip edebilirsiniz: sipariş oluşturuldu, stok ayrıldı, ödeme yeniden denendi, sevkiyat planlandı. Bu zaman çizelgesi genellikle dağıtık uygulama loglarından daha anlaşılırdır çünkü iş gerçeklerine odaklanır.

Somut örnek: iki saat boyunca bir indirim hatası siparişleri yanlış fiyatlandırdıysa, düzeltmeyi hızla dağıtıp etkilenen olayları yeniden oynatabilir, toplamları yeniden hesaplayabilir, faturaları güncelleyebilir ve analizleri yenileyebilirsiniz. Sonuçları yeniden türetmekle düzeltiyorsunuz, hangi tabloları elle yamalamaya çalışacağınızı tahmin etmekle değil.

Ne zaman basit bir kuyruk yeterlidir

Move From Queue to Log
Start with one thin slice and evolve from queue style jobs to event streams.

Basit bir kuyruk işinizi taşımak içindir, uzun vadeli kayıt oluşturmak için değil. Amaç bir görevi bir işçiye teslim etmek, çalıştırmak ve sonra unutmaktır. Kimse geçmişi yeniden oynatmaya, eski olayları incelemeye veya ileride yeni tüketiciler eklemeye ihtiyaç duymuyorsa, kuyruk işleri basit tutar.

Kuyruklar arka plan işleri için mükemmeldir: kayıt olma e-postalarını göndermek, yüklemeden sonra resimleri yeniden boyutlandırmak, gece raporu oluşturmak veya yavaş bir dış API'yi çağırmak. Bu durumlarda mesaj sadece bir iş bileti gibidir. İşçi işi bitirince bilet de amacına ulaşmıştır.

Kuyruk ayrıca tipik sahiplik modeline uyar: bir tüketici grubu işin uçtan uca sorumluluğunu taşır ve diğer servislerin aynı mesajı bağımsız olarak okuması beklenmez.

Aşağıdaki koşulların çoğu doğruysa bir kuyruk genellikle yeterlidir:

  • Verinin kısa ömürlü değeri var.
  • Bir ekip veya servis işi baştan sona sahipleniyor.
  • Yeniden oynatma ve uzun tutma gerekleri yok.
  • Hata ayıklama geçmişi yeniden çalıştırmaya bağlı değil.

Örnek: bir ürün kullanıcı fotoğrafları yüklüyor. Uygulama “resize image” (resmi yeniden boyutlandır) görevi kuyruğa yazar. İşçi A bunu alır, küçük resimleri oluşturur, depolar ve görevi tamamlandı olarak işaretler. Görev iki kez çalışırsa çıktı aynıysa (idempotent), en az bir kez teslimat gayet uygundur. Başka bir servis bu görevi sonra okumaya ihtiyaç duymaz.

İhtiyaçlarınız paylaşılan gerçekler (çoklu tüketiciler), yeniden oynatma, denetim veya “sistem geçen hafta neye inanıyordu?” yönünde kaymaya başlarsa, işte o zaman Kafka etkinlik akışı ve log tabanlı yaklaşım daha çok değeri geri verir.

Ne zaman log tabanlı yaklaşım avantaj sağlar

Log tabanlı bir sistem, olaylar tek seferlik mesaj olmaktan çıkıp paylaşılan tarihe dönüştüğünde değer verir. "Gönder ve unut" yerine, birçok ekibin kendi hızlarında okuyup daha sonra yeniden oynatabileceği sıralı bir kayıt tutarsınız.

En net sinyal birden fazla tüketicidir. Bir "OrderPlaced" olayı faturalama, e-posta, fraud kontrolleri, arama indeksleme ve analiz gibi birden fazla sistemi besleyebilir. Log ile her tüketici aynı akışı bağımsız olarak okur. Özel bir fan-out boru hattı kurmanıza veya mesajı önce kim alacak diye koordine etmenize gerek kalmaz.

Bir diğer kazanım "o zaman ne biliyorduk?" sorusunu cevaplayabilmektir. Bir müşteri bir ücreti itiraz ederse veya öneri yanlışsa, eklenebilir tarihçe olayların geldiği haliyle yeniden oynatmayı mümkün kılar. Bu denetim izi sonradan basit bir kuyruğa eklenmesi zor bir özelliktir.

Ayrıca yeni özellikleri eski parçaları yeniden yazmadan eklemenin pratik bir yolunu elde edersiniz. Aylar sonra yeni bir "gönderim durumu" sayfası eklemek isterseniz, yeni bir servis abone olup geçmişten backfill yaparak durumunu oluşturabilir; tüm üst akım sistemlerden dışa aktarımlar istemek zorunda kalmazsınız.

Log tabanlı yaklaşım genelde şu ihtiyaçlardan biri veya daha fazlası olduğunda değerli olur:

  • Aynı olaylar birden fazla sistemi beslemeli (analiz, arama, faturalama, destek araçları).
  • Yeniden oynatma, denetim veya geçmişe dayalı soruşturmalar gerek.
  • Yeni servislerin özel işler yazmadan geçmişten backfill yapması gerek.
  • Varlık başına (sipariş, kullanıcı) sıra önemli.
  • Olay formatları evrilecek ve versiyonlamayı kontrollü ele almanız gerekecek.

Yaygın bir örüntü, siparişler ve e-postalarla başlayan bir üründür. Sonra finans gelir ve gelir raporları ister, ürün funnel analizi ister ve operasyon canlı pano ister. Her yeni ihtiyaç sizi yeni bir boru hattı kurmaya zorluyorsa maliyetler hızla görünür olur. Paylaşılan bir olay logu ekiplerin aynı kaynaktan inşa etmesine izin verir ve sistem büyüdükçe olay şekilleri değişse bile ortak bir gerçeğe dayanırlar.

Karar vermek: adım adım

Draft Events That Age Well
Draft stable event names and fields, then generate code to publish and consume.

Basit bir kuyruk ile log tabanlı yaklaşım arasında seçim yapmak, bunu bir ürün kararı gibi ele aldığınızda daha kolaydır. Sadece bu hafta işe yarayan değil, bir yıl sonra geçerli olacak ihtiyaçlara bakın.

Pratik 5 adımlık karar

  1. Yayıncıları ve okuyucuları haritalayın. Bugün kim olay oluşturuyor ve kim onları okuyor yazın; sonra yakın gelecekte olası tüketicileri ekleyin (analiz, arama indeksleme, fraud kontroller, müşteri bildirimleri). Eğer birçok ekibin aynı olayları bağımsız olarak okumasını bekliyorsanız, bir log mantıklı olmaya başlar.

  2. Geçmişi tekrar okumanız gerekip gerekmediğini sorun. Nedenini netleştirin: hatadan sonra yeniden oynatma, backfill veya farklı hızlarda okuyan tüketiciler. Kuyruklar işi bir kez devretmek için iyidir. Loglar tekrar oynatma ve kayıt tutma gerektiğinde daha iyidir.

  3. “Tamamlandı”nın ne anlama geldiğini tanımlayın. Bazı iş akışları için tamamlandı “işin çalıştırılması” demektir (e-posta gönderildi, resim yeniden boyutlandırıldı). Diğerlerinde tamamlandı “olayın kalıcı bir gerçek olması” demektir (sipariş verildi, ödeme yetkilendirildi). Kalıcı gerçekler sizi loga iter.

  4. Teslimat beklentilerini seçin ve çoğaltmaları nasıl ele alacağınızı belirleyin. At-least-once teslimat yaygındır; bu kopyalar olabileceği anlamına gelir. Eğer bir kopya zararlı olabilirse (çift ücretlendirme), idempotentlik planlayın: işlenmiş olay ID'si saklamak, benzersiz kısıtlar kullanmak veya güncellemeleri tekrar uygulanabilir hale getirmek.

  5. İnce bir dilimle başlayın. Kolay anlaşılabilir bir olay akışı seçin ve oradan büyütün. Kafka etkinlik akışına karar verirseniz, ilk topic'i odaklanmış tutun, olayları açıkça adlandırın ve ilgisiz olay türlerini karıştırmaktan kaçının.

Somut örnek: OrderPlaced daha sonra gönderim, faturalama, destek ve analizleri besleyecekse, bir log her ekibin kendi hızında okuyup hatalardan sonra yeniden oynatmasına izin verir. Eğer sadece makbuz e-postası gönderecek bir arka plan işine ihtiyacınız varsa, basit bir kuyruk genellikle yeterlidir.

Örnek: büyüyen bir üründe sipariş olayları

Küçük bir çevrimiçi mağaza hayal edin. İlk etapta sadece sipariş almak, kartı tahsil etmek ve gönderim talebi oluşturmak gerekir. En kolay versiyon, checkout sonrası çalışan bir arka plan işi: “process order.” Bu ödeme API'siyle konuşur, veritabanındaki sipariş satırını günceller ve ardından gönderimi çağırır.

Bu kuyruk stili, tek bir iş akışı olduğunda, yalnızca bir tüketici gerektiğinde ve yeniden denemeler ile dead-letter'lar çoğu hata durumunu karşıladığında iyi çalışır.

Mağaza büyüdükçe acı başlar. Destek otomatik “siparişim nerede?” güncellemeleri ister. Finans günlük gelir rakamları ister. Ürün ekibi müşteri e-postaları ister. Gönderimden önce bir fraud kontrolü yapılmalı. Tek bir “process order” işiyle aynı işçiyi tekrar tekrar düzenleyip dallar eklemeye başlarsınız ve çekirdek akışta yeni hatalar riski artar.

Log tabanlı bir yaklaşımda checkout küçük gerçekleri olay olarak üretir ve her ekip bunların üzerine inşa edebilir. Tipik olaylar şöyle görünebilir:

  • OrderPlaced
  • PaymentConfirmed
  • ItemShipped
  • RefundIssued

Ana değişiklik sahipliktir. Checkout servisi OrderPlaced'in sahibidir. Ödeme servisi PaymentConfirmed'in sahibidir. Gönderim ItemShipped'ın sahibidir. Daha sonra yeni tüketiciler üreticiyi değiştirmeden ortaya çıkabilir: fraud servisi OrderPlaced ve PaymentConfirmed'i okuyarak risk skoru hesaplar, bir e-posta servisi makbuzları gönderir, analiz funnel'lar oluşturur ve destek araçları ne olduğuna dair bir zaman çizelgesi tutar.

İşte Kafka etkinlik akışının değeri: log geçmişi saklar, böylece yeni tüketiciler baştan (veya bilinen bir noktadan) geri sarıp yakalayabilir; üreticiden her seferinde yeni bir webhook istemenize gerek kalmaz.

Log veritabanınızın yerini almaz. Hâlâ mevcut durumu sorgulamak için bir veritabanına ihtiyacınız var: en son sipariş durumu, müşteri kaydı, stok sayımları ve işlem kuralları (örneğin "ödeme onaylanmadan gönderme yapma"). Log'u değişikliklerin kaydı, veritabanını ise "şu an ne doğru" sorusunun cevabı olarak düşünün.

Yaygın hatalar ve tuzaklar

Add an Audit Trail App
Build a small service that logs business events and exposes a timeline for debugging.

Olay akışı sistemleri daha temiz hissettirebilir, ama birkaç yaygın hata faydaları hızla siler. Çoğu, olay logunu uzaktan kumanda gibi ele almaktan kaynaklanır, oysa log bir kayıt olmalıdır.

Sık görülen bir tuzak olayları komut şeklinde yazmaktır, örneğin “SendWelcomeEmail” veya “ChargeCardNow.” Bu tüketicileri niyete sıkı sıkıya bağlar. Olaylar gerçekler olarak daha iyi çalışır: “UserSignedUp” veya “PaymentAuthorized.” Gerçekler zamanla iyi yaşlanır. Yeni ekipler ne demek istediğinizi tahmin etmek zorunda kalmaz.

Çoğaltmalar ve yeniden denemeler bir diğer büyük ağrı kaynağıdır. Gerçek dünyada üreticiler yeniden dener ve tüketiciler yeniden işler. Bunu planlamazsanız çift ücretlendirme, çift e-posta ve mutsuz müşteri servisleriyle karşılaşırsınız. Çözüm egzotik değildir ama kasıtlı olmalıdır: idempotent işleyiciler, sabit olay ID'leri ve “zaten uygulandı”yı tespit eden iş kuralları.

Yaygın hatalar:

  • Hizmetlere ne yapmaları gerektiğini söyleyen komut tarzı olaylar kullanmak yerine, olanı kaydetmeyle ilgili olaylar yayınlamak.

  • Aynı olayı iki kez görürse bozulan tüketiciler oluşturmak.

  • Tek bir iş akışını çok erken parçalayıp iş akışını çok fazla topic'e yaymak.

  • Küçük bir değişiklik eski tüketicileri kırana dek şema kurallarını görmezden gelmek.

  • Streaming'i iyi veritabanı tasımının yerine koymak.

Şema ve versiyonlama özel dikkat gerektirir. JSON ile başlasanız bile açık bir sözleşmeye ihtiyacınız var: gerekli alanlar, opsiyonel alanlar ve değişikliklerin nasıl yayılacağı. Bir alanın yeniden adlandırılması gibi küçük bir değişiklik analitikleri, faturalamayı veya yavaş güncellenen mobil uygulamaları gizlice bozabilir.

Bir diğer tuzak aşırı bölme yapmaktır. Ekipler bazen her özellik için yeni bir stream oluşturur. Bir ay sonra kimse “Bir siparişin güncel durumu nedir?” diyemez çünkü öykü çok sayıda yerde dağılmıştır.

Olay akışı, sağlam veri modelleri ihtiyacını ortadan kaldırmaz. Hâlâ güncel gerçeği temsil eden bir veritabanına ihtiyacınız var. Log, tüm uygulama değildir; geçmişin kaydıdır.

Hızlı kontrol listesi ve sonraki adımlar

Kuyruk ile Kafka etkinlik akışı arasında seçim yapmakta zorlanıyorsanız, birkaç hızlı kontrolle başlamanız yeterlidir. Bu kontroller size işçi arası basit bir devretme mi yoksa yıllarca yeniden kullanılacak bir log mu gerektiğini söyleyecektir.

Hızlı kontroller

  • Yeniden oynatma (backfill, hata düzeltme veya yeni özellikler için) gerekiyor mu; ne kadar geriye?

  • Aynı olayları birden fazla tüketici şimdi veya yakında mı kullanacak (analiz, arama, e-postalar, fraud, faturalama)?

  • Üreticiden tekrar istemeden ekiplerin geçmişi yeniden okuyabilmesi için tutma (retention) gerekli mi?

  • Sıralama ne kadar önemli ve hangi düzeyde: varlık başına (sipariş, kullanıcı) mı yoksa gerçekten global mi?

  • Tüketiciler idempotent olabilir mi (aynı olayı yeniden uygulamak çift ücretlendirme, çift e-posta veya çift güncelleme yaratmaz mı)?

Eğer "hayır" dediniz: yeniden oynatma yok, tek tüketici var ve kısa ömürlü mesajlar söz konusuysa, temel bir kuyruk genellikle yeterlidir. "Evet" dediyseniz: yeniden oynatma, çoklu tüketiciler veya uzun tutma gerekiyorsa, log tabanlı yaklaşım genelde değeri geri verir çünkü tek bir gerçekler akışını diğer sistemlerin üzerine inşa edebileceği paylaşılan bir kaynağa dönüştürür.

Sonraki adımlar

Cevapları küçük, test edilebilir bir plana dönüştürün.

  • 5-10 temel olayı açık dille listeleyin (örnek: OrderPlaced, PaymentAuthorized, OrderShipped) ve her birinin kim tarafından yayınlandığını ve kimlerin tüketeceğini not edin.

  • Sıralama anahtarını belirleyin (çoğunlukla varlık başına, örneğin orderId) ve “doğru sıralama”nın ne anlama geldiğini belgeleyin.

  • Her tüketici için idempotentlik kuralı tanımlayın (örneğin: her sipariş için işlenen son olay ID'sini saklamak).

  • İhtiyaçlarınıza uygun bir tutulma hedefi seçin (kuyruk benzeri iş akışları için günler, yeniden oynatma önemliyse haftalar/aylar).

  • Karar vermeden önce bir sandbox'ta uçtan uca bir dilim çalıştırın.

Hızlı prototip yapıyorsanız, Koder.ai planning modunda olay akışını çizebilir ve tasarımı dağıtmadan önce yineleyebilirsiniz. Koder.ai kaynak kodu dışa aktarma, anlık görüntüler ve geri alma (rollback) desteklediği için bir üretici-tüketici dilimini test etmek ve olay şekillerini ayarlamak için pratik bir yoldur; böylece erken deneyler üretime dönüşen teknik borca dönüşmez.

SSS

What’s the simplest way to explain “queue vs log”?

Kuyruk, iş tamamlandıktan sonra unutulmasını istediğiniz iş biletleri (e-posta gönderme, resmi yeniden boyutlandırma, bir işi çalıştırma) için en iyisidir. Kayıt (log) ise saklamak istediğiniz ve birçok sistemin daha sonra okuyup yeniden oynatabileceği olaylar içindir (sipariş verildi, ödeme onaylandı, iade yapıldı).

How do I know my point-to-point integrations are becoming a problem?

Bunu şunu hissettiğinizde anlarsınız: her yeni özellik birçok entegrasyonu değiştirmeyi gerektiriyor ve hata ayıklama “bu değeri kim yazdı?” gibi bir çıkmaza dönüşüyor. Bir log, ortak bir kayıt sunduğu için daha iyi: geçmişi inceleyebilir ve gerektiğinde yeniden oynatabilirsiniz.

When does a log-based approach (Kafka-style) actually pay off?

Aşağıdaki durumlarda değer verir: hatayı düzeltmek için geçmişi tekrar işleme (replay), eski veriden yeni bir özelliği doldurma (backfill), “o zaman ne biliyorduk?” gibi soruşturmalarda cevap almak veya birden fazla tüketici (faturalama, analiz, destek, dolandırıcılık) olduğunda üreticiyi her seferinde değiştirmek zorunda kalmamak.

Why does the “source of truth” argument get worse as systems grow?

Çünkü sistemler karmaşık hatalar yapar: tekrarlar, zaman aşımı, kısmi kesintiler ve manuel düzeltmeler. Eğer her servis diğerlerini doğrudan güncelliyorsa, farklı hizmetler olayların sırası hakkında anlaşmazlığa düşebilir. Eklenebilir (append-only) bir olay geçmişi, hangi olayların hangi sırayla geldiğini anlamanıza yardımcı olur; tüketiciler kapalıyken bile daha sonra yakalayabilirler.

What should an event look like if I want it to age well?

Olayları geçmişte olmuş değişiklikler olarak modelleyin ve değiştirilebilir komutlar yerine gerçekleri yayınlayın:

  • OrderPlaced, değil ProcessOrder
  • PaymentAuthorized, değil ChargeCardNow
  • UserEmailChanged, değil UpdateEmail

Bir şey değişirse, eski kaydı düzenlemek yerine yeni bir olay yayınlayın ve yeni durumu beyan edin.

How do I prevent duplicate events from causing real damage?

Çoğu sistemde tekrarlar olacaktır (at-least-once teslimat yaygındır). Her tüketiciyi güvenli hale getmek için:

  • Kararlı bir event ID kullanın ve “zaten işlendi” işaretleri saklayın
  • Mümkünse benzersiz kısıtlar uygulayın
  • Aynı olayı tekrar uygulamanın çift yan etki yaratmayacağı şekilde tasarlayın (iki kez ücretlendirme gibi)

Varsayılan kural: önce doğruluk, sonra hız.

How should I evolve event schemas without breaking consumers?

Eklemesel (additive) değişiklikleri tercih edin: eski alanları koruyun, yeni alanları opsiyonel ekleyin ve alan yeniden adlandırma/kaldırma gibi değişikliklerden kaçının. Zorunlu olarak geriye dönük uyumsuzluk yapmanız gerekiyorsa, olayı (veya topic/stream’i) versiyonlayın ve tüketicileri planlı şekilde taşıyın.

What’s a good first step if I’m switching from a queue mindset to a log mindset?

İnce, uçtan uca bir dilimle başlayın:

  1. Tek bir iş akışını seçin (örneğin OrderPlaced → e-posta makbuzu).
  2. Açık olay isimleri ve gerekli alanları tanımlayın.
  3. Sıralama anahtarını seçin (genelde orderId veya userId).
  4. Tüketiciyi idempotent yapın.
  5. Test sırasında yeniden oynatma için yeterli tutulma süresi belirleyin.

Döngünün çalıştığını kanıtlayın, sonra daha fazla olay ve ekip ekleyin.

Does an event log replace my database?

Hayır. Geçerli durum için bir veritabanı tutmaya devam edin: en son sipariş durumu, müşteri kaydı, stok sayımları ve işlemsel kurallar (örneğin “ödeme onaylanmadan gönderme yapma”). Log değişikliklerin kaydıdır; veritabanı “şu an doğru olan”ı sorguladığınız yerdir. Log, türetilmiş görünümleri yeniden oluşturmak için kullanılır (analiz tabloları, arama indeksleri, zaman çizelgeleri).

How can Koder.ai help me prototype an event-streaming design safely?

Planning modu, yayıncıları/tüketicileri haritalamak, olay isimlerini tanımlamak ve idempotentlik ile tutulma sürelerini belirlemek için faydalıdır. Ardından küçük bir üretici-tüketici dilimi uygulayıp anlık görüntüler (snapshots) alabilir ve geri almayı (rollback) deneyebilirsiniz. Stabil olduğunda kaynak kodunu dışa aktarın ve diğer servisler gibi dağıtın.

Related posts