Modern dağıtık sistemlerde veri tutarlılığını sağlamak, özellikle mikroservis mimarileri ve olay tabanlı sistemlerle çalışırken karmaşık bir meydan okumadır. Peki, Kafka gibi güçlü bir mesajlaşma platformunu kullanırken veri şemalarınızın evrimini nasıl yönetir, farklı servisler arasında veri uyumsuzluklarını nasıl önlersiniz? Bu makalede, DigitalOcean üzerinde Kafka Schema Registry’yi adım adım kurarak ve kullanarak bu sorulara yanıt bulacağız.
Kafka Schema Registry Nedir ve Neden Bu Kadar Önemli?
Dağıtık sistemlerde, özellikle de olay tabanlı mimarilerde, farklı mikroservisler arasında veri alışverişi kritik bir öneme sahiptir. Bu veri alışverişi genellikle Kafka gibi mesaj kuyrukları aracılığıyla gerçekleşir. Ancak bu mesajların formatı zamanla değişebilir; yeni alanlar eklenebilir, mevcut alanlar kaldırılabilir veya veri tipleri güncellenebilir. İşte tam da bu noktada, veri uyumsuzlukları ve hatalar baş göstermeye başlar. Bir servis eski bir formatta veri gönderirken, başka bir servis yeni formatı bekleyebilir ve bu durum sistem genelinde ciddi sorunlara yol açabilir. Bu karmaşayı çözmek ve veri tutarlılığını garanti altına almak için Kafka Schema Registry devreye girer.
Kafka Schema Registry, Kafka’da üretilen ve tüketilen mesajların şemalarını (yapılarını) merkezi bir yerde yöneten bir depodur. Temel amacı, veri üreticileri ve tüketicileri arasında veri formatı uyumluluğunu sağlamak ve veri evrimini kontrollü bir şekilde yönetmektir. Genellikle Avro, Protobuf veya JSON Schema gibi serileştirme formatlarıyla birlikte kullanılır. Bu formatlar, veriyi kompakt ve hızlı bir şekilde serileştirmekle kalmaz, aynı zamanda şema tanımıyla birlikte gelirler. Schema Registry, bu şemaları saklar ve her bir Kafka konusuna (topic) karşılık gelen şema sürümlerini takip eder.
Schema Registry’nin sağladığı temel faydalar şunlardır:
- Veri Tutarlılığı ve Güvenliği: Üreticiler, mesajlarını göndermeden önce şemaya uygun olup olmadığını kontrol edebilir. Tüketiciler ise aldıkları mesajların hangi şemaya ait olduğunu bilerek doğru şekilde deserileştirebilir. Bu, hatalı veya uyumsuz verinin sisteme girmesini engeller.
- Şema Evrimi Yönetimi: Uygulamalar geliştikçe veri şemaları da evrimleşir. Schema Registry, şema değişikliklerini (yeni alan ekleme, alan kaldırma vb.) belirli uyumluluk kurallarına göre yönetir. Bu sayede, eski ve yeni versiyonlar arasında sorunsuz bir geçiş sağlanır.
- Performans İyileştirmesi: Avro gibi ikili serileştirme formatları, JSON veya XML’e göre daha az yer kaplar ve daha hızlı işlenir. Schema Registry, şema kimliklerini kullanarak mesaj boyutunu küçültür, çünkü şema tanımını her mesaja dahil etmek yerine sadece şema kimliğini gönderir.
- Merkezi Yönetim: Tüm şemaların tek bir merkezi yerde depolanması, geliştiricilerin hangi şemaların mevcut olduğunu ve nasıl kullanıldığını kolayca görmesini sağlar. Bu, dokümantasyonu basitleştirir ve geliştirme sürecini hızlandırır.
- Dil Bağımsızlığı: Farklı programlama dilleriyle yazılmış servisler, aynı şemayı kullanarak uyumlu bir şekilde veri alışverişi yapabilir.
Özetle, Kafka Schema Registry, modern veri odaklı uygulamalar için vazgeçilmez bir araçtır. Veri uyumsuzluklarından kaynaklanan sorunları ortadan kaldırarak geliştirme süreçlerini hızlandırır, sistem kararlılığını artırır ve uzun vadede bakım maliyetlerini düşürür. DigitalOcean gibi bulut platformlarında çalışırken, bu merkezi yönetim ve tutarlılık katmanı, dağıtık sistemlerinizin sağlığı için hayati önem taşır.
DigitalOcean’da Bir Kafka Ortamı Nasıl Kurulur?
DigitalOcean üzerinde bir Kafka ortamı kurmanın birkaç yolu vardır. En yaygın ve önerilen yöntem, DigitalOcean’ın Managed Kafka hizmetini kullanmaktır. Bu hizmet, Kafka kümesinin kurulumu, yönetimi ve ölçeklenmesi gibi karmaşık operasyonel görevleri sizin yerinize üstlenir. Ancak, daha fazla kontrol veya özel yapılandırma gerektiren durumlar için bir Droplet (sanal sunucu) üzerine manuel kurulum da mümkündür. Bu makalede, hem Managed Kafka’nın sunduğu kolaylıklara değinecek hem de manuel kurulum için temel adımları özetleyeceğiz.
DigitalOcean Managed Kafka ile Kolay Kurulum
DigitalOcean Managed Kafka, tam olarak yönetilen bir hizmettir ve Zookeeper, Kafka broker’ları gibi tüm bileşenleri sizin için otomatik olarak ayarlar ve yönetir. Bu, özellikle operasyonel yükü azaltmak isteyen ekipler için idealdir.
- Hesap Oluşturma ve Giriş: DigitalOcean hesabınıza giriş yapın. Eğer yoksa, kolayca bir hesap oluşturabilirsiniz.
- Yeni Veritabanı Kümesi Oluşturma: Kontrol panelinde sol menüden “Databases” (Veritabanları) seçeneğine tıklayın. Ardından “Create a Database Cluster” (Veritabanı Kümesi Oluştur) butonuna basın.
- Kafka Seçimi: Veritabanı tipi olarak “Kafka”yı seçin.
- Plan ve Bölge Seçimi: İhtiyaçlarınıza uygun bir Kafka planı (geliştirme, üretim vb.) ve coğrafi bölge (örneğin, Frankfurt, Amsterdam) seçin. Bölge seçimi, uygulamanızın konumuna yakın olmalı ve gecikmeyi en aza indirmelidir.
- Küme Yapılandırması: Kümenizin adını belirleyin ve isterseniz etiketler ekleyin. Ayrıca, hangi VPC ağına (eğer kullanıyorsanız) bağlanacağını da seçebilirsiniz.
- Oluşturma: “Create a Database Cluster” butonuna tıklayarak Kafka kümenizi oluşturun. Bu işlem birkaç dakika sürebilir.
Küme oluşturulduktan sonra, bağlantı detaylarınıza (broker adresleri, kullanıcı adı, şifre, CA sertifikası) erişebilirsiniz. Bu bilgiler, Kafka üreticilerinizi ve tüketicilerinizi yapılandırmak için kullanılacaktır. Managed Kafka ile kurulum, altyapı yönetimiyle uğraşmadan doğrudan Kafka uygulamalarınıza odaklanmanızı sağlar.
Droplet Üzerinde Manuel Kafka Kurulumu (Kısa Özet)
Eğer Managed Kafka kullanmak istemiyorsanız, bir DigitalOcean Droplet’i üzerine manuel olarak Kafka kurabilirsiniz. Bu yöntem daha fazla esneklik sunar ancak operasyonel sorumluluğu artırır. İşte temel adımlar:
- Droplet Oluşturma: DigitalOcean kontrol panelinden bir Ubuntu Droplet’i oluşturun (minimum 2GB RAM önerilir). SSH ile Droplet’e bağlanın.
- Java Kurulumu: Kafka Java tabanlı olduğu için OpenJDK kurmanız gerekir.
sudo apt update sudo apt install openjdk-11-jdk -y - Kafka İndirme ve Çıkarma: Apache Kafka’nın en son stabil sürümünü indirin ve sıkıştırılmış dosyayı çıkarın.
wget https://downloads.apache.org/kafka/3.6.1/kafka_2.13-3.6.1.tgz tar -xzf kafka_2.13-3.6.1.tgz mv kafka_2.13-3.6.1 /opt/kafka - Zookeeper ve Kafka Başlatma: Kafka, Zookeeper’a bağımlıdır. Önce Zookeeper’ı, sonra Kafka broker’ını başlatın.
/opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
Bu adımlar, basit bir tek düğümlü Kafka kurulumu için yeterlidir. Üretim ortamları için çoklu broker’lı, yüksek erişilebilirliğe sahip bir küme yapılandırması ve sistemd servisleri ile otomatik başlatma gibi ek adımlar gerekecektir. Her iki durumda da, Kafka ortamınız hazır olduğunda, Schema Registry’yi entegre etmeye geçebiliriz.
Schema Registry’yi DigitalOcean Üzerinde Nasıl Konumlandırırız?
Kafka Schema Registry’yi DigitalOcean üzerinde konumlandırmak, genellikle bir Droplet üzerine Docker veya manuel kurulum yoluyla gerçekleştirilir. Managed Kafka hizmeti Schema Registry’yi doğrudan içermediği için, onu ayrı bir servis olarak çalıştırmanız gerekecektir. En esnek ve modern yaklaşım, Docker kullanarak Schema Registry’yi dağıtmaktır. Bu bölüm, Docker Compose ile hızlı bir kurulumu ve temel yapılandırmayı kapsayacaktır.
Docker Compose ile Schema Registry Kurulumu
Docker Compose, birden fazla Docker container’ını tanımlamak ve çalıştırmak için bir araçtır. Schema Registry’yi, Kafka broker’larınızla birlikte veya ayrı bir Droplet üzerinde çalıştırmak için idealdir. Aşağıdaki adımlar, temel bir kurulumu göstermektedir.
- Droplet Oluşturma ve Docker Kurulumu: DigitalOcean’da bir Ubuntu Droplet’i oluşturun. Bu Droplet, Schema Registry’yi barındıracak. Droplet’e SSH ile bağlandıktan sonra Docker ve Docker Compose’u kurun:
sudo apt update sudo apt install apt-transport-https ca-certificates curl software-properties-common -y curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io -y sudo usermod -aG docker ${USER} # Kullanıcıyı docker grubuna ekle newgrp docker # Grubun aktif olması için sudo apt install docker-compose -y - Docker Compose Dosyası Oluşturma: Bir metin editörü kullanarak (örneğin
nano)docker-compose.ymladında bir dosya oluşturun:nano docker-compose.ymlİçeriği aşağıdaki gibi doldurun. Burada Confluent’in resmi Schema Registry Docker imajını kullanıyoruz.
version: '3.8' services: schema-registry: image: confluentinc/cp-schema-registry:7.5.0 # En son stabil sürümü kontrol edin hostname: schema-registry container_name: schema-registry ports: - "8081:8081" # Schema Registry API portu environment: # Kafka broker adresleri. Eğer DigitalOcean Managed Kafka kullanıyorsanız, buraya bağlantı dizesini ekleyin. # Örnek: broker1:9092,broker2:9092 SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: "PLAINTEXT://your-kafka-broker-ip:9092" SCHEMA_REGISTRY_HOST_NAME: schema-registry SCHEMA_REGISTRY_LISTENERS: "http://0.0.0.0:8081" # Eğer Managed Kafka kullanıyorsanız ve SSL/TLS gerekiyorsa ek ayarlar # SCHEMA_REGISTRY_KAFKASTORE_SECURITY_PROTOCOL: SSL # SCHEMA_REGISTRY_KAFKASTORE_SSL_TRUSTSTORE_LOCATION: /etc/kafka/secrets/truststore.jks # SCHEMA_REGISTRY_KAFKASTORE_SSL_TRUSTSTORE_PASSWORD: your_truststore_password # SCHEMA_REGISTRY_KAFKASTORE_SSL_KEYSTORE_LOCATION: /etc/kafka/secrets/keystore.jks # SCHEMA_REGISTRY_KAFKASTORE_SSL_KEYSTORE_PASSWORD: your_keystore_password # SCHEMA_REGISTRY_KAFKASTORE_SSL_KEY_PASSWORD: your_key_password # Eğer kimlik doğrulama gerekiyorsa (SASL_SSL) # SCHEMA_REGISTRY_KAFKASTORE_SASL_MECHANISM: PLAIN # SCHEMA_REGISTRY_KAFKASTORE_SASL_JAAS_CONFIG: "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"your_username\" password=\"your_password\";" networks: - kafka-net # Eğer Kafka broker'ınız aynı Docker ağındaysa networks: kafka-net: driver: bridgeÖnemli Not:
SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERSkısmını kendi Kafka broker adreslerinizle güncellemeyi unutmayın. Eğer DigitalOcean Managed Kafka kullanıyorsanız, bağlantı dizenizdeki tüm broker’ları ve portlarını buraya eklemelisiniz. Ayrıca, Managed Kafka genellikle SSL/TLS ve SASL kimlik doğrulaması gerektirir. Bu durumda, yukarıdaki yorum satırındaki ilgili ayarları yapılandırmanız ve gerekli sertifika/anahtar dosyalarını Docker container’ına bind mount etmeniz gerekebilir. - Schema Registry’yi Başlatma:
docker-compose.ymldosyasını kaydettikten sonra, aynı dizinde aşağıdaki komutu çalıştırarak Schema Registry’yi başlatın:docker-compose up -d-dbayrağı, container’ı arka planda çalıştırmanızı sağlar. - Durumu Kontrol Etme: Schema Registry’nin başarıyla çalıştığını doğrulamak için:
docker psveya logları kontrol edebilirsiniz:
docker logs schema-registryAyrıca, Droplet’inizin genel IP adresinden 8081 portuna bir cURL isteği göndererek API’nin yanıt verip vermediğini test edebilirsiniz:
curl -X GET http://your_droplet_ip:8081/subjectsBoş bir dizi (
[]) veya hata mesajı almanız beklenir, bu da Schema Registry’nin çalıştığını gösterir.
Bu kurulumla birlikte, Kafka Schema Registry’niz artık DigitalOcean Droplet’inizde çalışır durumda. Bir sonraki adım, şemaları tanımlamak ve uygulamalarınızla entegre etmektir.
Veri Şemaları Nasıl Tanımlanır ve Yönetilir? (Uygulamalı Örnekler)
Schema Registry’nin temel işlevi, veri şemalarını merkezi olarak depolamak ve yönetmektir. Bu bölümde, Avro şemalarını nasıl tanımlayacağımızı, Schema Registry’ye nasıl kaydedeceğimizi ve Kafka üreticileri ile tüketicileri arasında nasıl kullanacağımızı adım adım inceleyeceğiz. Avro, hem şema tanımlama hem de kompakt ikili serileştirme için popüler bir seçimdir.
Avro Şeması Tanımlama
Avro şemaları, JSON formatında tanımlanır. Basit bir kullanıcı mesajı için bir Avro şeması oluşturalım. Bu şema, bir kullanıcının ID’sini, adını, soyadını ve e-posta adresini içerecektir.
user-registered.avsc adında bir dosya oluşturalım:
{
"type": "record",
"name": "UserRegistered",
"namespace": "com.example.events",
"fields": [
{"name": "id", "type": "string"},
{"name": "firstName", "type": "string"},
{"name": "lastName", "type": "string"},
{"name": "email", "type": ["null", "string"], "default": null}
]
}
Bu şema:
type: "record": Bir kayıt (nesne) tanımladığını belirtir.name: "UserRegistered": Şemanın adıdır.namespace: "com.example.events": Şemanın mantıksal grubunu belirler.fields: Kaydın alanlarını tanımlar. Her alanın bir adı (name) ve bir tipi (type) vardır.emailalanı,["null", "string"]ile hem null olabileceğini hem de string olabileceğini belirtir,"default": nullise varsayılan değerini ayarlar.
Schema Registry’ye Şema Kaydetme
Oluşturduğumuz Avro şemasını Schema Registry’ye kaydetmek için cURL komutunu kullanabiliriz. Şema, bir Kafka konusuna (topic) bağlı olarak kaydedilir. Schema Registry, şema kaydını yaparken konu adını ve anahtar/değer şeması olup olmadığını dikkate alır. Genellikle <topic_adı>-value veya <topic_adı>-key formatında konu adları kullanılır.
user-registered.avsc dosyamızı Schema Registry’ye kaydedelim. Droplet’inizin IP adresini your_droplet_ip ile değiştirmeyi unutmayın:
curl -X POST -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "$(cat user-registered.avsc)"}' \
http://your_droplet_ip:8081/subjects/user-registered-value/versions
Başarılı bir kayıt sonrası, Schema Registry size bir şema ID’si döndürecektir. Örneğin: {"id":1}. Bu ID, Kafka mesajlarınızda şema referansı olarak kullanılacaktır.
Kaydedilen şemaları ve versiyonlarını kontrol etmek için:
curl -X GET http://your_droplet_ip:8081/subjects/user-registered-value/versions
curl -X GET http://your_droplet_ip:8081/subjects/user-registered-value/versions/1
Kafka Üreticisi ve Tüketicisi ile Entegrasyon (Python Örneği)
Şema kaydedildikten sonra, Kafka üreticileri ve tüketicileri bu şemayı kullanarak veri serileştirme ve deserileştirme işlemlerini gerçekleştirebilir. Bu, Confluent’in Kafka istemci kütüphaneleri (örneğin confluent-kafka-python) aracılığıyla kolayca yapılır.
Öncelikle gerekli kütüphaneleri yükleyin:
pip install confluent-kafka
pip install avro
Kafka Üreticisi (Producer)
producer.py:
from confluent_kafka import SerializingProducer
from confluent_kafka.schema_registry import SchemaRegistryClient
from confluent_kafka.schema_registry.avro import AvroSerializer
from confluent_kafka.serialization import StringSerializer
# Kafka ve Schema Registry ayarları
KAFKA_BROKER = "your-kafka-broker-ip:9092" # DigitalOcean Managed Kafka bağlantı dizesi
SCHEMA_REGISTRY_URL = "http://your_droplet_ip:8081"
TOPIC = "user-registered"
# Avro şeması (bir önceki bölümde tanımladığımız dosyanın içeriği)
avro_schema_str = """
{
"type": "record",
"name": "UserRegistered",
"namespace": "com.example.events",
"fields": [
{"name": "id", "type": "string"},
{"name": "firstName", "type": "string"},
{"name": "lastName", "type": "string"},
{"name": "email", "type": ["null", "string"], "default": null}
]
}
"""
# Schema Registry istemcisi
schema_registry_client = SchemaRegistryClient({'url': SCHEMA_REGISTRY_URL})
# Avro serileştirici
# 'avro_schema_str' yerine 'schema_registry_client.get_latest_version(f"{TOPIC}-value").schema.schema_str' de kullanılabilir
avro_serializer = AvroSerializer(schema_registry_client, avro_schema_str)
# Üretici yapılandırması
producer_conf = {
'bootstrap.servers': KAFKA_BROKER,
'key.serializer': StringSerializer('utf_8'), # Anahtarı serileştirmek için
'value.serializer': avro_serializer
# Eğer Managed Kafka kullanıyorsanız SSL/SASL ayarları
# 'security.protocol': 'SASL_SSL',
# 'sasl.mechanism': 'PLAIN',
# 'sasl.username': 'your_username',
# 'sasl.password': 'your_password',
# 'ssl.ca.location': '/path/to/your/ca-cert.pem'
}
producer = SerializingProducer(producer_conf)
def delivery_report(err, msg):
if err is not None:
print(f"Mesaj gönderimi başarısız: {err}")
else:
print(f"Mesaj gönderildi. Konu: {msg.topic()}, Bölüm: {msg.partition()}, Ofset: {msg.offset()}")
# Gönderilecek veri
user_data = {
"id": "user-123",
"firstName": "Ali",
"lastName": "Can",
"email": "ali.can@example.com"
}
try:
producer.produce(
topic=TOPIC,
key=user_data["id"],
value=user_data,
on_delivery=delivery_report
)
producer.flush() # Mesajların gönderildiğinden emin olun
except Exception as e:
print(f"Hata oluştu: {e}")
Kafka Tüketicisi (Consumer)
consumer.py:
from confluent_kafka import DeserializingConsumer
from confluent_kafka.schema_registry import SchemaRegistryClient
from confluent_kafka.schema_registry.avro import AvroDeserializer
from confluent_kafka.serialization import StringDeserializer
# Kafka ve Schema Registry ayarları
KAFKA_BROKER = "your-kafka-broker-ip:9092" # DigitalOcean Managed Kafka bağlantı dizesi
SCHEMA_REGISTRY_URL = "http://your_droplet_ip:8081"
TOPIC = "user-registered"
GROUP_ID = "my-consumer-group"
# Schema Registry istemcisi
schema_registry_client = SchemaRegistryClient({'url': SCHEMA_REGISTRY_URL})
# Avro deserileştirici
# Şemayı doğrudan string olarak vermek yerine, Schema Registry'den ID ile otomatik olarak alacaktır.
avro_deserializer = AvroDeserializer(schema_registry_client)
# Tüketici yapılandırması
consumer_conf = {
'bootstrap.servers': KAFKA_BROKER,
'key.deserializer': StringDeserializer('utf_8'),
'value.deserializer': avro_deserializer,
'group.id': GROUP_ID,
'auto.offset.reset': 'earliest' # En baştan okumaya başla
# Eğer Managed Kafka kullanıyorsanız SSL/SASL ayarları
# 'security.protocol': 'SASL_SSL',
# 'sasl.mechanism': 'PLAIN',
# 'sasl.username': 'your_username',
# 'sasl.password': 'your_password',
# 'ssl.ca.location': '/path/to/your/ca-cert.pem'
}
consumer = DeserializingConsumer(consumer_conf)
consumer.subscribe([TOPIC])
try:
while True:
msg = consumer.poll(timeout=1.0) # 1 saniye bekle
if msg is None:
continue
if msg.error():
print(f"Tüketici hatası: {msg.error()}")
continue
key = msg.key()
value = msg.value()
print(f"Alınan Mesaj - Anahtar: {key}, Değer: {value}")
except KeyboardInterrupt:
pass
finally:
consumer.close()
Bu örneklerde, AvroSerializer ve AvroDeserializer, Schema Registry ile otomatik olarak etkileşime girerek şema kaydını ve doğrulamayı gerçekleştirir. Üretici, mesajı Avro formatında serileştirip Kafka’ya gönderirken, mesajın başlığına (header) şema kimliğini ekler. Tüketici ise bu şema kimliğini okuyarak Schema Registry’den ilgili şemayı alır ve mesajı doğru bir şekilde deserileştirir.
Şema Evrimi ve Uyumluluk Modları: Veri Bütünlüğünü Koruma Sanatı
Uygulamalar geliştikçe, kullandıkları veri şemaları da kaçınılmaz olarak değişir. Yeni alanlar eklenmesi, mevcut alanların kaldırılması veya veri tiplerinin değiştirilmesi gibi durumlar sıkça karşılaşılan senaryolardır. Schema Registry, bu şema evrimini “uyumluluk modları” adı verilen kurallar dizisiyle yöneterek veri bütünlüğünü sağlar ve servisler arasında kesintisiz iletişimi garanti eder.
Uyumluluk modları, yeni bir şema versiyonunun eski versiyonlarla ne kadar uyumlu olduğunu belirler. Bu, özellikle farklı zamanlarda dağıtılmış servislerin aynı Kafka konusundaki mesajları sorunsuz bir şekilde işleyebilmesi için kritik öneme sahiptir. Schema Registry, her konu (subject) için ayrı ayrı veya global olarak bir uyumluluk modu ayarlanmasına izin verir.
Başlıca Uyumluluk Modları
Schema Registry’nin sunduğu başlıca uyumluluk modları şunlardır:
- BACKWARD (Geriye Uyumlu): Yeni şema, eski şema tarafından üretilen veriyi okuyabilir. Yani, yeni bir tüketici eski bir üreticinin mesajını işleyebilir. Bu, genellikle yeni isteğe bağlı alanlar eklediğinizde veya mevcut alanları kaldırdığınızda (eğer varsayılan değerleri varsa) kullanılır.
Senaryo: Eski bir alanı kaldırdınız, ancak eski üreticiler hala o alanı içeren mesajlar gönderiyor. Yeni tüketiciler bu alanı görmezden gelerek eski mesajları işleyebilir. - FORWARD (İleri Uyumlu): Eski şema, yeni şema tarafından üretilen veriyi okuyabilir. Yani, eski bir tüketici yeni bir üreticinin mesajını işleyebilir. Bu, genellikle yeni zorunlu alanlar eklediğinizde (ancak eski tüketicilerin bu alanları görmezden gelebileceği şekilde) kullanılır.
Senaryo: Yeni bir zorunlu alan eklediniz, ancak eski tüketiciler bu alanı bilmiyor. Eski tüketiciler, yeni üreticilerin mesajlarını, bilmedikleri alanı atlayarak işleyebilir. - FULL (Tam Uyumlu): Hem geriye hem de ileriye uyumludur. Yeni şema eski veriyi okuyabilir ve eski şema yeni veriyi okuyabilir. Bu en kısıtlayıcı moddur ve genellikle sadece isteğe bağlı alanların varsayılan değerlerle eklenmesi gibi çok küçük değişikliklere izin verir.
- NONE (Uyumsuz): Şema evrimi kontrolü yapılmaz. Herhangi bir şema değişikliğine izin verilir. Bu mod, dikkatli kullanılmalı ve genellikle geliştirme veya test ortamları için ayrılmalıdır, çünkü veri uyumsuzluklarına yol açabilir.
- TRANSITIVE Modlar:
BACKWARD_TRANSITIVE,FORWARD_TRANSITIVE,FULL_TRANSITIVEmodları, uyumluluğu sadece bir önceki versiyonla değil, tüm önceki versiyonlarla kontrol eder. Bu, daha katı bir uyumluluk denetimi sağlar ve uzun vadeli şema evrimi için daha güvenlidir.
Uyumluluk Modunu Ayarlama
Bir konunun uyumluluk modunu ayarlamak için Schema Registry API’sini kullanırız:
# user-registered-value konusu için geriye uyumluluğu ayarla
curl -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"compatibility": "BACKWARD"}' \
http://your_droplet_ip:8081/config/user-registered-value
Mevcut uyumluluk modunu kontrol etmek için:
curl -X GET http://your_droplet_ip:8081/config/user-registered-value
Gerçek Dünya Senaryosu: Yeni Alan Ekleme
Diyelim ki UserRegistered şemamıza yeni bir alan, registrationDate, eklemek istiyoruz. Bu alanın isteğe bağlı olmasını ve varsayılan bir değeri olmasını istiyoruz. Bu durumda BACKWARD uyumluluk modu idealdir, çünkü eski tüketiciler bu yeni alanı bilmedikleri için görmezden gelebilirler.
Yeni şema (user-registered-v2.avsc):
{
"type": "record",
"name": "UserRegistered",
"namespace": "com.example.events",
"fields": [
{"name": "id", "type": "string"},
{"name": "firstName", "type": "string"},
{"name": "lastName", "type": "string"},
{"name": "email", "type": ["null", "string"], "default": null},
{"name": "registrationDate", "type": ["null", "string"], "default": null} # Yeni alan
]
}
Bu şemayı kaydedelim:
curl -X POST -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "$(cat user-registered-v2.avsc)"}' \
http://your_droplet_ip:8081/subjects/user-registered-value/versions
Eğer uyumluluk modu BACKWARD olarak ayarlandıysa, Schema Registry bu yeni şemayı kabul edecektir. Artık yeni üreticiler registrationDate alanını içeren mesajlar gönderebilirken, eski tüketiciler bu mesajları hala başarılı bir şekilde işleyebilir (registrationDate alanını görmezden gelerek). Bu, sisteminizde kesintiye neden olmadan şema evrimini yönetmenin gücünü gösterir.
BACKWARD veya FULL_TRANSITIVE modları, üretim ortamlarında en güvenli seçeneklerdir. Şema değişikliklerini küçük ve artımlı tutmak, uyumluluk sorunlarını minimize etmenin anahtarıdır.
Performans ve Güvenlik İpuçları: Üretim Ortamları İçin Neler Yapmalıyız?
Kafka Schema Registry’yi DigitalOcean üzerinde üretim ortamında kullanırken performans, güvenlik ve yüksek erişilebilirlik konuları büyük önem taşır. Bu bölümde, sisteminizin sağlam ve güvenilir olmasını sağlamak için bazı ileri düzey ipuçlarını ve en iyi uygulamaları ele alacağız.
Performans Optimizasyonu
- Donanım Kaynakları: Schema Registry’nin çalıştığı Droplet’in yeterli CPU, RAM ve disk kaynaklarına sahip olduğundan emin olun. Özellikle yüksek hacimli şema kayıt ve sorgulama işlemleri bekliyorsanız, kaynakları buna göre ölçeklendirin.
- Ağ Gecikmesi: Schema Registry’nin Kafka broker’larına ve uygulamalarınıza (üretici/tüketici) yakın coğrafi konumlarda olmasını sağlayın. DigitalOcean’da aynı veri merkezi içindeki Droplet’ler ve Managed Kafka kümeleri arasında düşük gecikme sağlanır.
- Önbellekleme (Caching): Schema Registry, şemaları önbelleğe alır. Varsayılan ayarlarla çoğu senaryo için yeterli performans sunar. Ancak çok yüksek yük altında, istemci tarafında da şema önbelleklemesi yaparak Schema Registry’ye yapılan istek sayısını azaltabilirsiniz.
- Sürümleme ve Temizleme: Zamanla birçok şema versiyonu birikebilir. Gereksiz veya kullanılmayan eski şema versiyonlarını temizlemek, Schema Registry’nin disk kullanımını ve performansını artırabilir. Ancak bu işlemi yaparken dikkatli olun ve uyumluluk gereksinimlerini göz önünde bulundurun.
Güvenlik Önlemleri
- Ağ İzolasyonu (VPC): Schema Registry Droplet’inizi DigitalOcean VPC (Virtual Private Cloud) ağına dahil edin. Bu, Schema Registry ile Kafka broker’ları ve uygulamalarınız arasındaki iletişimin özel bir ağ üzerinden yapılmasını sağlar ve dışarıdan erişimi kısıtlar. Public IP yerine Private IP kullanın.
- Güvenlik Duvarı (Firewall): Droplet’inizin güvenlik duvarını (DigitalOcean Firewall veya UFW) yapılandırarak sadece belirli IP adreslerinden veya VPC içindeki diğer Droplet’lerden Schema Registry’nin 8081 portuna erişime izin verin.
# Sadece belirli bir IP'den 8081 portuna erişime izin ver sudo ufw allow from your_trusted_ip to any port 8081 # VPC içinden erişime izin ver (örnek: 10.0.0.0/16 aralığı) sudo ufw allow from 10.0.0.0/16 to any port 8081 sudo ufw enable - SSL/TLS Şifrelemesi: Schema Registry ile istemciler (üreticiler/tüketiciler) arasındaki iletişimi SSL/TLS ile şifreleyin. Bu, verilerin ağ üzerinde şifreli olarak iletilmesini sağlar. Schema Registry’nin kendi SSL/TLS ayarları mevcuttur. Ayrıca, Schema Registry’nin Kafka ile olan iletişimi için de SSL/TLS yapılandırması yapın (
SCHEMA_REGISTRY_KAFKASTORE_SECURITY_PROTOCOL: SSLgibi). - Kimlik Doğrulama ve Yetkilendirme (Authentication & Authorization): Schema Registry’nin kendisi yerleşik bir kimlik doğrulama/yetkilendirme mekanizmasına sahip değildir. Ancak önünde bir ters proxy (Nginx gibi) kullanarak temel HTTP kimlik doğrulaması veya daha gelişmiş mekanizmalar (OAuth2 gibi) uygulayabilirsiniz. Ayrıca, Schema Registry’nin Kafka’ya bağlanırken kimlik doğrulaması (örneğin SASL) yapmasını sağlayın.
# Schema Registry'nin Kafka'ya SASL_SSL ile bağlanması için docker-compose.yml'de örnek environment: SCHEMA_REGISTRY_KAFKASTORE_SECURITY_PROTOCOL: SASL_SSL SCHEMA_REGISTRY_KAFKASTORE_SASL_MECHANISM: PLAIN SCHEMA_REGISTRY_KAFKASTORE_SASL_JAAS_CONFIG: "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"your_kafka_username\" password=\"your_kafka_password\";"
Yüksek Erişilebilirlik
Üretim ortamlarında Schema Registry’nin tek bir hata noktası olmaması önemlidir. Yüksek erişilebilirlik için:
- Birden Fazla Schema Registry Örneği: Birden fazla Droplet üzerinde Schema Registry örneği çalıştırın. Schema Registry, Kafka’yı bir koordinasyon ve depolama katmanı olarak kullandığı için, birden fazla örneği aynı Kafka kümesine işaret ederek yüksek erişilebilirlik sağlayabilir. Bir yük dengeleyici (DigitalOcean Load Balancer gibi) kullanarak gelen istekleri bu örnekler arasında dağıtabilirsiniz.
- Otomatik Kurtarma: Droplet’lerinizin sağlığını izleyin ve bir hata durumunda otomatik olarak yeniden başlatılmasını veya yeni bir Droplet üzerinde Schema Registry’nin dağıtılmasını sağlayacak araçlar (örneğin, Kubernetes ile konteyner orkestrasyonu) kullanın.
Bu ipuçlarını uygulayarak, DigitalOcean üzerinde dağıttığınız Kafka Schema Registry çözümünüzün hem güvenli hem de yüksek performanslı olmasını sağlayabilir, böylece veri akışınızın kesintisiz ve tutarlı kalmasını garanti edebilirsiniz.
Vaka Analizi: E-ticaret Uygulamasında Sipariş Verilerinin Yönetimi
Bir e-ticaret platformu düşünelim. Bu platformda “Sipariş Oluşturma”, “Ödeme İşleme”, “Stok Yönetimi” ve “Kargo Takibi” gibi farklı mikroservisler bulunuyor. Bu servisler, siparişlerle ilgili olayları (events) Kafka üzerinden birbirleriyle paylaşıyorlar. Başlangıçta, sipariş verileri basit bir JSON formatında gönderiliyordu. Ancak zamanla, iş gereksinimleri değiştikçe ve yeni özellikler eklendikçe, veri şemalarında sorunlar ortaya çıkmaya başladı.
Başlangıçtaki Problemler
- Veri Uyumsuzlukları: “Sipariş Oluşturma” servisi, yeni bir alan (örneğin,
couponCode) eklediğinde, “Stok Yönetimi” servisi hala eski şemayı beklediği için hata veriyordu. Tersine, “Kargo Takibi” servisi eski bir versiyonu kullanırken, “Ödeme İşleme” servisi yeni bir alanla (paymentMethod) mesaj gönderdiğinde, “Kargo Takibi” servisi bu mesajları doğru bir şekilde işleyemiyordu. - Geliştirme Yavaşlığı: Her şema değişikliğinde, ilgili tüm servislerin güncellenmesi ve eş zamanlı olarak dağıtılması gerekiyordu. Bu durum, dağıtım süreçlerini karmaşıklaştırıyor ve yeni özelliklerin piyasaya sürülmesini geciktiriyordu.
- Hata Ayıklama Zorluğu: Hangi servisin hangi şema versiyonunu kullandığını takip etmek zorlaşıyordu. Üretim ortamındaki hataların kök nedenini bulmak zaman alıcıydı.
Kafka Schema Registry ile Çözüm
E-ticaret ekibi, bu sorunları çözmek için Kafka Schema Registry’yi DigitalOcean üzerindeki Managed Kafka kümesiyle birlikte kullanmaya karar verdi. Schema Registry’yi ayrı bir Droplet üzerine Docker Compose ile kurdular ve tüm siparişle ilgili konular için (order-created, payment-processed vb.) şemaları Avro formatında tanımladılar.
Uygulama Adımları:
- Şema Tanımlama: Her olay (event) için ayrı bir Avro şeması oluşturdular. Örneğin,
order-created.avscşeması başlangıçta şu alanları içeriyordu:orderId,userId,items(ürün listesi),totalAmount. - Schema Registry’ye Kayıt: Tüm şemalar, Schema Registry’ye
<topic_adı>-valueformatında kaydedildi. Örneğin,order-created-value. - Uyumluluk Modu Ayarı: Tüm konular için uyumluluk modu
BACKWARD_TRANSITIVEolarak ayarlandı. Bu, yeni tüketicilerin eski üreticilerin verilerini okuyabilmesini garanti altına alıyordu. - Servis Entegrasyonu: Her mikroservis, Confluent’in Kafka istemci kütüphanelerini kullanarak Schema Registry ile entegre edildi. Üreticiler, mesajları göndermeden önce şemaya uygunluğunu kontrol ediyor, tüketiciler ise mesajları otomatik olarak doğru şemayla deserileştiriyordu.
Sonuçlar ve Faydalar:
- Kesintisiz Şema Evrimi: “Sipariş Oluşturma” servisi,
couponCodealanını eklemek istediğinde, şemayı güncelleyip Schema Registry’ye yeni bir versiyon olarak kaydetti.BACKWARD_TRANSITIVEmodu sayesinde, yeni üreticiler yeni alanı içeren mesajlar gönderirken, “Stok Yönetimi” gibi eski tüketiciler hala eski şemayı kullanarak çalışmaya devam etti. Eski tüketiciler, bilmediklericouponCodealanını güvenle görmezden geldi. - Hızlı Geliştirme ve Dağıtım: Şema değişiklikleri artık tüm servislerin eş zamanlı olarak dağıtılmasını gerektirmiyordu. Servisler birbirinden bağımsız olarak güncellenebiliyordu, bu da geliştirme hızını artırdı.
- Azalan Hata Oranı: Schema Registry, hatalı formatta mesajların Kafka’ya ulaşmasını engelleyerek veri uyumsuzluklarından kaynaklanan hataları önemli ölçüde azalttı. Veri kalitesi arttı.
- Merkezi Veri Yönetimi: Tüm şemaların merkezi bir yerde bulunması, geliştiricilerin veri yapılarını daha kolay anlamasını ve yönetmesini sağladı. Yeni bir geliştirici ekibe katıldığında, mevcut veri modellerini hızla öğrenebildi.
Bu vaka analizi, Kafka Schema Registry’nin e-ticaret gibi dinamik ve veri yoğun uygulamalarda veri tutarlılığını ve şema evrimini yönetmek için ne kadar değerli bir araç olduğunu açıkça göstermektedir. DigitalOcean’ın esnek altyapısı üzerinde bu tür bir çözüm kurmak, işletmelere çeviklik ve güvenilirlik sağlar.
Sonuç
Modern dağıtık sistemlerin karmaşıklığı içinde veri tutarlılığı, bir lüks olmaktan çıkıp temel bir gereklilik haline gelmiştir. Bu makale boyunca, DigitalOcean üzerinde Kafka Schema Registry’nin nasıl kurulacağını, yapılandırılacağını ve kullanılacağını adım adım inceledik. Kafka Schema Registry’nin, Avro gibi güçlü serileştirme formatlarıyla birlikte, veri şemalarınızın evrimini yönetmek, veri uyumsuzluklarını önlemek ve mikroservisler arasında güvenilir bir iletişim katmanı oluşturmak için ne kadar kritik bir araç olduğunu gördük. Uygulamalı Python örnekleri ve e-ticaret vaka analizi ile, Schema Registry’nin gerçek dünya senaryolarında nasıl değer yarattığını somutlaştırdık.
DigitalOcean’ın esnek ve ölçeklenebilir altyapısı üzerinde Schema Registry’yi konumlandırmak, operasyonel yükü yönetilebilir kılarken, uygulamanızın veri kalitesini ve güvenilirliğini artırmanıza olanak tanır. İster yeni bir proje başlatıyor olun ister mevcut bir Kafka altyapınızı güçlendirmek isteyin, Schema Registry’yi entegre etmek, veri yönetim stratejinizin vazgeçilmez bir parçası olmalıdır. Böylece, veri uyumsuzlukları nedeniyle ortaya çıkabilecek potansiyel sorunları proaktif bir şekilde ortadan kaldırabilir, geliştirme süreçlerinizi hızlandırabilir ve iş akışlarınızın kesintisizliğini sağlayabilirsiniz.
Sıkça Sorulan Sorular
1. Kafka Schema Registry olmadan Kafka kullanabilir miyim?
Evet, kullanabilirsiniz. Ancak Schema Registry olmadan, mesaj şemalarının yönetimi ve uyumluluğu tamamen sizin sorumluluğunuzda olur. Bu durum, özellikle mikroservis tabanlı ve farklı dillerde yazılmış uygulamaların olduğu büyük sistemlerde veri uyumsuzluklarına, hata ayıklama zorluklarına ve geliştirme yavaşlığına yol açabilir. Schema Registry, bu sorunları çözmek için tasarlanmıştır.
2. Schema Registry sadece Avro ile mi çalışır?
Hayır, Schema Registry sadece Avro ile sınırlı değildir. Confluent Schema Registry, Avro’nun yanı sıra Protobuf (Protocol Buffers) ve JSON Schema gibi diğer popüler serileştirme formatlarını da destekler. Hangi formatı seçeceğiniz, projenizin gereksinimlerine ve tercihlerinize bağlıdır.
3. DigitalOcean Managed Kafka hizmeti Schema Registry’yi içeriyor mu?
Hayır, DigitalOcean Managed Kafka hizmeti şu anda Schema Registry’yi doğrudan içermemektedir. Schema Registry’yi ayrı bir Droplet üzerine (genellikle Docker Compose kullanarak) kurmanız ve Managed Kafka kümenize bağlamanız gerekmektedir. Bu makalede anlatılan kurulum adımları bu senaryoyu kapsamaktadır.
4. Şema evrimi sırasında geriye uyumluluğu sağlamak neden önemlidir?
Geriye uyumluluk, yeni bir şema versiyonunun, önceki şema versiyonlarıyla üretilmiş veriyi hala okuyup işleyebilmesini sağlar. Bu, özellikle tüketicilerin her zaman en güncel şemayı kullanmadığı veya aynı anda güncellenemediği dağıtık sistemlerde kritik öneme sahiptir. Geriye uyumluluk sayesinde, eski tüketiciler yeni üreticilerin mesajlarını sorunsuz bir şekilde işleyebilir ve sistemin kesintisiz çalışmaya devam etmesi sağlanır.
5. Schema Registry’nin üretim ortamında yüksek erişilebilirliğini nasıl sağlarım?
Üretim ortamında yüksek erişilebilirlik için birden fazla Schema Registry örneğini farklı Droplet’ler üzerinde çalıştırmalısınız. Schema Registry, şemaları Kafka’da depoladığı için, birden fazla örneği aynı Kafka kümesine bağlayarak pasif-pasif veya aktif-pasif bir yapı oluşturabilirsiniz. Gelen istekleri bu örneklere dağıtmak için DigitalOcean Load Balancer gibi bir yük dengeleyici kullanmak, sisteminizin tek bir hata noktasını ortadan kaldıracaktır.
