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.
