Apache Ecosystem

Mikroservisler İçin Gelişmiş Kafka Şema Kaydı ve Veri Sözleşmeleri

Mikroservis mimarileri ölçeklendikçe, mesaj şemalarının sessiz evrimi genellikle sistemin kırılganlığının kritik bir kaynağı haline gelir. Apache Kafka yüksek verimli, dağıtık mesajlaşma sunsa da tasarım gereği şemadan bağımsızdır. Katı bir yönetim olmadan, üreticiler ve tüketiciler birbirinden uzaklaşabilir; bu da ayrıştırma hatalarına, veri kaybına veya kaskad benzeri arızalara yol açabilir. Confluent'in Şema Kaydı'nın (Schema Registry) sağlam veri sözleşmesi uygulama mekanizmalarıyla entegrasyonu artık bir seçenek değil; dayanıklı, kurumsal düzeyde olay yönlendirmeli sistemler inşa etmek için temel bir gerekliliktir. Bu yazıda, Şema Kaydı'nı uyumluluğu uygulamak, karmaşık sürüm yönetimini gerçekleştirmek ve servisler arasında net veri sözleşmeleri kurmak için kullanmanın gelişmiş stratejilerini ele alıyoruz.

Olay Yönlendirmeli Mimariye Şema Kaydı'nın Rolü

Şema Kaydı, bir Kafka kümesinde şema yönetimi için merkezi otorite olarak görev yapar. Şemaları merkezi bir depoda saklayarak ve yöneterek, istemcilerin veri yapısının tam farkında olarak mesajları seri hale getirmesini ve seri dışı hale getirmesini sağlar. Bu endişelerin ayrılması, güçlü uyumluluk denetlemelerine olanak tanır. Bir üretici bir şema yayınlamaya çalıştığında, kayıt defteri bunu mevcut sürümlerle karşılaştırarak doğrular. Şema, yapılandırılmış uyumluluk kurallarını ihlal ediyorsa kayıt reddedilir. Bu, uyumsuz verilerin akışa girmesini önler ve tüm tüketicilerin mesajı kırıcı değişiklikler olmadan işleyebileceğinden emin olunur.

Üç temel uyumluluk modu vardır: BACKWARD (Geriye Uyumlu), FORWARD (İleriye Uyumlu) ve FULL (Tam). Tipik bir üretici-tüketici kurulumunda, yeni şemaların eski mesajları okuyabilmesini, eski şemaların ise yenilerini okuyamayabileceğini garanti ettiği için BACKWARD uyumluluğu genellikle tercih edilir. Ancak uzun vadeli veri kalıcılığı ve karmaşık tüketici ortamları için FULL uyumluluk, hem yeni hem de eski sürümlerin sorunsuz bir şekilde bir arada var olmasını sağlar; ancak bu, şema evrimi üzerinde daha sıkı kısıtlamalarla gelir.

Avro ve Protobuf ile Veri Sözleşmeleri Uygulama

Doğru seri hale getirme biçimini seçmek, bir veri sözleşmesi tanımlamada ilk adımdır. Apache Avro ve Google Protocol Buffers (Protobuf) en yaygın seçimlerdir. Avro şema tabanlıdır, yani şema kayıt defterinde saklanır ve ikili biçim çalışma zamanında ondan türetilir. Protobuf dil bağımsızdır ve çok verimlidir, metin tabanlı bir biçimde tanımlanan bir ikili biçim kullanır. Her iküsü de güçlü tiplemeyi ve sürüm yönetimini destekler, ancak Şema Kaydı'nda farklı işleme stratejileri gerektirirler.

Bir sipariş olayı için Avro şemasının aşağıdaki örneğini düşünün. Kayıt defterinin konuyu (subject) tanımlaması için kritik olan namespace (ad alanı) ve type (tür) tanımlarına dikkat edin.

{
  "type": "record",
  "name": "OrderCreated",
  "namespace": "com.example.orders",
  "fields": [
    {"name": "orderId", "type": "string"},
    {"name": "customerId", "type": "string"},
    {"name": "totalAmount", "type": "double"},
    {"name": "createdAt", "type": "long"}
  ]
}

Bu şema kaydedildiğinde, genellikle konu adından ve Kafka başlık alanından türetilen bir konuyla (subject) ilişkilendirilir. Örneğin, OrderKey için bir anahtar şemasına ve OrderCreated için bir değer şemasına sahip orders konusu, orders-key ve orders-value gibi konular oluşturur. Kayıt defteri, bu konular altında kaydedilen herhangi bir sonraki şemanın mevcut sürümle uyumlu olduğunu garanti eder.

Gelişmiş Uyumluluk Modları ve Sürüm Yönetimi Stratejileri

Birden fazla servisi yöneten ekipler için, varsayılan FULL veya BACKWARD uyumluluğu çok kısıtlayıcı veya çok gevşek olabilir. Gelişmiş uygulamalar genellikle konu düzeyinde yapılandırma geçersiz kılma özelliklerini kullanır. Şema Kaydı, uyumluluk kurallarını konu başına veya hatta konu (subject) başına yapılandırmanıza olanak tanır. Bu, belirli konuların tek bir servisin içine ait olduğu ve kırıcı değişikliklerin kabul edilebilir olduğu ve koordine edilmiş dağıtımlar yoluyla yönetilebildiği durumlarda özellikle faydalıdır.

Farklı ekiplerin farklı şemaların sahibi olduğu çok kiracılı (multi-tenant) ortamlarda, bir yönetim katmanı uygulamak esastır. Bu, özel eklentiler aracılığıyla veya Şema Kaydı'nın API'sini denetim günlükleri oluşturmak için kullanarak sağlanabilir. Hangi ekibin hangi şema sürümünü ne zaman kaydettiğini izleyerek, ekipler kayıt öncesi şema değişikliklerinin akran incelemesi (peer review) sürecinden geçmesini gerektiren kurumsal politikaları uygulayabilir.

Tüketici Gecikmesi ve Şema Evrimiyle Başa Çıkma

Yırtıcı uyumluluk denetlemelerine rağmen, tüketiciler üreticilerin gerisinde kalabilir. Bir üretici yeni, uyumlu bir şema kaydeder ve mesaj yayınlamaya başlarsa, hâlâ daha eski bir önbelleğe alınmış şema kullanan bir tüketici, yeni verileri seri dışı hale getirebilmelidir. Avro'nun ikili biçimi, varsayılan değerlere sahip yeni alanların eski şemalar tarafından okunabileceğini ve isteğe bağlı alanların yeni şemalar tarafından yok sayılabileceğini garanti eder. Ancak bu, varsayılan değerlerin ve alan sıralamasının doğru işlenmesine bağlıdır.

Protobuf için, bilinmeyen alanların işlenmesi kritiktir. Protobuf hat biçimine (wire-format) dayalı olduğu için, bilinmeyen alanlar varsayılan olarak atlanır; bu da onu ekleyici değişiklikler için doğal olarak geriye uyumlu kılar. Ancak, bir alanın kaldırılması veya türünün değiştirilmesi, seri dışı hale getirme hatalarına neden olabilir. Bu nedenle, Protobuf için veri sözleşmeleri, alan kaldırılmalarını açıkça yasaklamalı ve sıkı tip istikrarını uygulamalıdır.

Pratik Örnek: Java'da Şema Kaydetme ve Kullanma

Şema Kaydı'nı Java tabanlı bir üreticiye entegre etmek, Confluent Kafka istemci kütüphanesi kullanılarak basittir. Aşağıdaki örnek, Avro seri hale getirme ve Şema Kaydı ile bir üreticinin nasıl yapılandırılacağını göstermektedir.

Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, KafkaAvroSerializer.class);
props.put(SchemaRegistryClient.SCHEMA_REGISTRY_URL_CONFIG, "http://schema-registry:8081");

KafkaAvroSerializer serializer = new KafkaAvroSerializer(new SchemaRegistryClient(props));
Producer producer = new KafkaProducer<>(props);

OrderCreated order = new OrderCreated();
order.setOrderId("ORD-12345");
order.setCustomerId("CUST-98765");
order.setTotalAmount(150.75);
order.setCreatedAt(System.currentTimeMillis());

producer.send(new ProducerRecord<>("orders", "ORD-12345", order));
producer.flush();
producer.close();

Tüketici tarafında, KafkaAvroDeserializer, şema kimliğini mesaj başlığından alır ve yükü (payload) seri dışı hale getirmek için şemayı kayıt defterinden getirir. Bu, tüketicinin en son şema değişikliğinden önce dağıtılmış olsa bile her zaman doğru şema sürümüne sahip olmasını garanti eder.

Veri Sözleşmesi Uygulaması İçin En İyi Uygulamalar

Şema Kaydı entegrasyonunun faydalarını en üst düzeye çıkarmak için aşağıdaki en iyi uygulamalara uyun:

  1. Açık Konu (Subject) Adları Kullanın: Otomatik konu adlandırma kurallarına güvenmekten kaçının. Şemaların sahipliğini ve amacını netleştirmek için açık konu adları kullanın.
  2. Sıkı Uyumluluğu Uygulayın: Herhangi bir türde kırıcı değişikliği önlemek için tüm herkese açık konular için FULL uyumluluğu kullanın.
  3. Otomatik Testler Uygulayın: Şema değişikliklerini dağıtım öncesi CI/CD hatlarında doğrulamak için Confluent'in schema-compat aracı veya özel betikleri kullanın.
  4. Şema Kaydı Sağlığını İzleyin: Şema Kaydı kritik bir bağımlılıktır. Kullanılabilirliğini ve gecikmesini izleyin ve kayıt defteri kesintilerini zarif bir şekilde ele almak için tüketicilerde devre kesiciler (circuit breakers) uygulayın.
  5. Şemaları Belgeleyin: Tüm şemaların, sahiplerinin, sürüm geçmişlerinin ve ilişkili veri sözleşmelerinin canlı bir belgesini tutun.

Sonuç

Apache Kafka'nın bir Şema Kaydı ile entegrasyonu, modern mikroservis mimarisinin temel taşıdır. Veri sözleşmeleri ve uyumluluk kurallarını uygulayarak, kuruluşlar güvenilirlikten veya veri bütünlüğünden ödün vermeden olay yönlendirmeli sistemlerin çevikliğine ulaşabilir. Mimariniz büyüdükçe, sağlam bir şema yönetimi stratejisine yatırım yapmak, hata ayıklama süresinin azalması, geliştirici verimliliğinin artması ve daha dayanıklı bir sistem olarak karşılığını verecektir. Şema yönetimini bürokratik bir yük olarak değil, dağıtık sistemlerinizde güven ve netlik inşa etmek için stratejik bir araç olarak benimseyin.

Share: