DynamoDB depolama iç yapısı nasıl çalışır
DynamoDB, değerleri sıralı ağaçlar olan ve üç Erişilebilirlik Bölgesindeki makinelere yayılmış bir hash tablosudur. Neredeyse bütün işi iki veri yapısı yapar: üzerindeki bir hash makineyi seçer, üzerindeki bir B-ağacı öğeleri makinenin içinde sıralar.
DynamoDB veriyi nasıl saklar?
DynamoDB verinizi, değerleri sıralı B-ağaçları olan dev bir dağıtık hash tablosu olarak saklar. üzerindeki bir hash tek bir depolama düğümü seçer; düğümün içinde bir B-ağacı öğeleri sıralama anahtarına göre sıralar. Her yazma, üç Erişilebilirlik Bölgesindeki iki eşe çoğaltma yapan bir lidere gider ve çoğunluk (üç kopyadan ikisi) yazıyı aldığında onaylanır.
- Bölüm anahtarı aranmaz, hash'lenir. DynamoDB, o bölümü tutan depolama düğümünü (ya
da büyük bir koleksiyon bölündüğünde düğümleri) bulmak için
PKüzerinde bir hash fonksiyonu çalıştırır — tablo boyutundan bağımsız, O(1) bir sıçrama. - Sıralama anahtarı bir B-ağacında yaşar. Bir bölümün içinde öğeler, sıralama
anahtarına göre sıralı bir B-ağacında saklanır — dizeler için UTF-8 bayt sırası,
Number anahtarlar için sayısal sıra. Aralık okumalarının (
begins_with,between) ucuz,Scan'in ise pahalı olmasının nedeni budur. - Her yazma onaylanmadan önce bir çoğunlukta commit olur. Yazma bir lidere gider;
lider onu diğer AZ'lerdeki iki eşe çoğaltır ve çoğunluk (üç kopyadan ikisi) yazıyı
aldığında onaylar — dayanıklılık,
PutItemçağrınız dönmeden önce satın alınır. - Erişim deseni kuralları bu yüzden var. Önce-hash-sonra-ağaç yalnızca anahtarla okuduğunuzda hızlıdır. Anahtar yoksa hızlı yol da yoktur — ağacı taramaya düşersiniz.
API'den değil, veri yapısından başlayın
SQL'den gelirken bir tabloyu, dizin seçen bir sorgu planlayıcısıyla birlikte diskteki satırlar olarak canlandırırsınız. DynamoDB'de planlayıcı yoktur. Sözleşmenin kendisi depolama yerleşimidir — neyin hızlı, neyin tuzak olduğu doğrudan iki yapıdan çıkar.
Dev bir dağıtık harita düşünün. Anahtar, bölüm anahtarınızın hash'idir. Değer ise o bölüm anahtarını paylaşan, sıralama anahtarına göre sıralı öğelerden oluşan bütün bir B-ağacıdır.
Geri kalan her şey — sorgu semantiği, 10 GB uyarıları, eksik bir anahtarın neden Scan'e
zorladığı — bu tek cümlenin sonucudur.
Düğümü bulmak için bölüm anahtarını hash'leyin
Bir istek geldiğinde DynamoDB, bölüm anahtarı değerine dahili bir hash fonksiyonu uygular. Hash, deterministik olarak tek bir depolama düğümüne eşlenir — o öğelere sahip olan fiziksel bölüme. AWS bunu, tablo boyutundan bağımsız sabit zamanlı anahtar aramalarının ardındaki mekanizma olarak belgeliyor.
O(1) adımı budur. 10 TB'lık bir tabloyu bulmak, 10 KB'lık bir tabloyu bulmakla aynı maliyettedir: hash'le, sıçra, bitti. Düğümü bulmak için dizin taraması, istatistik ya da plan yoktur.
İşin öteki yüzü ise şu: bölüm anahtarını vermezseniz DynamoDB'nin sıçrayacağı bir düğüm
kalmaz — her bölümü gezmek zorunda kalır. Bu bir Scan'dir ve O(1) ile tüm tabloyu
okumak arasındaki farktır.
İstek tam olarak tek bir bölüme hash'lenir, sonra o bölümün sıralama anahtarı B-ağacında öğeye iner — tablo gezintisi yerine iki ucuz adım.
Öğeleri bölüm başına bir B-ağacında sıralayın
Tek bir bölümün içinde öğeler bir yığın değildir. Sıralama anahtarıyla anahtarlanmış
bir B-ağacında, sözlük düzeninde tutulurlar. B-ağacı araması O(log n)'dir ve önemli
olan şu: buradaki n tüm tablodaki değil, tek bir bölümdeki öğe sayısıdır.
Sıralama anahtarı aralık okumalarının ucuz olmasının tek nedeni budur. Her cihazın ölçümlerinin tek bir bölüm anahtarı altında yaşadığı bir filo telemetri tablosunu düşünün:
| PK | SK |
|---|---|
| PK = DEVICE#a91 | SK = READING#2026-06-23T08:00Z |
| PK = DEVICE#a91 | SK = READING#2026-06-23T08:05Z |
| PK = DEVICE#a91 | SK = READING#2026-06-23T08:10Z |
B-ağacı sıralı olduğu için "08:00 ile 09:00 arasındaki tüm ölçümler", başlangıç değerine bir ağaç inişi artı sıralı bir yürüyüştür — cihazın şimdiye kadar gönderdiği her ölçüm üzerinde bir filtre değil. Yalnızca eşleşen aralığı okursunuz.
Bir begins_with(SK, "READING#2026-06-23") sorgusunun hızlı, anahtar olmayan bir
attribute üzerinde filtrelemenin ise hızlı olmamasının nedeni de bu sıralamadır. Ağaç
SK ile arama yapabilir; başka hiçbir şeyle yapamaz. Bu anahtar koşullarını güvenli
biçimde kurmak için onları elle dize birleştirmek yerine
DynamoDB Expression Builder içinde oluşturun:
KeyConditionExpression PK = :pk AND begins_with(SK, :day)
Her yazmayı üç AZ'ye çoğaltın
Bir bölüm tek bir makine değildir. Her biri üç Erişilebilirlik Bölgesindeki üç düğüme çoğaltılır — 2022 USENIX ATC DynamoDB makalesinde ayrıntılandırılan, lider tabanlı çoğunluk tasarımı (2007 Amazon Dynamo makalesi bu çoğaltma modelinin değil, adlandırma ve felsefenin atasıdır).
Düğümlerden biri bölümün lideridir. Yazma lidere gider; lider yerelde yazar ve iki
eşine çoğaltır. Lider, dayanıklı bir düğüm çoğunluğu yazıyı aldığında yazmayı onaylar —
yani AZ'ler arası dayanıklılığın bedeli, PutItem çağrınız dönmeden önce ödenir.
Okumaların bir seçeneği vardır. bir okuma lidere gider ve en son commit edilmiş yazmayı görür. bir okuma ise üç düğümden herhangi biri tarafından karşılanabilir; bu düğümlerden biri birkaç milisaniye geride olabilir — daha ucuz ve daha erişilebilir okumalar için takas ettiğiniz gecikme budur.
| Nihai tutarlı | Güçlü tutarlı | |
|---|---|---|
| Kim karşılar | 3 düğümden herhangi biri | Yalnızca lider düğüm |
| Son yazmayı görür mü | Belki (küçük gecikme) | Her zaman |
| RCU maliyeti | Yarısı (us-east-1'de on-demand modda 4 KB başına 0,5 RCU) | Tam (4 KB başına 1 RCU) |
| Erişilebilirlik | Daha yüksek | Daha düşük (tek düğüm) |
On-demand faturalandırmada 2 KB'lık bir öğeyi güçlü tutarlı okumak 1 RCU tutar; aynı okuma nihai tutarlı yapıldığında 0,5 RCU'dur. Sıcak yollarınızı fiyat hesaplayıcıda fiyatlandırın.
Aynı eşzamansız yayılma fikri, bir GSI okumasının neden bayat olabileceğini de açıklar — bkz. GSI'lar nihai tutarlıdır.
Kuralları yapının üzerinden okuyun
Neredeyse her DynamoDB "kuralı" aslında depolama fiziğidir:
- Bölüm anahtarını her zaman verin. Anahtar yoksa hash hedefi de yoktur — tüm haritayı tarıyorsunuz demektir. Bu, Query ile Scan konusunun özüdür.
- Birlikte okuduğunuz şeyleri tek bir bölüm anahtarı altında bir arada tutun, ki tek bir hash + ağaç yürüyüşü öğe koleksiyonunun tamamını döndürsün. Bu, tek tablo tasarımının temelidir.
- Bölümleri sınırlı tutun. Bir bölüm, sonlu bir düğüm kümesi üzerindeki tek bir B-ağacıdır; kontrolden çıkmış sıcak bir anahtar da bir LSI'ın 10 GB tavanı da o fiziksel bölümün sınırlarıdır.
Önce-hash-sonra-B-ağacı şeklini bir kez gördüğünüzde erişim deseni disiplini keyfi görünmekten çıkar — sadece her okumayı hızlı yolda tutuyorsunuz.
Sonraki adımlar
Anahtarlarınızı yapıya uyacak biçimde sıralama anahtarı stratejileri ve tek tablo tasarımı ile modelleyin, sonra asıl ifadeleri DynamoDB Expression Builder içinde kurun. Bu okumaların kendi tablolarınıza karşı çalışmasını izlemek ve bir anahtar koşulunun tam olarak hangi öğeleri getirdiğini görmek için DynoTable'ı deneyin.