AWS DynamoDB Global Tables Yapılandırması ve Yönetimi

Global uygulamalar geliştirirken en büyük baş ağrılarından biri veritabanı replikasyonunu doğru kurmak. Özellikle düşük gecikme süresi gerektiren, birden fazla coğrafi bölgede çalışan sistemlerde bu iş ciddi bir mimari karar haline geliyor. AWS DynamoDB Global Tables tam da bu noktada devreye giriyor: tamamen yönetilen, çok bölgeli, aktif-aktif bir replikasyon çözümü. Tek bir satır replikasyon kodu yazmadan, iki veya daha fazla AWS bölgesinde verilerinizi senkron tutabiliyorsunuz. Bu yazıda DynamoDB Global Tables’ı sıfırdan yapılandırmayı, yönetmeyi ve gerçek dünya senaryolarında nasıl kullanacağınızı detaylıca ele alacağız.

DynamoDB Global Tables Nedir ve Ne Zaman Kullanılır

DynamoDB Global Tables, aynı tablonun birden fazla AWS bölgesinde eş zamanlı olarak yazılabilir ve okunabilir replikalara sahip olmasını sağlar. Bu özellik özellikle şu senaryolarda hayat kurtarıcı:

  • Global e-ticaret platformları: Avrupa’daki kullanıcı Amsterdam’daki region’dan, Asya’daki kullanıcı Tokyo’daki region’dan okuma/yazma yapıyor
  • Oyun uygulamaları: Oyuncu skorlarının dünya genelinde anlık senkronizasyonu
  • SaaS uygulamaları: GDPR gibi veri yerelleştirme gereksinimlerini karşılarken yüksek performans sağlamak
  • Felaket kurtarma: Bir bölge tamamen çöktüğünde diğer bölgeden otomatik devam

Global Tables’ın çalışma mantığı şu şekilde: Her bölge kendi DynamoDB tablosunu yönetir, AWS arka planda DynamoDB Streams kullanarak değişiklikleri tüm bölgelere replike eder. Replikasyon genellikle 1-2 saniye içinde tamamlanır, bu da eventual consistency modeli anlamına gelir. Eğer iki farklı bölgede aynı öğeye aynı anda yazma yapılırsa, “last writer wins” prensibi uygulanır.

Ön Gereksinimler

Global Tables yapılandırmasına geçmeden önce bazı ön koşulları sağlamanız gerekiyor:

  • Tablonun her bölgede oluşturulmuş olması (ya da Global Tables özelliği açılmadan önce boş olması)
  • DynamoDB Streams’in NEW_AND_OLD_IMAGES modunda aktif olması
  • Tablonun on-demand kapasitede ya da auto-scaling yapılandırılmış provisioned kapasitede olması
  • Tüm bölgelerde aynı partition key ve sort key yapısının kullanılması
  • IAM izinlerinin doğru yapılandırılmış olması

AWS CLI’nin kurulu ve yapılandırılmış olduğunu varsayıyorum. Değilse önce şunu çalıştırın:

# AWS CLI versiyon kontrolü
aws --version

# Hangi bölge için yapılandırılmış kontrol et
aws configure list

# Profil bilgilerini göster
aws sts get-caller-identity

Yeni Bir Global Table Oluşturma

En temiz yol, tabloyu direkt Global Table olarak oluşturmak. Bu yaklaşımda DynamoDB otomatik olarak tüm bölgelerde gerekli yapıyı kurar.

# us-east-1 bölgesinde Global Table oluştur
# eu-west-1 ve ap-northeast-1 bölgelerini replica olarak ekle
aws dynamodb create-table 
  --table-name UserSessions 
  --attribute-definitions 
    AttributeName=userId,AttributeType=S 
    AttributeName=sessionId,AttributeType=S 
  --key-schema 
    AttributeName=userId,KeyType=HASH 
    AttributeName=sessionId,KeyType=RANGE 
  --billing-mode PAY_PER_REQUEST 
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES 
  --replica-updates 
    '[{"Create":{"RegionName":"eu-west-1"}},{"Create":{"RegionName":"ap-northeast-1"}}]' 
  --region us-east-1

Bu komut çalıştırıldıktan sonra tablo oluşturma süreci başlar. Üç bölge için de tablolar oluşturulur ve replikasyon bağlantıları kurulur. Bu işlem genellikle birkaç dakika sürer.

Tablonun durumunu izlemek için:

# Tablo durumunu kontrol et
aws dynamodb describe-table 
  --table-name UserSessions 
  --region us-east-1 
  --query 'Table.{Status:TableStatus,Replicas:Replicas[*].{Region:RegionName,Status:ReplicaStatus}}'

Çıktı şöyle görünmeli:

{
  "Status": "ACTIVE",
  "Replicas": [
    {
      "Region": "eu-west-1",
      "Status": "ACTIVE"
    },
    {
      "Region": "ap-northeast-1",
      "Status": "ACTIVE"
    }
  ]
}

Mevcut Bir Tabloyu Global Table’a Dönüştürme

Daha yaygın senaryo şu: Zaten üretimde çalışan bir DynamoDB tablonuz var ve bunu Global Table’a çevirmek istiyorsunuz. Bu durumda önce Streams’i aktif etmeniz gerekiyor.

# Önce mevcut tabloda DynamoDB Streams aç
aws dynamodb update-table 
  --table-name ProductCatalog 
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES 
  --region us-east-1

# Streams'in aktif olduğunu doğrula
aws dynamodb describe-table 
  --table-name ProductCatalog 
  --region us-east-1 
  --query 'Table.StreamSpecification'

Streams aktif olduktan sonra replica bölgeler ekleyebilirsiniz. Dikkat: Bu adımda mevcut veriler de yeni bölgeye kopyalanır, tablo boyutuna göre bu işlem uzun sürebilir.

# eu-central-1 bölgesini replica olarak ekle
aws dynamodb update-table 
  --table-name ProductCatalog 
  --replica-updates 
    '[{"Create":{"RegionName":"eu-central-1"}}]' 
  --region us-east-1

# Replikasyon durumunu izle (birkaç dakika bekle)
watch -n 10 "aws dynamodb describe-table 
  --table-name ProductCatalog 
  --region us-east-1 
  --query 'Table.Replicas'"

Auto-Scaling Yapılandırması

Global Tables ile provisioned kapasite kullanıyorsanız, her bölge için ayrı ayrı auto-scaling yapılandırmanız gerekiyor. Bu kritik bir nokta; bir bölgede kapasite artırırsanız diğer bölgeler otomatik artmaz.

# us-east-1 için auto-scaling politikası kaydet
aws application-autoscaling register-scalable-target 
  --service-namespace dynamodb 
  --resource-id "table/UserSessions" 
  --scalable-dimension "dynamodb:table:WriteCapacityUnits" 
  --min-capacity 5 
  --max-capacity 1000 
  --region us-east-1

# Scaling politikasını tanımla
aws application-autoscaling put-scaling-policy 
  --service-namespace dynamodb 
  --resource-id "table/UserSessions" 
  --scalable-dimension "dynamodb:table:WriteCapacityUnits" 
  --policy-name "UserSessionsWriteScaling" 
  --policy-type TargetTrackingScaling 
  --target-tracking-scaling-policy-configuration 
    '{
      "TargetValue": 70.0,
      "PredefinedMetricSpecification": {
        "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
      },
      "ScaleInCooldown": 60,
      "ScaleOutCooldown": 60
    }' 
  --region us-east-1

# Aynı yapılandırmayı eu-west-1 için de uygula
aws application-autoscaling register-scalable-target 
  --service-namespace dynamodb 
  --resource-id "table/UserSessions" 
  --scalable-dimension "dynamodb:table:WriteCapacityUnits" 
  --min-capacity 5 
  --max-capacity 1000 
  --region eu-west-1

PAY_PER_REQUEST modunda bu adımları atlamanız gerekmez, AWS otomatik ölçeklendirme yapar. Ancak maliyet öngörülebilirliği istiyorsanız provisioned mod tercih edilebilir.

Global Secondary Index Yönetimi

GSI’ları Global Tables ile kullanmak biraz dikkat istiyor. Global Table’a yeni bir GSI eklediğinizde, bu değişiklik otomatik olarak tüm replica bölgelere yayılır. Ancak bu süreçte tablo performansı etkilenebilir.

# Mevcut Global Table'a yeni GSI ekle
aws dynamodb update-table 
  --table-name UserSessions 
  --attribute-definitions 
    AttributeName=userId,AttributeType=S 
    AttributeName=sessionId,AttributeType=S 
    AttributeName=createdAt,AttributeType=S 
  --global-secondary-index-updates 
    '[{
      "Create": {
        "IndexName": "CreatedAt-Index",
        "KeySchema": [
          {"AttributeName": "userId", "KeyType": "HASH"},
          {"AttributeName": "createdAt", "KeyType": "RANGE"}
        ],
        "Projection": {
          "ProjectionType": "ALL"
        },
        "ProvisionedThroughput": {
          "ReadCapacityUnits": 5,
          "WriteCapacityUnits": 5
        }
      }
    }]' 
  --region us-east-1

# GSI oluşturma durumunu izle
aws dynamodb describe-table 
  --table-name UserSessions 
  --region us-east-1 
  --query 'Table.GlobalSecondaryIndexes[*].{Name:IndexName,Status:IndexStatus}'

GSI oluşturma tamamlandıktan sonra diğer bölgelerde de otomatik görünmesini birkaç dakika beklemeniz gerekebilir.

Okuma/Yazma İşlemlerinde Bölge Seçimi

Uygulamanızı Global Tables’a uyarlarken en önemli tasarım kararı hangi bölgeden okuyup hangi bölgeye yazacağınız. En iyi pratik, her zaman kullanıcıya en yakın bölgeye yönlendirmek.

# Python boto3 ile bölge bazlı bağlantı örneği
import boto3
from geolite2 import geolite2

def get_dynamodb_client(user_ip):
    reader = geolite2.reader()
    match = reader.get(user_ip)
    
    if match:
        country = match.get('country', {}).get('iso_code', 'US')
        
        region_map = {
            'DE': 'eu-central-1',
            'FR': 'eu-west-3',
            'GB': 'eu-west-2',
            'JP': 'ap-northeast-1',
            'SG': 'ap-southeast-1',
            'AU': 'ap-southeast-2',
        }
        
        region = region_map.get(country, 'us-east-1')
    else:
        region = 'us-east-1'
    
    return boto3.resource('dynamodb', region_name=region)

# Kullanım
dynamodb = get_dynamodb_client('81.169.145.100')  # Almanya IP
table = dynamodb.Table('UserSessions')

# Yazma işlemi - en yakın bölgeye yaz
table.put_item(
    Item={
        'userId': 'user123',
        'sessionId': 'sess456',
        'createdAt': '2024-01-15T10:30:00Z',
        'data': {'browser': 'Chrome', 'os': 'Linux'}
    }
)

Conflict Resolution ve Conditional Writes

Global Tables’ın “last writer wins” mekanizması çoğu senaryo için yeterli, ancak kritik verilerde conflict’leri önlemek için conditional writes kullanın:

# CLI ile conditional write örneği
# Stok sayacını atomik olarak güncelle
aws dynamodb update-item 
  --table-name ProductCatalog 
  --key '{"productId": {"S": "PROD-001"}}' 
  --update-expression "SET stockCount = stockCount - :decrease" 
  --condition-expression "stockCount >= :decrease AND stockCount > :zero" 
  --expression-attribute-values 
    '{":decrease": {"N": "1"}, ":zero": {"N": "0"}}' 
  --return-values ALL_NEW 
  --region eu-central-1

Bu örnekte stok 0’ın altına düşmesi engelleniyor. Conditional write başarısız olursa ConditionalCheckFailedException fırlatır, uygulamanız bunu yakalayıp kullanıcıya uygun mesaj verebilir.

CloudWatch ile İzleme ve Alarm Kurulumu

Global Tables’ı üretime aldıktan sonra her bölge için izleme kurmanız şart. Replikasyon gecikmesini özellikle takip edin.

# Replikasyon gecikmesi için CloudWatch alarmı kur
aws cloudwatch put-metric-alarm 
  --alarm-name "DynamoDB-GlobalTable-ReplicationLatency-High" 
  --alarm-description "UserSessions tablosu replikasyon gecikmesi 10 saniyi astı" 
  --metric-name "ReplicationLatency" 
  --namespace "AWS/DynamoDB" 
  --statistic Maximum 
  --dimensions 
    Name=TableName,Value=UserSessions 
    Name=ReceivingRegion,Value=eu-west-1 
  --period 60 
  --evaluation-periods 3 
  --threshold 10000 
  --comparison-operator GreaterThanThreshold 
  --alarm-actions "arn:aws:sns:us-east-1:123456789012:ops-alerts" 
  --region us-east-1

# Throttle metriği için alarm
aws cloudwatch put-metric-alarm 
  --alarm-name "DynamoDB-UserSessions-WriteThrottle" 
  --metric-name "WriteThrottleEvents" 
  --namespace "AWS/DynamoDB" 
  --statistic Sum 
  --dimensions Name=TableName,Value=UserSessions 
  --period 60 
  --evaluation-periods 2 
  --threshold 10 
  --comparison-operator GreaterThanThreshold 
  --alarm-actions "arn:aws:sns:us-east-1:123456789012:ops-alerts" 
  --region eu-west-1

Takip etmeniz gereken başlıca metrikler:

  • ReplicationLatency: Replikasyon gecikmesi, 10 saniyenin altında olmalı
  • PendingReplicationCount: Bekleyen replikasyon işlem sayısı, ani artışlar sorun işareti
  • WriteThrottleEvents: Yazma throttle olayları
  • ReadThrottleEvents: Okuma throttle olayları
  • SystemErrors: Sistem hataları, sıfır olmalı
  • ConsumedWriteCapacityUnits: Gerçek kullanılan yazma kapasitesi

Felaket Kurtarma Senaryosu

Diyelim ki us-east-1 bölgesi tamamen devre dışı kaldı. Global Tables sayesinde verileriniz eu-west-1’de zaten mevcut. Yapmanız gereken sadece uygulamanızı yeni bölgeye yönlendirmek:

# Bölge sağlık durumunu kontrol et
aws dynamodb describe-table 
  --table-name UserSessions 
  --region eu-west-1 
  --query 'Table.{Status:TableStatus,ItemCount:ItemCount}'

# Route 53 üzerinden trafik yönlendirme değişikliği
# (Bu örnekte health check tabanlı failover varsayılıyor)
aws route53 change-resource-record-sets 
  --hosted-zone-id Z1234567890ABC 
  --change-batch 
    '{
      "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
          "Name": "api.myapp.com",
          "Type": "A",
          "AliasTarget": {
            "HostedZoneId": "Z35SXDOTRQ7X7K",
            "DNSName": "eu-west-1-alb.amazonaws.com",
            "EvaluateTargetHealth": true
          }
        }
      }]
    }'

Gerçek bir felaket kurtarma senaryosunda uygulamanız Route 53 health check’leri ile otomatik failover yapacak şekilde yapılandırılmış olmalı. Global Tables bu noktada size RPO (Recovery Point Objective) sıfır, RTO (Recovery Time Objective) ise saniyeler mertebesinde sunar.

Terraform ile Global Tables Yönetimi

Prodüksiyon ortamlarında manuel CLI komutları yerine Infrastructure as Code kullanın. Basit bir Terraform örneği:

# main.tf içeriğini terraform apply ile uygula
# Önce workspace'i doğrula
terraform workspace show

# Değişkenleri kontrol et
terraform plan 
  -var="primary_region=us-east-1" 
  -var="replica_regions=["eu-west-1","ap-northeast-1"]" 
  -var="table_name=UserSessions" 
  -out=global-tables.tfplan

# Planı uygula
terraform apply global-tables.tfplan

# State'i doğrula
terraform state list | grep dynamodb

Terraform’un aws_dynamodb_table kaynağı replica bloğunu destekler ve değişiklik yönetimini çok kolaylaştırır. Özellikle çok bölgeli ortamlarda manuel yapılandırma hatalarını önlemek açısından Terraform veya AWS CDK şiddetle tavsiye edilir.

Maliyet Optimizasyonu

Global Tables kullanırken maliyet, tek bölgeli DynamoDB’ye kıyasla belirgin şekilde artar. Ana maliyet bileşenleri:

  • Replicated Write Request Units (rWRU): Her yazma işlemi, replica bölge başına ek ücret getirir. 2 replica varsa her yazma 3x maliyete sahip
  • Depolama: Her bölge için ayrı depolama ücreti ödenir
  • Veri transferi: Bölgeler arası replikasyon için veri transferi ücreti

Maliyet optimizasyonu için:

  • Sık değişmeyen referans veriler için Global Tables yerine uygulama katmanında önbellekleme düşünün
  • Yazma yoğun tablolarda gerçekten multi-region yazma ihtiyacınız olup olmadığını sorgulayın
  • TTL (Time to Live) özelliğini kullanarak gereksiz veriyi otomatik temizleyin
  • CloudWatch Cost Explorer ile bölge bazlı maliyetleri düzenli takip edin
# TTL özelliğini etkinleştir
aws dynamodb update-time-to-live 
  --table-name UserSessions 
  --time-to-live-specification 
    "Enabled=true, AttributeName=expiresAt" 
  --region us-east-1

# TTL durumunu kontrol et (tüm bölgelerde otomatik aktif olur)
aws dynamodb describe-time-to-live 
  --table-name UserSessions 
  --region eu-west-1

Sık Karşılaşılan Sorunlar ve Çözümleri

Replikasyon durdu, PendingReplicationCount sürekli artıyor: Bu genellikle hedef bölgedeki yazma kapasitesinin yetersiz olduğu anlamına gelir. Auto-scaling ayarlarını kontrol edin veya geçici olarak provisioned kapasiteyi artırın.

TableAlreadyExists hatası: Bir bölgede aynı isimde tablo zaten varsa ve Global Table replica’sı olarak eklemeye çalışıyorsanız bu hata alınır. Mevcut tabloyu silip tekrar denemeniz ya da tabloyu boşaltmanız gerekir.

ValidationException: Streams not enabled: DynamoDB Streams’i aktif etmeden Global Table oluşturmaya çalışıyorsunuz. Önce Streams’i NEW_AND_OLD_IMAGES modunda aktif edin.

IAM izin hataları: Global Tables için servis rolü dynamodb.amazonaws.com‘a gerekli izinler verilmiş olmalı:

# IAM politikasını kontrol et
aws iam get-policy-version 
  --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess 
  --version-id v4 
  --query 'PolicyVersion.Document.Statement[*].Action' 
  --output text | tr 't' 'n' | grep -i replication

Sonuç

DynamoDB Global Tables, doğru yapılandırıldığında global ölçekli uygulamalar için inanılmaz güçlü bir altyapı sunar. Sıfır replikasyon kodu, aktif-aktif yazma, otomatik conflict resolution ve saniyeler içinde felaket kurtarma bunların hepsi tek bir servisten geliyor. Ancak bu kolaylığın bir bedeli var: maliyet ve eventual consistency. Her iki konuyu da uygulamanızı tasarlarken göz önünde bulundurmanız gerekiyor.

Pratik önerilerim şunlar: Yeni bir proje başlıyorsanız ve global deployment planınız varsa direkt Global Table olarak başlayın. Mevcut bir tabloyu dönüştürecekseniz düşük trafikli bir zaman dilimi seçin ve replikasyon tamamlanana kadar yakından izleyin. Auto-scaling’i her bölge için ayrı ayrı yapılandırmayı unutmayın, bu en çok atlanan adım. CloudWatch alarmlarını kurmadan tabloyu üretime almayın, özellikle ReplicationLatency alarmı kritik. Ve son olarak, Terraform veya CDK ile altyapınızı kodlayın; birden fazla bölgeyi manuel yönetmek kaçınılmaz olarak hatalara yol açıyor.

Global Tables’ı doğru kurduğunuzda kullanıcılarınız dünyanın neresinde olursa olsun tek haneli milisaniye gecikme sürelerinde veri okuyup yazabiliyor. Bu da son kullanıcı deneyiminde gerçek bir fark yaratıyor.

Bir yanıt yazın

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