İleri6 dakikalık okuma

Kesintisiz DynamoDB Migration'ları

SQL'den geliyorsan migration, her satırı yeniden yazarken tabloyu kilitleyen bir ALTER TABLE'dır. DynamoDB'de değiştirilecek şema yok — öğeler schemaless'tır, bu yüzden bir attribute veya yeni bir entity tipi eklemek bedavadır.

Zor kısım, yeni verinin hizmet etmesi gereken erişim deseni ve canlı veriyi dünyayı durduran bir yeniden yazma olmadan o desene hizmet edecek şekilde yeniden şekillendirmektir.

DynamoDB tablosunu kesintisiz nasıl migrate edersin?

DynamoDB'de ALTER TABLE yoktur, migration'lar tabloyu asla kilitlemez. Attribute, yeni bir key şekli veya yeni bir 'yi UpdateTable ile online ekler, sonra canlı veriyi artımlı yeniden şekillendirirsin: eski öğeleri okumada lazy backfill veya kısıtlı bir tarama ile doldurur, geçiş boyunca her iki formatı da dual-write edersin. Flag-day cutover yoktur.

  • ALTER TABLE yoktur. Öğeler schemaless'tır. Bir "migration" attribute, yeni bir key şekli veya yeni bir indeks eklemek demektir — sabit bir sütun kümesini yeniden yazmak değil.
  • Yeni yazmalar kolaydır; sorun eski öğelerdir. Mevcut satırlar yeni attribute'ları taşımaz, bu yüzden yeni indeks veya sorgu onları backfill edene kadar sessizce kaçırır.
  • İndeksleri online ekle, lazy backfill et. UpdateTable canlı tabloda GSI kurar; eski öğeleri okumada (lazy) veya kontrollü bir tarama ile backfill et — asla flag-day cutover değil.
  • Geçiş boyunca dual-write. İki şekil bir arada yaşarken eski ve yeni formatı birlikte yaz ki hiçbir okuma yolu bayatlamasın.

Bunu sütun değil erişim deseni olarak çerçevele

Diyelim tek tabloda bir SaaS workspace ürünü çalıştırıyorsun. Öğeler PK = "WS#<id>" ve entity başına SK kullanır:

PKSKattributes
WS#a91METAname, tier
WS#a91DOC#2026-04-01#x7title, author, body
WS#a91DOC#2026-04-02#k2title, author, body

Şimdi ürün belgeler üzerinde yorum istiyor, artı yeni bir okuma: "bir üyenin workspace genelinde yazdığı her yorumu listele, en yeniden eskiye." Migration o son cümledir. Yalnızca yeni bir entity tipi önemsizdir; mevcut anahtarların yanıtlayamayacağı bir sorguyu servis etmek asıl iştir.

Önce yeni entity tipini ekle

Yorumlar aynı partition'da yalnızca yeni öğelerdir — migration töreni yok, yeni tablo yok:

PKSKattributes
WS#a91DOC#2026-04-01#x7#CMT#01HZ...author, text, createdAt

PK = "WS#a91" üzerinde SK begins_with "DOC#2026-04-01#x7#CMT#" ile bir Query zaten bir belgenin yorumlarını listeler. Mevcut belgelere dokunulmaz. Bu yarı birinci günde çıkar — aynı partition'ın ikisini de neden tuttuğu için bak item collections and overloaded keys.

Yeni sorgu bir GSI ister

"Bir üyenin tüm yorumları, en yeniden eskiye" base table tarafından servis edilemez — memberId ne PK ne de bir SK önekidir. Bu yeni bir indekstir ve doğru seçmek kendi kararıdır: bak GSI vs LSI (bir LSI tablo oluşturmada var olmalıdır, bu yüzden canlı tabloda migration için tek seçeneğin GSI'dir).

Genel bir GSI1 ekle ve yeni attribute'ları yeni yorum öğelerine yaz:

GSI1PKGSI1SK
MEMBER#u442026-04-02T09:15:00Z

ScanIndexForward = false ile Query GSI1 WHERE GSI1PK = "MEMBER#u44" üye başına en yeniden eskiye yorumları verir.

İndeksi online kur

UpdateTable canlı bir tabloya kesintisiz GSI ekler. DynamoDB mevcut öğeleri arka planda indekse backfill eder; indeks bitene kadar CREATING/backfilling raporlar, sonra ACTIVE'e döner (Managing GSIs).

UpdateTable: GSI1 ekleİndeks durumu: CREATINGMevcut öğeleri backfill etDurum: ACTIVEGSI1 Query güvenli

Burada iki tuzak var. Birincisi, AWS yeni bir eklemenin yeni anahtar düzensiz dağılırsa base-table yazmalarını kısıtlayabileceğini uyarır — düşük trafik penceresinde ekle ve CloudWatch'u izle. İkincisi, indeks ACTIVE olduktan sonra bile ; bir yazma bir an GSI'de görünmeyebilir. Bak why GSIs are eventually consistent.

Eski öğeleri backfill et

GSI yalnızca GSI1PK/GSI1SK taşıyan öğeleri indeksler. Migration öncesi yorumların — attribute var olmadan önce yazılmış — backfill bitse bile asla görünmez. Online GSI backfill mevcut öğeleri kopyalar ama üzerlerinde olmayan attribute'ları icat edemez. Değerleri sen eklemelisin.

İki strateji:

StratejiNasıl çalışırNe zaman kullan
LazyEski bir öğeyi okurken yeni attribute'ları geri yazEski öğeler sık okunur; maliyeti damlat
SweepSayfalanmış bir Scan her eski öğeyi bir kez güncellerGSI'nin bir deadline'a tamamlanması gerek

Sweep için Scan ile sayfala ve her eski yoruma, eşzamanlı bir yazmayı asla ezmemek için koşullu UpdateItem ile indeks attribute'larını ekle.

Koşul, attribute'un henüz var olmamasını korur. Tam ConditionExpression ve UpdateExpression'ı elle attribute_not_exists(GSI1PK) yazmak yerine DynamoDB Expression Builder ile kur ve kopyala.

Geçiş boyunca dual-write

Her eski öğe yeni attribute'ları taşıyana kadar iki şekil bir arada yaşar. Yazma yolu her yazmada — yeni yorumlar ve eski birine her güncelleme — yeni formatı doldurmalıdır ki boşluk yalnızca küçülsün.

Doğrulayabileceğin bir backfill bitiş koşulu seç: sweep tüm tabloyu sayfaladı, veya lazy yol dönüştürülmemiş öğelerin tasarım gereği bayat olduğu kadar uzun koştu. Ancak o zaman eski okuma yolunu kaldırırsın. Bunu atlamak, sorguların bir kısmı sessizce kısa sonuç dönerken migration'ın "bitmesinin" yoludur.

Backfill sırasında yeni indeks attribute'ları eksik öğeleri bulmak için DynoTable'da bir tabloyu sayfalama.
Backfill sırasında yeni indeks attribute'ları eksik öğeleri bulmak için DynoTable'da bir tabloyu sayfalama.

Tuzaklar

  • Attribute eklemek ≠ backfill edilmiş. Yeni bir GSI eski öğeler için boş başlar. Sorguya güvenmeden önce coverage'ı doğrula.
  • Yerinde bir anahtarı değiştirmek bir yeniden yazmadır. Bir öğenin PK/SK'sini mutate edemezsin; yeni anahtar altında yeni bir öğe yazar ve eskisini silersin. Bunu kopyala-sonra-sil, arada dual-read olarak planla.
  • İşlemsel cutover yoktur. Tüm tablonun döndüğü bir an yoktur. Her adımı her iki şekil canlıyken güvenli olacak şekilde tasarla.

Sonraki adımlar

Yeni anahtarları ve aşırı yüklenmiş collection'ları single-table design içinde doğrula ve backfill'in tamamlandığını canlı tabloyu sayfalayarak onayla. Tablonuna göz atmak, backfill edilmemiş öğeleri bulmak ve koşullu güncellemeleri kendi verine karşı çalıştırmak için DynoTable'ı dene.

Güncellendi