DynamoDB Bölüm Anahtarları Nasıl Çalışır
bir adrestir. DynamoDB o anahtarı hash'ler ve hash, öğeyi hangi fiziksel makinenin saklayacağına karar verir. Anahtarı iyi seçin, yük yayılır; kötü seçin, ısıyı tek bir sunucu çeker.
DynamoDB bölüm anahtarları nasıl çalışır?
DynamoDB dahili bir hash fonksiyonundan geçirir ve o hash, öğeyi hangi fiziksel bölümün saklayacağına karar verir. Yerleşime hash karar verir; anahtar bir SQL sütunu gibi sıralanmaz ya da dizinlenmez. Yüksek kardinaliteli bir anahtar seçin, yük birçok bölüme yayılır; düşük kardinaliteli birini seçin, ısının tamamını tek bir bölüm çeker.
- Anahtar sıralanmaz, hash'lenir. DynamoDB bir bölüm seçmek için bölüm anahtarınızı dahili bir hash'ten geçirir. Birbirine komşu iki değer diskte birbirinin yakınına düşmez.
- Bölüm gerçek bir depolama birimidir. Her biri kabaca 10 GB, saniyede 3.000 okuma birimi ve saniyede 1.000 yazma biriminde tavan yapar. Trafiğiniz, anahtarlarınızın kaç bölüme yayıldığına bölünür.
- Asıl tuzak sıcak anahtarlardır. İsteklerin çoğunu tek bir bölüm anahtarı değerine hunilerseniz, tablonun geri kalanı boş dururken o bölümde kısıtlanırsınız.
- Yüksek kardinaliteli anahtarlar kazanır. Ne kadar çok farklı ve dengeli isabet alan anahtar değeriniz varsa, yükü o kadar çok bölüm emer.
Anahtarın gerçekte ne yaptığıyla başlayın
SQL'den gelirken birincil anahtar, üzerinde JOIN ve ORDER BY yaptığınız sıralı ve
dizinli bir sütundur. DynamoDB'de bölüm anahtarı (bazen hash anahtarı da denir) başka
bir iş yapar: yerleşime karar verir.
DynamoDB bölüm anahtarını dahili bir hash fonksiyonuna verir. Çıktı bir anahtar uzayına eşlenir ve anahtar uzayı aralıklara dilimlenir — her aralığın sahibi bir fiziksel bölümdür. O bölüm, gerçek bir düğüm üzerindeki gerçek depolamadır.
Yani bölüm anahtarı tek bir soruyu yanıtlar: bu öğeyi hangi makine tutuyor? Varsa yalnızca öğeleri o makinenin içinde sıralar. Yerleşimde hiçbir rolü yoktur.
Tek bir yazmayı hash boyunca izleyin
Diyelim ki cihaz ölçümlerini toplayan bir SaaS işletiyorsunuz. SensorReadings
tablonuz deviceId bölüm anahtarını ve readingTs sıralama anahtarını kullanıyor.
deviceId = "vac-7741" için bir ölçüm yazıyorsunuz.
O yazmanın izlediği yol — anahtarınızdan indiği diske kadar:
vac-7741 için yazma, anahtar uzayında bir noktaya hash'lenir, o nokta P2'nin aralığına
düşer ve öğe P2'ye iner — orada readingTs'e göre sıralanır.
İçselleştirilmesi gereken şu: "vac-7741" ile "vac-7742" tek karakter farklıdır, ama
hash'leri birbiriyle ilgisizdir. Neredeyse kesinlikle farklı bölümlerde yaşarlar. Bölüm
anahtar uzayında "yakın" diye bir şey yoktur.
Bu, DynamoDB'nin özgün tasarımdan devraldığı tutarlı hash'leme fikridir — 2007 Amazon Dynamo makalesi ("Dynamo: Amazon's Highly Available Key-value Store") anahtarları düğümlere tam da hiçbir düğüm darboğaza dönüşmesin diye hash'leyerek yaydı.
Bir hash'in değerleri kovalara nasıl saçtığını görmek için aşağıya bölüm anahtarı değerlerinden oluşan bir liste yapıştırın. Yüksek kardinaliteli bir küme dengeli yayılır; tek bir değeri tekrar tekrar kullanın, hepsi tek bir kovada yığılır — bir sonraki bölümün konusu olan .
Bu, sezgi kazandırmak için bir öğretim hash'idir, DynamoDB'nin gerçek dahili hash'i değildir — asıl fonksiyon, anahtar uzayı ve bölüm sınırları AWS'nin iç işleyişidir. Onu bir anahtarın hangi fiziksel bölüme düşeceğini tahmin etmek için değil, yayılma ile çarpıklık arasındaki farkı hissetmek için kullanın.
Bölümün katı sınırlarına saygı gösterin
Fiziksel bir bölüm sonludur. AWS DynamoDB Developer Guide'a göre her biri kabaca şu kadarını tutar:
| Sınır | Bölüm başına |
|---|---|
| Depolama | ~10 GB |
| Okuma throughput'u | saniyede 3.000 okuma birimi |
| Yazma throughput'u | saniyede 1.000 yazma birimi |
Bir bölüm 10 GB'ı aşacak kadar dolduğunda ya da sağlanan throughput'unuz daha çok yer istediğinde DynamoDB onu böler — anahtar uzayı aralığı ikiye ayrılır ve öğeler daha fazla bölüme dağılır. Bu otomatiktir; siz tetiklemezsiniz.
Bir bölme, tek bir bölüm anahtarının öğe koleksiyonunu sıralama anahtarı sınırında ayırabilir; böylece yoğun bir anahtarın yükü daha fazla bölüme yayılabilir. Bölmenin kurtaramayacağı şeyler ise tek bir sıcak öğe, hep artan bir sıralama anahtarı ya da LSI'ı olan bir tablodur — bunlar koleksiyonu tek bir bölüme sabitler.
Tuzağı adıyla anın: sıcak bölüm
Sıcak bölüm klasik tuzaktır. Tek bir bölüm anahtarı değeri (ya da çok küçük bir grubu) trafiğin orantısız bir payını emdiğinde ortaya çıkar.
Somut bir hata: SensorReadings tablosunu "us-east", "eu-west" gibi değerler alan
bir region bölüm anahtarına geçiriyorsunuz. Üç bölge, üç anahtar değeri demek; bu da —
en fazla — gerçek iş yapan üç bölüm demek. "us-east"i okumalarla dövün, tablonun toplam
sağlanan kapasitesi kullanılmadan dururken 3.000 RCU'da kısıtlanır.
DynamoDB'nin adaptive capacity özelliği bunu yumuşatır — kullanılmayan throughput'u yoğun bir bölüme kaydırabilir ve çok sıcak tek bir anahtarı kendi bölümüne izole edebilir. AWS bunu re:Invent'teki "Advanced Design Patterns for DynamoDB" derinlemesine oturumlarında anlattı. Ama adaptive capacity bağışıklık değil, zaman kazandırır: tek bir sıcak öğe, hep artan bir sıralama anahtarı ya da bir LSI yine tek bir anahtarı tek bir bölümle sınırlar. Yayılmaya göre tasarlayın; emniyet ağına yaslanmayın.
Yüksek kardinaliteli bir anahtar seçin
Çözüm kardinalitedir — farklı anahtar değerlerinin sayısı ve trafiğin onlara ne kadar dengeli çarptığı.
- Düşük kardinalite (
region,status,true/false): az bölüm, trafik yoğunlaşır, erkenden kısıtlanırsınız. - Yüksek kardinalite (
deviceId,userId, bir sipariş kimliği): birçok bölüme hash'lenen çok sayıda değer, yük yayılır, pay büyür.
SQL'den gelirken bir status sütununu memnuniyetle dizinler ve üzerinde filtrelerdiniz.
DynamoDB bölüm anahtarı olarak bu bir tuzaktır — yayılamaz. Düşük kardinaliteli
attribute'ları filtre olarak ya da bir
ikincil dizinin sıralama anahtarı olarak tutun, asla
yerleşime karar veren şey olarak değil.
Doğal olarak iyi bir anahtar bile çarpıklaştığında — bir avuç dev kiracı diğerlerini
gölgede bıraktığında — tek bir mantıksal değeri N bölüme yaymak için sonek ekleyin,
örneğin shard'lanmış bir yazma yolu için tenantId#3. Okumada yeniden birleştirirsiniz.
Anahtarınız yayıldıktan sonra bir bölümün içindeki öğeleri hedeflemek için sıralama
anahtarı üzerinde bir KeyConditionExpression yazacaksınız. Bunu koda bağlamadan önce
kendi şemanıza karşı
DynamoDB expression builder içinde kurabilirsiniz:
deviceId = "vac-7741" AND readingTs BETWEEN "2026-06-01" AND "2026-06-30"
Bu, tek bir cihazın haziran penceresini tek bir bölümden okur — bir Query, bir
Scan değil. Bölüm anahtarı makineyi sabitler; sıralama
anahtarı koşulu satırları daraltır.
Tuzaklar ve sonraki adımlar
- Anahtarı SQL'de iyi okunduğu için seçmeyin. Onu neyin yaydığına göre seçin. Önce kardinalite, sonra sorgu kolaylığı.
- Tablonun toplam kapasitesinin anahtar başına size ait olduğunu varsaymayın. Throughput bölüm başınadır; tablo boş görünürken tek bir sıcak değer kısıtlanabilir.
- Bölmeye karşı savaşmayın. Otomatiktir ve hash tarafından yönlendirilir — sizin işiniz, ona yayılacak yeterince farklı anahtar vermektir.
Anahtarınız temiz biçimde yayıldıktan sonraki kararlar, öğeleri bir bölümün içinde nasıl yerleştireceğiniz — bkz. tek tablo tasarımı — ve ikinci bir erişim deseni için ikincil dizinin doğru araç olup olmadığıdır.
DynoTable'ı indirin ve SQL Workbench'te bölüm anahtarınız üzerinde bir
GROUP BY çalıştırarak, biri sıcak bölüme dönüşmeden önce hangi anahtarların öğe
yığdığını görün.