AWS Kinesis: Tek İsim Altında Dört Servis
Kinesis tek bir servis değil, dört ayrı AWS servisidir. Dördünün ayrımı, altındaki Data Streams shard motoru, maliyet şekli ve ne zaman başka bir şey seçmeli.
“Kinesis”, AWS’deki en fazla anlam yüklenmiş isimlerden biridir. Tek bir ürün değil, farklı problemleri çözen dört ayrı servisi kapsayan bir markadır; bu yüzden konsoldaki bir açılır listeden “Kinesis” seçen bir ekip, çoğu zaman seçtiği servisin varsaydığı işi yapamadığını sonradan fark eder. Bir mühendis “bunu Kinesis’e koyarız” dediğinde neredeyse her zaman Data Streams’i kasteder: shard tabanlı, sıralı ve yeniden okunabilen ham log’u. Diğer üçü bir teslim borusu, bir akış işleme motoru ve bir video servisidir. Aşağıdaki bölümler önce dördünü ayrıştırır, sonra commit etmeden önce bilmen gereken Data Streams mekaniğine, maliyet şekline ve karar sınırlarına derinlemesine iner.
Dört servisin ayrımı
Dördün ikisi hâlâ “Kinesis” önekini taşır; diğer ikisi bu önekten uzaklaştırılarak yeniden adlandırıldı ama eski API’lerini korudu. Aşağıda her biri, var olma sebebi olan tek işiyle birlikte birer paragrafta açıklanıyor.
Amazon Kinesis Data Streams ham gerçek zamanlı veri akışıdır. Shard tabanlıdır, bir shard içinde sıralıdır ve bir saklama penceresi içinde yeniden okunabilir. Producer’ları ve consumer’ları sen yazarsın; dayanıklılığı ve (isteğe bağlı olarak) kapasiteyi AWS yönetir. “Kinesis” denildiğinde nitelemeden kastedilen servis budur ve aşağıdaki derinlemesine incelemenin konusudur.
Amazon Data Firehose (eski adıyla Amazon Kinesis Data Firehose, 2024-02-09’da yeniden adlandırıldı) tamamen yönetilen bir teslim ve ETL borusudur. Akışları yakalar, isteğe bağlı olarak dönüştürür ve S3, Redshift, OpenSearch, Splunk ve Snowflake gibi hedeflere teslim eder. Yönetilecek shard yoktur ve teslimat tamponlanır: alt saniye varış değil, bir tampon aralığının ya da boyutunun dolması beklenir. “Bu verinin sadece S3’e veya bir veri ambarına düşmesini istiyorum” gereksiniminde buna uzan. Firehose kaynağı olarak bir Data Stream’i de tüketebilir, yani ikisi rakip değil, birbirini tamamlar.
Amazon Managed Service for Apache Flink (eski adıyla Amazon Kinesis Data Analytics, 2023-08-30’da yeniden adlandırıldı) durumlu (stateful) akış işleme için serverless Apache Flink’tir: pencereli toplamalar, join’ler ve akışlar üzerinde SQL veya not defteri tabanlı analitik. Akışı sadece taşımak değil, üzerinde hesaplama çalıştırmak istediğinde buna uzan.
Amazon Kinesis Video Streams oynatma, analitik ve makine öğrenmesi için medyayı (video, ses ve diğer zaman kodlu verileri) alır, saklar ve işler. Data Streams’ten ayrı bir API yüzeyi ve fiyatlandırması vardır. Aileden ayrı düşendir: JSON kayıtları değil, medya.
Bir ayrıntı insanları yanıltır. 2024 ve 2023 yeniden adlandırmaları yalnızca konsola, dokümantasyona ve pazarlamaya dokundu. API’ler, CLI komutları, IAM eylem adları ve CloudWatch metrik isim alanları eski tanımlayıcılarını korudu. Yani aws firehose ve kinesisanalytics API adları yeni konsol etiketlerine göre hâlâ “yanlış” görünür. Bu bir hata değil, beklenen durumdur.
| Servis | Aldığı veri | Bölümlemeyi kim yönetir | Tipik çıktı | Bunu kastediyorsan söyle |
|---|---|---|---|---|
| Kinesis Data Streams | JSON veya ikili kayıtlar | Sen (partition key, shard’lar) | Senin consumer’ların | ”sıralı, yeniden okunabilir gerçek zamanlı akış” |
| Amazon Data Firehose | Kayıtlar (veya bir Data Stream) | Tamamen yönetilen | S3, Redshift, OpenSearch, Snowflake | ”şunu sadece bir hedefe düşür” |
| Managed Service for Apache Flink | Bir akış (Kinesis, Kafka) | Tamamen yönetilen | Toplamlar, türetilmiş akışlar, hedefler | ”akış üzerinde hesaplama çalıştır” |
| Kinesis Video Streams | Medya (video, ses) | Tamamen yönetilen | Oynatma, ML, medya analitiği | ”video al ve işle” |
Aşağıdaki her şey ilk satır hakkındadır.
Data Streams nasıl çalışır: shard’lar ve kapasite
Bir Data Stream, shard’lardan oluşan bir kümedir. Shard, kapasite birimidir ve katı limitleri vardır. Provisioned modda shard başına saniyede 1 MB veya 1.000 kayıt (hangi tavan önce dolarsa) yazabilir, GetRecords üzerinden saniyede 2 MB veya 2.000 kayıt okuyabilirsin; bu okuma bütçesi tüm paylaşımlı throughput consumer’ları arasında bölüşülür. Kapasite shard sayısıyla doğrusal ölçeklenir: on shard, on katı throughput verir. Bir akışı boyutlandırmak, beklenen throughput’unu bir shard sayısına çevirmek demektir.
Boyutlandırma için birkaç API limiti önemlidir. Tek bir kaydın veri bloğu 10 MiB’a kadar olabilir (eski 1 MB sınırından yükseltildi); Kinesis aralıklı 1-10 MiB kayıtlar için burst kapasitesi kullanır. Bu kayıt başına sınırı, shard başına saniyelik yazma hızıyla karıştırma; “1 MB” throughput tavanıdır, kayıt boyutu sınırı değil. PutRecords istek başına 500 kayıt veya 10 MiB’a kadar toplar. GetRecords çağrı başına 10.000 kayıt veya 10 MB döndürür, shard başına saniyede 5 okuma işlemi ile; bir çağrı tam 10 MB döndürürse, izleyen 5 saniye içindeki çağrılar ProvisionedThroughputExceededException fırlatır.
Partition key, hash ve shard yerleşimi
Bir producer kayıt yazdığında bir partition key (bir string) verir. Kinesis bu anahtarı MD5 ile 128 bitlik bir tamsayı hash anahtar uzayına hash’ler. Her shard bu uzayın bitişik bir aralığına sahiptir, böylece belirli bir anahtar her zaman aynı shard’a düşer. Sıralamayı çalıştıran kural budur: kayıtlar bir shard içinde, yani partition key başına sıralıdır, asla tüm akış genelinde değil.
İki farklı anahtarı aynı shard’a zorlaman gerekirse, yerleşimi bir ExplicitHashKey ile geçersiz kılabilirsin. Bu, her gün kullanılan bir ayar değil, bilinçli bir bir-arada-konumlandırma aracıdır.
Sıcak shard (hot shard) problemi
Yerleşim anahtarı takip ettiği için, çarpık bir anahtar dağılımı orantısız trafiği tek bir shard’a gönderir. O shard kısıtlanır (WriteProvisionedThroughputExceeded) ama akış toplamda az kullanılmış görünür; yani yalnızca akış düzeyindeki toplamlara bakan panolar bolca boş alan gösterir. Bu, en sık yapılan Data Streams tasarım hatasıdır. country veya tenant_id gibi bir partition key, bir ülke ya da bir büyük tenant baskın çıkana kadar makul görünür. Çözüm, daha yüksek kardinaliteye sahip, daha iyi dağılan bir anahtardır. Tenant başına sıralamaya gerçekten ihtiyacın varsa, sıcak bir tenant’ın kendi shard bütçesine ihtiyaç duyacağını kabul et ve ortalamaya değil, en yoğun anahtara göre boyutlandır.
Yeniden bölümleme (resharding): split ve merge
Provisioned modda kapasiteyi yeniden bölümleyerek değiştirirsin. İki temel işlem vardır. SplitShard bir shard’ı iki çocuğa böler, kapasiteyi ve maliyeti yükseltir. MergeShards iki bitişik shard’ı tek bir çocukta birleştirir, ikisini de düşürür. Split ve merge her zaman ikişerlidir. Ana (parent) shard’lar kapanır, çocuklar hash aralığını devralır. Provisioned ölçekleme için UpdateShardCount, split ve merge’leri senin yerine hesaplayan üst düzey çağrıdır. On-demand mod bütün bunları otomatik yapar, yani resharding API’leri bir provisioned-mod meselesidir.
Resharding sırasında consumer’ları bir sıralama kuralı bağlar: bir consumer, çocuklarını okumadan önce bir ana shard’daki tüm kayıtları okumalıdır, yoksa partition key başına sıralama sınırda bozulur. Kinesis Client Library bunu otomatik halleder; elle yazılmış bir consumer buna uymak zorundadır.
Kapasite modları: provisioned ve on-demand
Provisioned mod, shard sayısını kendin belirlemen ve ölçeklemen demektir. Sabit, öngörülebilir ve yüksek throughput’ta en ucuz seçenektir, çünkü GB başına veri ücreti ödemezsin; karşılığında boyutlandırma ve resharding senin sorumluluğundadır.
On-demand mod, AWS’nin shard’ları yönetmesi ve senin yerine otomatik ölçeklemesi demektir. Yeni bir on-demand akış 4 shard (4 MB/s yazma, 8 MB/s okuma) ile başlar ve son 30 günde görülen tepe yazma throughput’unun iki katına kadar otomatik ölçeklenir. Ölçekleme tepkisel olduğu için, yaklaşık 15 dakika içinde önceki tepenin 2 katını aşan ani bir sıçrama yine de kısıtlanabilir. Varsayılan on-demand tavanı 200 MB/s yazma ve 400 MB/s okuma’dır; us-east-1, us-west-2 ve eu-west-1’de 10 GB/s yazma ve 20 GB/s okuma’ya yükselir (başka yerlerde daha yüksek katmanı bir destek talebi açar). Bir akışı 24 saatte iki kez modlar arasında değiştirebilirsin.
Artık on-demand hikâyesinin birinci sınıf bir parçası sayılması gereken üçüncü bir seçenek var. On-demand Advantage modu (2025-11-20’de duyuruldu), On-demand Standard’a göre GB başına yaklaşık %60 daha düşük fiyatlandırmaya ve daha yüksek bir enhanced fan-out consumer sınırına (20 yerine 50) sahip, hesap düzeyinde bir ayardır. Yüksek ve sabit on-demand hacim için güncel maliyet-ve-ölçek hamlesidir, maliyet bölümünde ele alınan bir püf noktasıyla: hesap düzeyinde bir minimum taahhüt.
İpucu: Trafiği bilinmeyen yeni bir akış için makul bir varsayılan on-demand’dir, sonra şekil belli olup oturunca provisioned’a geçmektir. Boyutlandırma kararlarını atlamak için GB başına primi ödemek başlangıçta değer; öngörülebilir, yüksek hacimli bir akışta bunu sonsuza kadar ödemek değmez.
Saklama, teslim ve sıralama
Varsayılan saklama 24 saattir. IncreaseStreamRetentionPeriod ile en fazla 8.760 saate (365 gün) kadar uzatabilirsin; minimum 24 saattir. 24 saatin ötesindeki saklama ücretlendirilir ve uzatılmış katman (24 saat - 7 gün) ile uzun vadeli katman (7 günden fazla - 365 gün) farklı fiyatlandırılır. Uzun vadeli saklama, harici bir arşiv olmadan geriye dönük test, geri doldurma (backfill) ve denetim amaçlı yeniden okumayı mümkün kılan özelliktir.
İki anlamsal gerçek, yazdığın her consumer’ı şekillendirmelidir. Teslim en az bir kez (at-least-once)‘tir, yani consumer’lar idempotent olmalıdır; yeniden denemelerde ve resharding civarında kopyalar oluşur. Producer’lar da PUT yeniden denemelerinde kopya oluşturabilir. Yalnızca bir shard içinde tutan sıralamayla birleşince sonuç somuttur: tekrarsızlaştırma (deduplication) ve sıralamaya duyarlı mantık, bir idempotency anahtarı ve bir dedup deposuyla, consumer tarafına aittir.
Consumer modelleri
Bir Data Stream’i okumanın dört yolu vardır ve aralarındaki fark çoğunlukla shard başına 2 MB/s okuma bütçesinin nasıl paylaşıldığıyla ilgilidir.
Paylaşımlı throughput polling varsayılandır. Her paylaşımlı consumer, shard başına o 2 MB/s’yi (ve saniyede 5 okuma işlemini) bölüşür. İkinci bir consumer ekle, her biri etkin olarak yaklaşık 1 MB/s alır. Üçüncüsünü ekle, açlığa düşmeye başlarlar: consumer’lar geri kaldıkça GetRecords.IteratorAgeMilliseconds yükselir. “Kinesis yavaş” şeklindeki yanlış sonucun arkasındaki mekanizma budur. Yavaş değildir; paylaşımlı okuma bütçesi bölünmektedir.
Kinesis Client Library (KCL), kendi yönettiğin consumer filoları içindir. Shard başına bir lease’i (kiralama) worker’lar arasında koordine eder, shard başına sequence number’ı bir DynamoDB tablosuna checkpoint’ler, shard’ları worker’lar arasında yük dengeler ve resharding’e ana shard’ları çocuklardan önce boşaltarak otomatik tepki verir. KCL 3.x (güncel ana sürüm) iki DynamoDB metadata tablosu daha (worker-metrics ve coordinator-state) ve okuma kapasitesi maliyetini düşürmek için leaseOwner üzerinde bir global secondary index ekler. Ayrıca zarif (graceful) lease devri ekler: bir worker, bir lease’i devretmeden önce checkpoint’lemeyi bitirir, bu da yeniden işlemeyi azaltır. Maliyet sonucuna dikkat: DynamoDB lease tablosu, ekiplerin bir KCL consumer’ı bütçelerken rutin olarak unuttuğu, gerçek ve ücretlendirilen bir yan bağımlılıktır.
Enhanced fan-out (EFO), kayıtlı her consumer’a shard başına ayrılmış 2 MB/s verir; polling yerine SubscribeToShard üzerinden HTTP/2 ile itilir (push) ve tipik olarak yaklaşık 70 ms içinde teslim edilir (AWS’nin yayımladığı rakamlara göre GetRecords’a kıyasla kabaca %65 daha düşük gecikme). Consumer’lar artık birbiriyle çekişmez. Kayıtlı consumer sınırı On-demand Standard ve Provisioned’da akış başına 20, On-demand Advantage’da akış başına 50’dir. EFO ekstra maliyetlidir (bir consumer-shard-saat ücreti artı GB başına bir alım ücreti, consumer başına eklenir), yani kabaca iki ya da üç consumer’ı geçince veya gecikme gerçekten önemli olduğunda hakkını verir.
Lambda’nın bir consumer olarak kullanımı, bir event source mapping (ESM) aracılığıyla, serverless varsayılandır. Lambda her shard’ı yoklar (standart iterator için saniyede yaklaşık bir kez) veya bir consumer ARN’i verirsen EFO ile abone olur, kayıtları toplar ve fonksiyonunu çağırır. Onu 5 dakikaya kadar bir toplama penceresi, 6 MB’a kadar bir yük ve 1 ile 10 arası bir ParallelizationFactor (shard başına eşzamanlı toplu işler, hâlâ partition key başına sıralı) ile ayarlarsın.
Lambda’nın hata davranışı, ezberlenmeye değer püf noktasıdır. Varsayılan olarak MaximumRetryAttempts ve MaximumRecordAgeInSeconds -1, yani sonsuzdur. Yani tek bir zehirli (poison-pill) toplu iş, shard’ını bloke eder ve o kayıtlar saklama süresinden düşene kadar yeniden dener; tek bir kötü kaydın arkasında tüm shard durur. Üç hafifletme önemlidir: BisectBatchOnFunctionError başarısız bir toplu işi bölerek kötü kaydı izole eder (ve retry kotasını tüketmez), sonlu MaximumRetryAttempts veya MaximumRecordAgeInSeconds durmayı sınırlar ve bir OnFailure hedefi (SQS, SNS veya S3) işlenemeyeni yakalar. O hedef hakkında bir uyarı: SQS ve SNS için Lambda yalnızca metadata (streamArn, shardId, startSequenceNumber, endSequenceNumber) gönderir, kayıt gövdelerini değil; yani dead-letter (DLQ) işleyicin, onları kurtarmak için akışı yeniden okumak zorundadır.
| Model | Shard başına okuma bütçesi | Gecikme | Ne zaman kullanmalı |
|---|---|---|---|
| Paylaşımlı polling | 2 MB/s tüm consumer’lar arasında bölünür | Yoklama aralığı | Bir veya iki consumer, maliyete duyarlı |
| KCL 3.x | Paylaşımlı (veya EFO) | Yoklama veya push | Checkpoint ve dengeleme gerektiren kendi filon |
| Enhanced fan-out | Consumer başına ayrılmış 2 MB/s | ~70 ms push | Üç veya daha fazla consumer, ya da gecikmeye duyarlı |
| Lambda ESM | Paylaşımlı veya EFO | Yoklama (~1s) veya push | Worker çalıştırmadan serverless işleme |
Minimal bir producer ve bir akış kontrolü
AWS SDK v3 JavaScript için sunucu tarafıdır, yani bir Lambda ya da servis producer’ı şöyle görünür. Shard’ı belirleyenin partition key olduğuna dikkat et.
import {
KinesisClient,
PutRecordCommand,
} from "@aws-sdk/client-kinesis";
const kinesis = new KinesisClient({ region: "us-east-1" });
export async function publishOrderEvent(order: {
id: string;
tenantId: string;
}) {
await kinesis.send(
new PutRecordCommand({
StreamName: "order-events",
// Yüksek kardinaliteli anahtar yükü shard'lara yayar.
// Yalnızca tenantId kullanmak büyük bir tenant için sıcak shard riski taşır.
PartitionKey: `${order.tenantId}#${order.id}`,
Data: new TextEncoder().encode(JSON.stringify(order)),
}),
);
}
Deploy zamanında bir kez bir EFO consumer’ı kaydetmek için en basit yol CLI’dır:
aws kinesis register-stream-consumer \
--stream-arn arn:aws:kinesis:us-east-1:123456789012:stream/order-events \
--consumer-name analytics-efo
{
"Consumer": {
"ConsumerName": "analytics-efo",
"ConsumerARN": "arn:aws:kinesis:us-east-1:123456789012:stream/order-events/consumer/analytics-efo:1719532800",
"ConsumerStatus": "CREATING",
"ConsumerCreationTimestamp": "2026-06-28T00:00:00+00:00"
}
}
Bir akışın kapasite modunu ve shard sayısını tüm shard listesini ayrıştırmadan hızlıca okumak istediğinde, doğru çağrı describe-stream-summary’dir:
aws kinesis describe-stream-summary --stream-name order-events
{
"StreamDescriptionSummary": {
"StreamName": "order-events",
"StreamARN": "arn:aws:kinesis:us-east-1:123456789012:stream/order-events",
"StreamStatus": "ACTIVE",
"StreamModeDetails": {
"StreamMode": "ON_DEMAND"
},
"RetentionPeriodHours": 24,
"OpenShardCount": 4,
"ConsumerCount": 1,
"EnhancedMonitoring": [
{
"ShardLevelMetrics": []
}
]
}
}
O boş ShardLevelMetrics bir hatırlatmadır: bir sıcak shard’ı asıl ortaya çıkaran shard başına metrikler, EnableEnhancedMonitoring ile isteğe bağlıdır ve ek CloudWatch özel metrikleri olarak ücretlendirilir. IncomingBytes, IncomingRecords ve GetRecords.IteratorAgeMilliseconds gibi akış düzeyi metrikleri varsayılan olarak bir dakika granülaritesinde yayınlanır, ama çarpıklığı gizlerler. Bir sıcak shard’dan şüpheleniyorsan, onu doğrulayacağın yer shard başına görünümdür.
Yaygın kullanım senaryoları
Alan etiketlerini soyduğunda, kanonik Data Streams kullanım senaryoları yukarıdaki mekanikten hep aynı üç özelliği satın alır: ölçekte saniye-altı alım, shard başına sıralama ve bağımsız consumer’lara yeniden okunabilir fan-out. AWS’nin kendi listesi (log alımı, gerçek zamanlı metrikler, gerçek zamanlı analitik ve karmaşık çok-aşamalı işleme) bu özelliklerin farklı kıyafetler giymiş halidir: içeri çok sayıda producer, ortada tek bir sıralı dayanıklı log, dışarı birkaç bağımsız okuyucu.
| Kullanım senaryosu | Neye dayanır | Ailede nereye oturur |
|---|---|---|
| Log ve event alımı | producer tarafında batch’leme olmadan saniye-altı alım, böylece front-end çökse de veri hayatta kalır | Data Streams içeri, Firehose ile ham log’ları S3’e düşür |
| Gerçek zamanlı metrik ve dashboard | sıralama artı saniye altı put-to-get gecikmesi | Data Streams’ten Lambda ya da Managed Service for Apache Flink’e |
| Clickstream ve ürün analitiği | replay artı paralel, bağımsız çok-consumer okuma | Data Streams’ten enhanced fan-out ile aynı anda birkaç uygulamaya |
| IoT ve telemetri alımı | partition key ile cihaz başına sıralama, yüksek throughput’ta | Data Streams, device id ile anahtarlanmış |
| Streaming ETL ve toplama | durumlu pencereli işleme, sonra düzenlenmiş veriyi düşürme | Data Streams’ten Flink’e, Firehose ile bir veri ambarına |
| Çok aşamalı (DAG) işleme | bir aşamanın çıktısı sonraki aşamanın akışını besler | Data Streams, Data Streams’e zincirlenir |
Şeklin ne sıklıkla tekrarlandığına dikkat et: sıralı, yeniden okunabilir log için Data Streams, üstündeki iş için Firehose ya da Flink. İşte dört servisin ayrı isimlerini bir kez daha hak etmesi, bu kez tanım tarafından değil, kullanım senaryosu tarafından.
Data Streams pratikte: CDC, routing ve idempotency
Mekanik, neredeyse her gerçek Data Streams kurulumunda beliren üç pattern’de karşılığını bulur: veritabanı değişikliklerini bir akış olarak yakalamak, kayıtları içeriğe göre yönlendirmek ve teslim tam-bir-kez değil en-az-bir-kez olduğu için onları idempotent tüketmek.
Değişiklikleri (CDC) bir akışa yakalamak
Change data capture (CDC), bir veritabanındaki her insert, update ve delete’i sıralı bir event’e çevirir; Data Streams de bunlar için doğal bir evdir: shard başına sıralı, yeniden okunabilir ve aynı anda birçok consumer tarafından okunabilir. İki giriş yolu çoğu durumu kapsar ve her birinin, bağlamadan önce bilmeye değer bir record şekli ve birkaç ayarı vardır.
Doğrudan DynamoDB. Kinesis Data Streams for DynamoDB’yi açtığında tablo, her item-level değişiklik için değişiklik zamanını, item’ın birincil anahtarını ve item’ın hem önceki hem sonraki görüntüsünü taşıyan bir kayıt yayar. Yalnızca açtığın andan itibaren yakalar, yani geçmişi cutover’dan önce bir export ya da scan ile tohumla; backfill yoktur. Düz DynamoDB Streams’ten ayıran şey erişimdir: DynamoDB Streams 24 saat saklar ve kendi KCL adaptörü vardır, oysa Kinesis yolu 365 güne kadar saklama, enhanced fan-out ve consumer olarak Firehose ya da Managed Service for Apache Flink verir. Dokümanların doğrudan belirttiği iki davranış consumer’ını şekillendirir: kayıtlar sırasız gelebilir ve aynı değişiklik birden fazla kez görünebilir. İkisini de her kayıttaki ApproximateCreationDateTime damgasıyla (milisaniye ya da mikrosaniye hassasiyetine ayarlanabilir) çözersin. Bir keskin kenar daha: binary alanlar girişte ikinci kez base64’lenir, yani consumer’lar iki kez decode eder.
AWS DMS üzerinden ilişkisel veritabanları. Bir DMS görevi bir Data Stream’i hedef alır ve her satır değişikliğini bir JSON kaydı olarak yazar; ya da Firehose’un onu Athena için S3’e düşürmesini istediğinde tek satırlık JSON_UNFORMATTED olarak. Kaydı şekillendirir ve partition key’i object mapping ile seçersin. Endpoint ayarları ne kadar bağlamın eşlik edeceğine karar verir: IncludeTransactionDetails commit zaman damgasını ve transaction_id’yi ekler, IncludeTableAlterOperations add-column gibi DDL’i taşır ve before-image ayarları, bir consumer’ın eskiyle yeniyi karşılaştırabilmesi için satırın önceki değerlerini iliştirir. Throttling tuzağı somuttur: birincil anahtarla anahtarlar ve dar anahtarlı binlerce tablo aynı aralığı paylaşırsa, her tablodan aynı anahtar tek bir shard’a yığılır; PartitionIncludeSchemaTable bunu dağıtmak için partition değerine şema ve tablo adını ön ek olarak ekler. Throughput için DMS, CDC’yi 32’ye kadar ParallelApplyThreads ile uygular; bunu açtığında partition key, tablonun birincil anahtarına varsayılır, yani her satır yine tek bir shard’da serileşirken farklı satırlar paralel gider.
İkisinin altındaki kural aynıdır: varlık başına sıralama yalnızca bir shard içinde geçerlidir, yani partition key, varlığın birincil anahtarı olmalıdır. Değişiklikleri customerId ile anahtarla, bir müşterinin geçmişi tek bir shard’da sırada kalır; kaba bir şeyle anahtarla, bir delete onu izlemesi gereken insert’i geçebilir. Tek bir sıcak varlık o zaman sıcak bir shard olur ve aynı anahtarı hem kusursuz sıralayıp hem paralelleştiremezsin; aşağıdaki versiyon tabanlı idempotency’nin ara sıra olan bir sıra bozulmasını zararsız kılmasının nedeni de budur.
Routing: Kinesis böler, EventBridge yönlendirir
Data Streams içeriğe göre yönlendirmez. Tek yönlendirmesi, bir shard’ı seçen partition-key hash’idir; her consumer sahip olduğu shard’lardaki her kaydı okur ve neyi yok sayacağına kendisi karar verir. İhtiyaç “USD 1.000 üzerindeki siparişler şu handler’a, iadeler şuna” haline geldiği an, bu içerik yönlendirmesidir ve Kinesis’e değil EventBridge’e aittir.
EventBridge Pipes bağlayıcı dokudur ve ilk bakışta göründüğünden daha yapılandırılabilirdir. Bir pipe, bir Data Stream’e ya paylaşımlı-throughput consumer’ı ya da ayrılmış enhanced-fan-out consumer’ı olarak bağlanır, her shard’ı saniyede yaklaşık bir kez yoklar ve harekete geçmeden önce beş dakikalık bir pencereye ya da 6 MB’a kadar tamponlar. Shard başına on batch’e kadar paralel çalışabilir ve yine partition-key seviyesinde sırayı korur; kısmi batch hatalarını raporlar, böylece tek bir zehirli kayıt tüm batch’i yeniden denemeye zorlamaz; bu da consumer bölümündeki shard-bloklama probleminin bildirimsel (declarative) çözümüdür. Her kayıt pipe’a bir zarf olarak ulaşır (partitionKey, sequenceNumber, base64 data, approximateArrivalTimestamp); filtre aşaması bu alanlara bir EventBridge event pattern’i uygular ve eşleşmeyen kayıtları, herhangi bir zenginleştirme ya da hedef compute’una mal olmadan düşürür. data base64 olduğu için, derin içerik filtrelemesi genelde ham pattern yerine zenginleştirme adımına (bir Lambda ya da Step Functions akışı ya da 6 MB yanıtla sınırlı bir API çağrısı) dayanır.
Bir pipe tam olarak tek bir hedefe gider. Bir akışı içeriğe göre yönlendirilen birçok hedefe açmak için dokümante edilen şekil şudur: Kinesis’ten bir pipe’a, oradan hedef olarak bir EventBridge event bus’a; sonra bus kuralları ihtiyacın kadar hedefe yönlendirir. İşbölümü temizdir: akış, yeniden okuduğun dayanıklı sıralı log’dur; bus, replay olmadan içerik yönlendiricisi ve fan-out’tur; pipe ise ikisi arasındaki tek yönlü köprüdür.
| Araç | Yönlendirme modeli | Replay | Faturalama |
|---|---|---|---|
| Kinesis Data Streams | içeriğe göre değil, partition-key hash’i ile shard’a | evet, saklama içinde | shard-saati veya GB başına |
| EventBridge bus | çok hedefe içerik kuralları, fan-out | hayır | event başına |
| EventBridge Pipes | tek kaynak, filtrele ve zenginleştir, tek hedef, sıra koruyan | hayır, kaynaktan okur | istek başına |
Idempotency: en-az-bir-kez, çift kayıtları tasarıma katmak demektir
Data Streams en az bir kez teslim eder, dolayısıyla duplicate’ler bir kenar durum değil, sözleşmenin parçasıdır; ve CDC giriş yollarının gösterdiği gibi, kaynak kendi başına sırayı bozabilir ve tekrarlayabilir. Dört şey bunları üretir: bir producer zaman aşımından sonra PutRecord’u yeniden dener ve iki kez yazar; bir consumer bir batch’i işledikten sonra ama checkpoint’ten önce çöker ve yeniden başlayınca tekrar işler; bir reshard sınır civarındaki kayıtları yeniden oynatır; ve DynamoDB’nin kendi değişiklik akışının sırayı bozduğu ve tekrarladığı dokümante edilmiştir. Dördü için de planla.
Savunma, sabit bir kimliğe dayanan bir dedup kapısıdır. Her kayıt bir sequenceNumber taşır; bu, shard’ı içinde partition key başına benzersizdir, dolayısıyla stream genelinde benzersiz bir anahtar için onu shard id ile eşle (bu çift, yukarıdaki pipe zarfında gördüğün eventID’dir) ya da payload’daki bir iş idempotency anahtarını kullan; her ikisi de koşullu bir yazmayı anahtarlar: etkiyi uygulamak ve anahtarı kaydetmek atomik olur ve bir replay no-op’a döner. Apaçık olmayan kısım penceredir: bir stream tüm saklama süresi boyunca, 365 güne kadar yeniden okunabilir, yani bir saatlik TTL’li bir dedup tablosu, bir backfill daha eski geçmişi yeniden oynattığı an sessizce korumayı bırakır. TTL’i gerçekten çalıştıracağın en uzun replay’e göre boyutlandır ve tabloyu, olduğu şey olarak gör: gerçek, faturalanan bir bağımlılık.
CDC için bir adım daha git ve yazmayı yalnızca bir anahtara değil, bir versiyona göre idempotent yap; çünkü kayıtlar bir kez sırasını bozunca “bunu gördüm mü?” yanlış soru, “bu elimdekinden daha mı yeni?” doğru sorudur. Versiyon olarak DynamoDB’nin ApproximateCreationDateTime’ını ya da DMS’in commit zaman damgasını kullan ve bir değişikliği yalnızca depolanandan daha yeniyse uygula. Yeniden teslim edilen ya da sırasız daha eski bir değişiklik o zaman bayat veriyi diriltmek yerine no-op olarak iner.
import {
DynamoDBClient,
UpdateItemCommand,
ConditionalCheckFailedException,
} from "@aws-sdk/client-dynamodb";
const db = new DynamoDBClient({ region: "us-east-1" });
// Bir CDC değişikliğini yalnızca elimizdekinden daha yeniyse uygula.
// Yeniden teslim edilen ya da sırasız bir kayıt koşulu geçemez ve atlanır.
async function applyChange(change: {
entityId: string;
version: number;
state: string;
}) {
try {
await db.send(
new UpdateItemCommand({
TableName: "projection",
Key: { id: { S: change.entityId } },
UpdateExpression: "SET #s = :state, version = :v",
ConditionExpression: "attribute_not_exists(version) OR version < :v",
ExpressionAttributeNames: { "#s": "state" },
ExpressionAttributeValues: {
":state": { S: change.state },
":v": { N: String(change.version) },
},
}),
);
} catch (err) {
if (err instanceof ConditionalCheckFailedException) return; // duplicate veya bayat
throw err;
}
}
Pratikte iki ayrıntı ısırır. Producer’ların Kinesis Producer Library kullanıyorsa, o birçok kullanıcı kaydını tek bir Kinesis kaydına paketler ve KCL bunları açar; o yüzden Kinesis kaydı yerine kendi payload anahtarına göre dedup yap. Ve tüm bunları elle yazmak ağır geliyorsa, Managed Service for Apache Flink tam da bunun için: checkpoint’lemesi kendi state’i üzerinde exactly-once işleme verir; işlettiğin dedup deposunu, işlettiğin bir Flink uygulamasıyla takas edersin.
Aynı fikir genel durumu da kapsar; anahtarlar, pencereler ve depolama için daha tam bir ele alış istersen idempotency rehberine bak.
Maliyet modeli
Fiyatlandırma değişir, bu yüzden modeli kalıcı kısım, her dolar rakamını da tarihli bir çapa olarak ele al. Aşağıdaki tüm rakamlar US East (N. Virginia), AWS fiyatlandırma sayfasından, 2026-06-28’de alındı; güvenmeden önce güncelliğini doğrula, çünkü Kinesis fiyatlandırması değişir.
Provisioned mod şu kalemleri faturalandırır:
- Shard saati: shard-saati başına USD 0,015 (bir shard 1 MB/s yazma, 2 MB/s okumadır).
- PUT yük birimleri (payload units): milyon birim başına USD 0,014; bir birim, bir kaydın 25 KB’lık bir parçasıdır, yukarı yuvarlanır. 5 KB’lık bir kayıt 1 birim; 30 KB’lık bir kayıt 2 birim; 1 MB’lık bir kayıt 40 birimdir. Yüksek hızlı, küçük kayıtlı iş yüklerini ısıran kalem budur.
- Uzatılmış saklama (24 saat - 7 gün): shard-saati başına ekstra USD 0,020.
- Uzun vadeli saklama (7 günden fazla - 365 gün): GB-ay başına USD 0,023 depolama artı
GetRecordsüzerinden GB başına USD 0,021 alım. - Enhanced fan-out: consumer-shard-saati başına USD 0,015 artı alınan GB başına USD 0,013, kayıtlı her consumer için eklenir.
On-demand Standard farklı faturalandırır: stream-saati başına USD 0,040, artı alınan (ingest) GB başına USD 0,08 (1 KB yuvarlama ile), artı alınan (retrieved) GB başına USD 0,040; EFO ayrıca GB başına faturalanır. Sayılacak shard ve shard-saati yoktur.
On-demand Advantage (2025-11-20) alınan GB başına USD 0,032 ve alınan GB başına USD 0,016 faturalandırır, kabaca Standard’ın %60 altında; stream başına saatlik ücret yoktur ve EFO veri-çıkış oranına dâhildir. Püf noktası, hesap düzeyinde 25 MB/s ingest artı 25 MB/s retrieval’lık bir minimum taahhüttür. O minimum, Advantage’ı küçük akışlar için bir varsayılan değil, tam olarak yüksek-sabit-throughput hamlesi yapan şeydir.
Adım adım örnek hesap
Yaklaşık 1.000 kayıt/s ve her biri kabaca 3 KB olan bir iş yükü düşün; bu yaklaşık 3 MB/s ingest demektir. Aşağıdaki aritmetik yöntemdir; kendi rakamların için güncel fiyatlarla yeniden hesapla.
Provisioned modda, 3 MB/s throughput ceil(3 / 1) = 3 shard gerektirir (saniyede 1.000 kayıt/shard sınırı burada bağlayıcı kısıt değil, byte hızı bağlayıcı). İki EFO consumer’ı ekle.
| Kalem | Hesap | Aylık |
|---|---|---|
| Shard saatleri | 3 shard x USD 0,015 x 730 sa | ~USD 32,85 |
| PUT yük birimleri | ~2,63 milyar birim x USD 0,014/milyon | ~USD 36,80 |
| EFO consumer-shard saatleri | 2 x 3 shard x USD 0,015 x 730 sa | ~USD 65,70 |
| EFO + alım | üstüne GB başına alım | hacimle artar |
Aynı 3 MB/s, On-demand Standard altında ayda yaklaşık 7,78 TB alır; bu GB başına USD 0,08 ile sadece ingest ücretinde, alım hariç, kabaca USD 622 eder. Bu fark, bütün mesele: provisioned sabit, öngörülebilir yükte kazanır; on-demand ani ya da bilinmeyen yükte kazanır. Geçiş noktası gerçek ve büyüktür, yani kapasite-modu seçimi yalnızca operasyonel değil, bir maliyet kararıdır.
Servisler arasında faturanın şekli, kesin rakamlardan daha fazla değişir. Data Streams provisioned throughput (shard-saatleri) veya GB başına (on-demand) ücretlendirir. SQS istek başına ücretlendirir (Standard, bu tarihte us-east-1’de kabaca milyon istek başına USD 0,40; doğrula) ve sıfıra ölçeklenir, ama FIFO dışında sıralama, yeniden okuma ve tek bir kuyruktan bire-çok fan-out sunmaz. MSK, boştayken bile faturalanan bir küme (broker-saatleri artı depolama) için ücretlendirir; karşılığında Kafka semantiği ve daha yüksek bir taban verir. İş yükü şekline göre seç, fatura da şekli takip eder.
Data Streams ne zaman doğru cevap, ne zaman değil
Sıralı, yeniden okunabilir, çok consumer’lı gerçek zamanlı bir akışa ihtiyacın olduğunda ve Kafka işletmeden yönetilen, shard ile boyutlandırılan bir servis istediğinde Kinesis Data Streams’e uzan. Onun tatlı noktası budur ve akış kullanım durumu içinde mantıklı varsayılandır. O üç özellikten (sıralama, yeniden okuma, birden çok bağımsız consumer) biri gerçekten gerekli olmadığı anda, daha basit bir servis genellikle kazanır.
Bu sınırlar bu sitede başka yerlerde zaten derinlemesine tartışıldı, bu yüzden burada yeniden açmak yerine: soru Kafka mı, bus mu ise, bkz. Kafka mı, event bus mı: geçiş sinyalleri. SNS ve SQS fan-out desenleri için bkz. SNS’ten SQS’e hesaplar arası fan-out ve İzole consumer hesaplarına event fan-out. Event sistemi seçeneklerinin daha geniş manzarası için bkz. Event-driven sistem araçları karşılaştırması.
Sık yapılan hatalar
Birkaç hata, ekiplerin Data Streams’le yaşadığı sıkıntının çoğunu açıklar.
- Data Streams gerekirken Firehose seçmek ya da tersi. Firehose yalnızca tamponlanmış teslimdir; veriyi bir hedefe düşürür ve birçok bağımsız consumer bağladığın yeniden okunabilir bir log değildir. Tersine, Firehose (kaynağı olarak bir Data Stream’i tüketebilir) sıfır kodla halledecekken Data Streams üzerinde S3 teslimini elle yazmak.
- Düşük kardinaliteli bir partition key’in sıcak shard yaratması. Anahtarı dağıt; explicit hash key’i yalnızca bir-arada-konumlandırma amacın olduğunda kullan.
- Üçüncü veya dördüncü paylaşımlı consumer’ı ekleyip gecikme için Kinesis’i suçlamak, enhanced fan-out’a geçmek yerine.
- En-az-bir-kez teslim altında idempotent olmayan consumer’lar, ki bu yeniden denemelerde ve resharding civarında çift işlemeye yol açar.
- Başarısız bir Lambda toplu işinin shard’ını bloke edebileceğini unutmak, kayıtlar düşene kadar;
BisectBatchOnFunctionError, sonlu retry’lar ya da bir on-failure hedefi yapılandırmamak. - Saklamanın bedava ve sınırsız olduğunu varsaymak. Uzatılmış ve uzun vadeli saklama ücretlendirilir ve iki katman farklı fiyatlandırılır.
- Paylaşımlı modda shard çıkışını consumer başına sanmak. Paylaşımlı bir 2 MB/s’dir; yalnızca EFO onu consumer başına yapar.
Kapanış
Kinesis dört servistir ve çoğu zaman Data Streams’i kastedersin: kendi consumer’larını bağladığın, sıralı, yeniden okunabilir, shard ile boyutlandırılan bir akış. Throughput’u shard’lara çevirerek boyutlandır, partition key’i hiçbir tek shard sıcak çalışmayacak şekilde seç, kapasite modunu alışkanlıktan değil trafik öngörülebilirliğinden seç ve her consumer’ı idempotent yap, çünkü teslim en-az-bir-kez’dir. Sınır, en az varsayılan kadar önemlidir. Sıralama, yeniden okuma ve bağımsız çok-consumer fan-out’a birlikte ihtiyacın yoksa, bir iş kuyruğu, bir event yönlendirici ya da bir tablo akışı daha basit ve çoğu zaman daha ucuz cevaptır; Kafka ağırlıklı bir ortam ise MSK ile daha iyi hizmet alır. Commit etmeden önceki somut sonraki adım, beklenen tepe throughput’unu ve consumer sayını kâğıda yazmak ve ikisini de shard başına limitlere karşı kontrol etmektir; boyutlandırma bundan çıkar, fatura da öyle.
Kaynaklar
- Amazon Kinesis Data Streams: Quotas and limits - Shard başına yazma ve okuma limitleri, 10 MiB kayıt boyutu, GetRecords ve PutRecords limitleri, on-demand varsayılanları ve tavanları, 20’ye-50 EFO consumer sınırı, 365 günlük maksimum saklama.
- Amazon Kinesis Data Streams: Terminology and concepts - Partition key’den hash’e ve shard’a eşleme, bir shard içinde garanti edilen sıralama.
- Reshard a stream (split ve merge) - İkişerli split ve merge, ana ve çocuk shard’lar, yalnızca provisioned ve UpdateShardCount.
- Change the data retention period - Varsayılan 24 saat, uzatılmış saklama ve 365 güne kadar uzun vadeli saklama.
- Develop enhanced fan-out consumers with dedicated throughput - Consumer başına shard başına ayrılmış 2 MB/s, HTTP/2 üzerinden SubscribeToShard ve yaklaşık 70 ms teslim.
- DynamoDB metadata tables and load balancing in the KCL - Lease’ler, checkpoint ve KCL’nin yönettiği DynamoDB tabloları.
- amazon-kinesis-client CHANGELOG (KCL 3.x) - KCL 3.x metadata tabloları, leaseOwner GSI ve zarif lease devri.
- Using Lambda to process records from Kinesis Data Streams - Event source mapping, toplama penceresi ve 6 MB yük, ParallelizationFactor 1 ile 10 ve EFO consumer’lar.
- Retain discarded batch records (on-failure destination) - BisectBatchOnFunctionError, -1 varsayılan retry ve kayıt-yaşı ayarları ve yalnızca metadata içeren DLQ yükü.
- Amazon Kinesis Data Streams pricing - Shard-saati, PUT yük birimleri (25 KB), uzatılmış ve uzun vadeli saklama, EFO ve on-demand Standard ile Advantage fiyatlandırması.
- Introducing Amazon Data Firehose, formerly Amazon Kinesis Data Firehose - APIs değişmeden, 2024-02-09 yeniden adlandırması.
- Announcing Amazon Managed Service for Apache Flink, renamed from Kinesis Data Analytics - 2023-08-30 yeniden adlandırması.
- Kinesis Data Streams now supports up to 50 enhanced fan-out consumers - On-demand Advantage modu ve 50-consumer sınırı, 2025-11-20.
- Amazon Kinesis Data Streams On-Demand - On-demand modeli ve son-30-gün-tepesinin-iki-katı ölçekleme davranışı.
- Using Kinesis Data Streams to capture changes to DynamoDB - DynamoDB’den bir Data Stream’e native item-level CDC; tam Kinesis consumer ekosistemi ve DynamoDB Streams’ten daha uzun saklama.
- Using Amazon Kinesis Data Streams as a target for AWS Database Migration Service - İlişkisel CDC’yi bir akışa taşımak, object mapping ile partition-key kontrolü ve before-image’lar.
- Amazon EventBridge Pipes - Noktadan noktaya kaynak, filtre, zenginleştirme ve hedef; desteklenen bir kaynak olarak Kinesis Data Streams ve korunan sıralama.
- What is Amazon Kinesis Data Streams? - AWS’nin kanonik kullanım senaryoları: hızlandırılmış log ve veri akışı alımı, gerçek zamanlı metrik ve raporlama, gerçek zamanlı analitik ve karmaşık çok-aşamalı stream işleme; saniye-altı put-to-get gecikmesiyle.
İlgili yazılar
Amazon SNS ve SQS ile güvenli cross-account event dağıtımı: IAM policy'leri, KMS şifreleme, AWS CDK kurulumu ve production'da karşılaşılan yaygın sorunlar.
SQS, SNS ve EventBridge arasında özelliklere göre değil iletişim modeline göre seçim yap; çalışan CDK örnekleri ve net bir maliyet analizi ile.
AppSync subscription'ları yalnızca mutation ile tetiklenir. Downstream BFF olaylarını NONE veri kaynaklı bir mutation'a EventBridge ve CDK ile köprülemeyi inceliyorum.
Yönetilen bir event bus'tan Kafka'ya geçişi hak eden sinyaller ve rip-and-replace yapmadan taşımak için outbox tabanlı dört aşamalı geçiş planı.
Çok takımlı AWS organizasyonları için platform varsayılanı: tek event, birçok consumer, her biri kendi hesabında SQS ve DLQ'suyla; fan-out bus katmanında.