Orta7 dakikalık okuma

DynamoDB Sıcak Bölümler (Hot Partitions)

DynamoDB verilerinizi her biri kendi verim dilimine sahip birçok fiziksel bölüme yayar. Sıcak bölüm (hot partition), bir anahtarın diliminin sunabileceğinden çok daha fazla okuma ya da yazma çekmesidir — böylece o anahtara giden istekler kısıtlanırken tablonun geri kalanı boş durur.

DynamoDB sıcak bölüm (hot partition) nedir?

DynamoDB sıcak bölüm (hot partition), tek bir bölüm anahtarının kendi verim diliminin sunabileceğinden çok daha fazla okuma ya da yazma çekmesidir; böylece o anahtara giden istekler kısıtlanırken tablonun geri kalanı boş durur. Sebep anahtar tasarımıdır — ünlü bir öğe, düşük kardinaliteli bir anahtar, bugünün tarihi — tablo boyutu değil. Çare ise yazmaları yaymaktır.

  • Sebep tablo boyutu değil, anahtar tasarımıdır. Trafiği tek bir bölüm anahtarında yoğunlaştırmak — ünlü bir kullanıcı, bir status="OPEN" bayrağı, bugünün tarihi — tuzaktır.
  • Uyarlanabilir kapasite (adaptive capacity) yardımcı olur ama bir çözüm değildir. DynamoDB ısıyı otomatik olarak yeniden dengeler, yine de tek bir öğe veya tek bir anahtar, tek bir bölümün sunabileceğini aşabilir.
  • Çare, yazmaları yaymaktır. Anahtara entropi ekleyin (yazma sharding'i) ya da sıcak okuma yolunu daha iyi dağıtılmış bir erişim deseni üzerine taşıyın.
  • SQL'den geliyorsanız bunun bir karşılığı yoktur. İlişkisel bir tablonun "bir satırın indeks değeri fazla popüler" diye bir kavramı yoktur — DynamoDB'nin düz, anahtar başına verim modelinin ise vardır.

Bölümler neden var

DynamoDB, tek düğümlü SQL modelini bölümlü, yatay ölçeklenen bir modelle takas eden 2007 tarihli Amazon Dynamo makalesinin üretim mirasçısıdır. Veriler, bölüm anahtarının bir hash'iyle fiziksel depolama düğümlerine dağıtılır.

Her bölüm sınırlı bir miktar veri tutar ve sınırlı bir miktar verim sunar. AWS, saniyede bölüm başına 3.000 okuma birimi ve 1.000 yazma birimi sabit bir tavan belgeler (AWS — bölüm davranışı).

Bütün hikâye bu tavandır. Tablonuzun sağlanan verimi tüm bölümler boyunca toplamdır — ama herhangi bir anahtar yalnızca tek bir bölüme düşer.

Tuzağı adlandıralım: tek bir anahtara yığılan trafik

Verim, yalnızca erişiminiz anahtarlar arasında eşit yayıldığında eşit paylaşılır. Bir anahtar orantısız trafik aldığı anda, tablonun toplam kapasitesi kullanılmadan dururken o anahtar tek başına kısıtlanır.

Klasik sıcak anahtar biçimleri:

  • Ünlü öğe — herkesin okuduğu tek bir kullanıcı, ürün ya da kiracı.
  • Düşük kardinaliteli bölüm anahtarıstatus, country, type. Az sayıda farklı değer, tüm işi yapan az sayıda bölüm demektir.
  • Zaman kovalı anahtarPK = "2026-06-23". Bugünün her yazması tek bir bölümü döver; dünkü ise sonsuza dek soğuktur.

SQL'den geliyorsanız bunların hiçbiri önemli olmazdı. Popüler bir değer üzerindeki bir B-ağacı indeksi sorun değildir. DynamoDB'de popüler değer fiziksel yerleşimin birimi olduğu için, popülerlik bir verim uçurumuna dönüşür.

İşlenmiş bir örnek: ünlü liderlik tablosu

Diyelim ki küresel bir oyun liderlik tablosu işletiyorsunuz. Skorlar şöyle anahtarlanmış bir tabloda yaşıyor:

PK = "BOARD#global"
SK = "PLAYER#<playerId>"

Okumalar skora göre en üst N'i alır; yazmalar her maçtan sonra bir oyuncunun currentScore değerini günceller. Küresel tablodaki her satır tek bir bölüm anahtarını paylaşır — BOARD#global — yani her okuma ve yazma tek bir bölüme düşer.

Buna kendi sırasını yenilemek için yenile düğmesine basıp duran iki milyon canlı izleyiciye sahip bir yayıncı ekleyin; o tek bölüm 3.000 okuma birimini aşar. Tablodaki diğer her tablo boştayken küresel tabloda ProvisionedThroughputExceededException alırsınız.

Asıl tuzak BOARD#global çöküşüdür: tek bir mantıksal tabloyu tek bir fiziksel anahtar olarak modellediniz.

Yazmaları yayın: anahtarı sharding'leyin

Çözüm, kardinalite üretmektir. Bölüm anahtarına bir shard soneki ekleyerek tek bir mantıksal tabloyu N fiziksel bölüme yayın:

PK = "BOARD#global#<shard>"  -- shard = playerId mod 10
SK = "PLAYER#<playerId>"

Yazmalar artık birin yerine on bölüme dağılır — on kat yazma payı. Bedeli: tüm tablonun bir okuması on shard'ın hepsine erişip birleştirmek zorundadır, çünkü tek bir Query shard sınırlarını aşmaz. Okuma basitliğini yazma dağıtımıyla takas edersiniz.

AWS buna yazma sharding'i (write sharding) der ve tam olarak yüksek hızlı, düşük kardinaliteli anahtarlar için önerir (AWS — yazma sharding'i kullanma).

Bu, tek tablo tasarımının arkasındaki aynı anahtar aşırı yükleme içgüdüsüdür — anahtarı, verinin "doğal" olarak nasıl durduğuna göre değil, erişim desenine göre şekillendirirsiniz.

Kolay kısmı uyarlanabilir kapasiteye bırakın

DynamoDB, re:Invent 2018 oturumu "Amazon DynamoDB Under the Hood" (DAT401) içinde anlatılan uyarlanabilir kapasite (adaptive capacity) ile gelir. Bir tablonun verimini ısı alan bölümlere doğru sürekli yeniden dağıtır ve kalıcı olarak sıcak bir anahtarı kendi bölümüne izole eder (anahtar düzeyinde izolasyon, AWS — burst ve uyarlanabilir kapasite).

Anlık ve ücretsizdir — ama fizikle sınırlıdır. Uyarlanabilir kapasite ısıyı anahtarlar arasında taşıyabilir; tek bir anahtarı bölüm başına tavanın ötesine itemez. Gerçek bir ünlü anahtar yine kısıtlanır. O duvarı aşmanızı sağlayan şey sharding'dir.

Yoğun bir anahtarda kısıtlamalar gördüğünüzde izlenecek karar yolu şudur:

EvetHayır, aynı öneklibirçok anahtarEvetHayırTek bir anahtardakısıtlama var?Tek öğefazla sıcak?Anahtarı sharding'leya da okumayı önbelleğe alDüşük kardinalitelibölüm anahtarı mı?Önekiyazma-sharding'leUyarlanabilir kapasitemuhtemelen halleder

Çoğu sıcak bölüm ya "anahtarı sharding'le" ya da "uyarlanabilir kapasitenin emmesine izin ver" ile çözülür — şema yalnızca hangi dalda olduğunuzu gösterir.

Yeniden tasarlamadan önce teşhis edin

Göremediğinizi düzeltemezsiniz. Kısıtlama, ProvisionedThroughputExceededException (sağlanan) olarak ya da CloudWatch'ta ThrottledRequests ve bölüm başına ThrottleCount olarak görünür (AWS — CloudWatch metrikleri).

Bunu, en çok erişilen anahtarlarınızı doğrudan sıralayan CloudWatch Contributor Insights for DynamoDB ile eşleştirin — bir ünlü anahtarı ismiyle doğrulamanın en hızlı yolu budur (AWS — Contributor Insights).

Sharding'lenmiş okuma yolunu test ederken, her shard için KeyConditionExpression'ı elle kuracaksınız. Bunları yazım hatası olmadan üretmek için DynamoDB Expression Builder aracını kullanın — her shard için tam olarak PK = :pk AND begins_with(SK, :sk) biçimini üretir.

Kaçınılması gereken tuzaklar

  • Otomatik artan ya da monoton anahtarlar. Bölüm anahtarı olarak sıralı kimlikler ve zaman damgaları, ardışık yazmaları aynı bölüme yönlendirir. Bir hash öneki ekleyin.
  • Okuma ağırlıklı yolu gereksiz yere sharding'lemek. Okumalar baskınsa ve öğe küçükse, bir önbellek ya da daha iyi dağıtılmış bir anahtara sahip bir GSI, genellikle sharding'in scatter-gather okuma maliyetini yener.
  • Sıcak bölümü yavaş bir Scan ile karıştırmak. Bir Scan yavaştır çünkü her şeyi okur; sıcak bölüm kısıtlanır çünkü tek bir anahtar aşırı yüklenmiştir. Farklı sorunlar — bkz. Query vs Scan.

Sonraki adımlar

Sharding'lenmiş anahtarları çizin, ardından okuma yolunu gerçek veriyle kanıtlayın. DynamoDB Expression Builder içinde shard başına koşulları oluşturun ve bunları kendi tablolarınıza karşı çalıştırıp hangi bölümlerin gerçekten ısındığını izlemek için DynoTable'ı indirin.

Güncellendi