İleri6 dakikalık okuma

DynamoDB Parallel Scan'ler

Bir parallel scan, bir Scan'i N bağımsız Scan isteğine böler, her biri tablonun bir Segment'ini sahiplenir, böylece birden çok worker onu aynı anda okur. Bir tablonun tamamını tek bir partition'ın throughput'unun izin verdiğinden daha hızlı okumanın tek yoludur.

DynamoDB parallel scan nedir?

DynamoDB parallel scan, bir Scan'i N bağımsız isteğe böler; her biri Segment ve TotalSegments aracılığıyla tablonun bir Segment'ini sahiplenir, böylece birden çok worker onu eşzamanlı olarak okur. Tüm tabloyu tek bir partition'ın throughput'unun izin verdiğinden daha hızlı okumanın tek yoludur — ancak yine de tam bir okumadır, dolayısıyla taranan her item için ödersiniz.

  • Sıralı bir Scan her seferinde tek bir partition okur — hızı, tablo ne kadar büyük olursa olsun, tek bir partition'ın throughput'uyla sınırlıdır.
  • Segment + TotalSegments okumayı parçalar TotalSegments worker'a; her worker kendi dilimini paralel olarak tarar.
  • DynamoDB segment atamak için partition key'i hash'ler, dolayısıyla dilimler dengesiz olabilir — daha fazla worker her zaman daha hızlı demek değildir.
  • O hâlâ bir Scan'dir: her item'ı okumak için ödersin ve şişman bir parallel scan, tablonun throughput'unu canlı trafiğinin altından çekip alabilir.

Sıralı bir Scan neden yavaştır

SQL'den geliyorsan, tam tablo okuması tek bir akış operasyonu gibi hissettirir. DynamoDB'de öyle değil. Tablonun verisi birçok fiziksel partition üzerinde yaşar, ama tek bir Scan onları her seferinde bir tane, sayfa başına 1 MB gezer.

Bu, düz bir Scan'in herhangi bir anda yalnızca tek bir partition'ın throughput bütçesinden çekebileceği anlamına gelir — tablo, boş kapasiteli onlarca partition'a yayılmış olsa bile. Tablo ne kadar büyükse, o kadar uzun süre sürünür. (AWS: Parallel scan)

Okumayı Segment ve TotalSegments ile böl

Bir parallel scan darboğazı düzeltir. Bir worker sayısı seçersin, TotalSegments'i o sayıya ayarlarsın ve her worker'a sıfırdan başlayan ayrı bir Segment verirsin. Her worker kendi Scan'ini gönderir; DynamoDB onları eşzamanlı olarak sunar.

Worker 0Scan  Segment=0  TotalSegments=4
Worker 1Scan  Segment=1  TotalSegments=4
Worker 2Scan  Segment=2  TotalSegments=4
Worker 3Scan  Segment=3  TotalSegments=4

Her worker yine LastEvaluatedKey ile bağımsız olarak sayfalar — segment'ine ilk sayfadan son sayfaya sahiptir. Uygulama dört akışı tekrar bir araya diker. Artık bir yerine dört partition'lık throughput'u aynı anda okuyorsun.

İşlenmiş bir örnek: geceki export

Diyelim ki bir telemetri tablosu, sensor-readings, çalıştırıyorsun. Her item bir saha cihazından bir okumadır:

PK = "DEVICE#a83f"          (partition key — cihaz id'si)
SK = "TS#2026-06-22T03:14"  (sort key — ISO timestamp)
batteryMv  = 3120
tempC      = 41.8
firmwareTag = "fw-7.2.1"

Her gece bir cron job tüm tabloyu analitik warehouse için S3'e döker. 80 GB'lık sıralı bir Scan saatler sürer ve sağlanan okuma kapasitene zar zor dokunur. Yani onu sekiz worker'a yayarsın:

Scan  sensor-readings  Segment=0  TotalSegments=8  ConsistentRead=falseScan  sensor-readings  Segment=7  TotalSegments=8  ConsistentRead=false

Sekiz worker, sekiz segment, bir tablo okuması kabaca sekiz kat daha hızlı. Yalnızca son okumalara ihtiyacın varsa, satırlar tele çarpmadan önce eski timestamp'leri atmak için bir FilterExpression ekle — o expression'ı Expression Builder içinde oluştur ve incele:

FilterExpression:  begins_with(SK, :today)

DynamoDB item'ları segment'lere nasıl atar

İnsanları tökezleten kısım burası. DynamoDB her item'ı bir segment'e partition key'ini hash'leyerek atar — satır sayısına göre değil, bayt sayısına göre değil.

Yani bir PK'yı paylaşan her item aynı segment'e iner. sensor-readings'te, DEVICE#a83f'in tüm okumaları, o cihazın kaç timestamp'i olduğuna ya da item koleksiyonunun ne kadar büyük olduğuna bakılmaksızın tek bir worker'a gider. (AWS: Parallel scan)

sensor-readings tablosupartition key'i hash'leSegment 0DEVICE#a83fDEVICE#1c20Segment 1DEVICE#9be4Segment 2 (boş)

Sonuç: segment'ler dengesizdir. Bir worker milyonlarca okuması olan üç geveze cihazı sahiplenebilir; bir başkası boş bir dilim çekebilir. Partition key'lerin kümeleniyorsa TotalSegments'i daha yükseğe çekmek yardımcı olmaz — yalnızca sıcak olanı bekleyen boş worker'lar eklersin. Fan-out'u kazançlı kılan şey, eşit key dağılımıdır.

Çalıştırmadan önce okuma maliyetini gör

Bir parallel scan bir throughput olayıdır, bedava bir öğle yemeği değil. Dürüst soru "bu tüm tabloyu okumak kaç okuma birimine mal olacak?" — ve DynoTable, gerçek tablona karşı bir scan'in ölçülen okuma maliyetini, segment segment gösterir, böylece geceki job seni faturada şaşırtmaz.

Tuzaklar ve ne zaman uğraşmamalı

  • Throughput uçurumu. Yüksek-TotalSegments'li bir scan, tablonun tüm okuma kapasitesini saniyeler içinde tüketebilir, canlı trafiği aç bırakır. Kullanıcılara hizmet veren bir tabloda, her worker'ı Limit parametresiyle kısıtla ya da yoğun olmayan saatlerde tara. (AWS: Parallel scan)
  • Bir erişim deseni için hâlâ yanlış araçtır. Parallel scan'ler kasıtlı tam tablo işleri içindir — export'lar, geri doldurmalar, taşımalar. Tekrarlayan bir sorguyu cevaplamak için birine uzanıyorsan, bu bir modelleme sinyalidir: bir GSI ekle ve onu bir Query yap.
  • PartiQL'deki SELECT * kılık değiştirmiş aynı scan'dir. Sıralı bir Scan'e derlenir. Gerçekten item'lar arası analitiğe ihtiyacın olduğunda — bir GROUP BY, bir JOIN, bir toplam — DynoTable'ın SQL Workbench'i bunları, tabloyu dövmek yerine sınırlı bir sonuç kümesi üzerinde istemci tarafında çalıştırır.
  • Güçlü tutarlılık faturayı ikiye katlar. Bir Scan varsayılan olarak nihai tutarlı okumalara ayarlıdır. Bir export için, gerçekten bir zaman noktası anlık görüntüsüne ihtiyacın olmadıkça ConsistentRead=false bırak.

Sonraki adımlar

Key'lerini, günlük okumaların asla bir scan'e ihtiyaç duymayacağı şekilde modelle — single-table design ve Query vs Scan ile başla. Bir tam tablo işi gerçekten doğru karar olduğunda, kendi tablolarına karşı bir parallel scan çalıştırmak ve okuma maliyetini gerçek zamanlı izlemek için DynoTable'ı dene.

Güncellendi