ЁЯЧВя╕П рдзрдбрд╛ 11 тАФ Partitioning + DynamoDB: рдкрд╕рд░рдгрд╛рд▒реНрдпрд╛ key рдиреЗ рдиреЛрдВрджрд╡рд╣реАрдЪреА рд╡рд┐рднрд╛рдЧрдгреА рдХрд░рд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 13 рдкреИрдХреА рдзрдбрд╛ 11 ┬╖ рдорд╛рдЧреАрд▓: lesson-10-replicas-and-pools ┬╖ рдкреБрдвреАрд▓: lesson-12-queues-and-blueprint
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ10, рдЖрдгрд┐ data рдЪреАрдЪ рд╡рд┐рднрд╛рдЧрдгреА: hash partitioning, partition
key, рдПрдХрд╛ key рд▓рд╛ рдмрд╣реБрддреЗрдХ traffic рдорд┐рд│рддреЗ рддреЗрд╡реНрд╣рд╛рдЪрд╛ hot partition, рддреЛ рдкрд╕рд░рд╡рдгреНрдпрд╛рд╕рд╛рдареА write-sharding,
рдЖрдгрд┐ DynamoDB рдЪреЗ per-partition capacity units (RCU рдЖрдгрд┐ WCU). scale/demo.py
рдордзрд▓реЗ shards() 1,000 keys 4 partitions рд╡рд░ hash рдХрд░рддреЗ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдиреЛрдВрджрд╡рд╣реА рдПрдХрд╛ рдХрд╛рд░рдХреБрдирд╛рд╕рд╛рдареА рдЦреВрдк рдореЛрдареА рдЖрд╣реЗ, рдореНрд╣рдгреВрди рджреАрдкрд┐рдХрд╛ рддреА 4 рдХрд╛рд░рдХреБрдирд╛рдВрд╕рд╣ 4 рдХрдкреНрдкреНрдпрд╛рдВрдордзреНрдпреЗ ЁЯЧДя╕П рд╡рд┐рднрд╛рдЧрддреЗ. рдХреЛрдгрддрд╛ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдХреЛрдгрддреНрдпрд╛ рдХрдкреНрдкреНрдпрд╛рдд? рдПрдХ рдард░рд▓реЗрд▓рд╛ рдирд┐рдпрдо: рдПрдХ рдпрдВрддреНрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рдЪреНрдпрд╛ рдирд╛рд╡рд╛рдЪреЗ рдПрдХрд╛ рдЖрдХрдбреНрдпрд╛рдд рд░реВрдкрд╛рдВрддрд░ рдХрд░рддреЗ, рдЖрдгрд┐ рддреЛ рдЖрдХрдбрд╛ рдХрдкреНрдкрд╛ рдирд┐рд╡рдбрддреЛ. рдПрдХрд╛рдЪ рдирд╛рд╡рд╛рд▓рд╛ рдиреЗрд╣рдореА рдПрдХрдЪ рдХрдкреНрдкрд╛ рдорд┐рд│рддреЛ. 1,000 рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдЕрд╕рддреАрд▓ рддрд░ рдкреНрд░рддреНрдпреЗрдХ рдХрдкреНрдкреНрдпрд╛рд▓рд╛ рд╕реБрдорд╛рд░реЗ 250. рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░рдХреВрди рд╕рд╛рд░рдЦрд╛рдЪ рд╡реНрдпрд╕реНрдд.
рдордЧ рдХреЛрдгреАрддрд░реА рдореНрд╣рдгрддреЗ: "рддреНрдпрд╛рдРрд╡рдЬреА рд╡рд░реНрдЧрд╛рдиреБрд╕рд╛рд░ рд▓рд╛рд╡реВрдпрд╛." рдирд┐рдХрд╛рд▓рд╛рдЪреНрдпрд╛ рджрд┐рд╡рд╢реА 1,000 рдкреИрдХреА 900 рдирд╡реАрди рдиреЛрдВрджреА 3A рд╡рд░реНрдЧрд╛рдЪреНрдпрд╛ рдЕрд╕рддрд╛рдд. 3A рдЪреЗ рд╕рдЧрд│реЗ рдПрдХрд╛рдЪ рдХрдкреНрдкреНрдпрд╛рдд рдЬрд╛рддреЗ. рддреНрдпрд╛ рдХрд╛рд░рдХреБрдирд╛рдХрдбреЗ рдкреНрд░рдЪрдВрдб рдХрд╛рдо, рдЖрдгрд┐ рдмрд╛рдХреАрдЪреЗ рддрд┐рдШреЗ рд░рд┐рдХрд╛рдореЗ. рдпрд╛рд▓рд╛рдЪ hot partition рдореНрд╣рдгрддрд╛рдд.
рдЙрдкрд╛рдп: 3A рдЪреНрдпрд╛ рдиреЛрдВрджреА "3A#0" рддреЗ "3A#39" рдЦрд╛рд▓реА рд▓рд┐рд╣рд╛ тАФ 40 рдЫреЛрдЯреА рд▓реЗрдмрд▓реЗ. рдпрдВрддреНрд░ рддреА рдЪрд╛рд░рд╣реА рдХрдкреНрдкреНрдпрд╛рдВрдд рдкрд╕рд░рд╡рддреЗ. рд╕рдЧрд│рд╛ 3A рд╡рд╛рдЪрд╛рдпрдЪрд╛ рдЕрд╕реЗрд▓ рддрд░ рд╕рдЧрд│реНрдпрд╛ 40 рд▓реЗрдмрд▓рд╛рдВрдирд╛ рд╡рд┐рдЪрд╛рд░рд╛.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
w["тЬПя╕П 1,000 writes"] --> h["#я╕ПтГг hash(partition key) mod 4"]
h --> p0["ЁЯЧДя╕П drawer 0"]
h --> p1["ЁЯЧДя╕П drawer 1"]
h --> p2["ЁЯЧДя╕П drawer 2"]
h --> p3["ЁЯЧДя╕П drawer 3"]
good["pupil-N тЖТ 245 ┬╖ 262 ┬╖ 249 ┬╖ 244"]
hot["class тЖТ 19 ┬╖ 31 ┬╖ 928 ┬╖ 22 ЁЯФе"]
fix["class-3A#0тАж#39 тЖТ 179 ┬╖ 253 ┬╖ 277 ┬╖ 291"]
ЁЯЧ║я╕П рд░реЗрдЦрд╛рдЯрд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/scaling/lesson-diagrams.html#l11
тЭУ рдХрд╛рдп
- Partitioning (sharding) тАФ рдПрдХ data set рдЕрдиреЗрдХ machines рд╡рд░ рд╡рд┐рднрд╛рдЧрдгреЗ, рдкреНрд░рддреНрдпреЗрдХреАрдХрдбреЗ рдПрдХ рднрд╛рдЧ. Replicas рдЪреНрдпрд╛ рдЙрд▓рдЯ, рд╣реЗ рдлрдХреНрдд reads рдирд╛рд╣реА рддрд░ write рдХреНрд╖рдорддрд╛ рдЖрдгрд┐ storage рд╡рд╛рдврд╡рддреЗ.
- Partition key тАФ row рдХреБрдареЗ рд░рд╛рд╣реАрд▓ рддреЗ рдард░рд╡рдгрд╛рд░реЗ field. Hash partitioning key рдЪрд╛ hash рдХрд╛рдвреВрди рддреНрдпрд╛ рдирд┐рдХрд╛рд▓рд╛рдиреЗ partition рдирд┐рд╡рдбрддреЗ, рдореНрд╣рдгрдЬреЗ рд╕рд╛рд░рдЦреНрдпрд╛ keys рдкрд╕рд░рддрд╛рдд.
- Hot key / hot partition тАФ рдПрдХрд╛ key рд▓рд╛ (рдХрд┐рдВрд╡рд╛ рдереЛрдбреНрдпрд╛ keys рдирд╛) рдмрд╣реБрддреЗрдХ traffic рдорд┐рд│рддреЗ. рддреЛ partition рддреНрдпрд╛рдЪреНрдпрд╛ рдорд░реНрдпрд╛рджреЗрд▓рд╛ рдкреЛрд╣реЛрдЪрддреЛ рдЖрдгрд┐ рдмрд╛рдХреАрдЪреЗ рд░рд┐рдХрд╛рдореЗ рд░рд╛рд╣рддрд╛рдд. рдЬрд╛рд╕реНрдд partitions рдиреЗ рдлрд╛рдпрджрд╛ рд╣реЛрдд рдирд╛рд╣реА: рдПрдХ key рдиреЗрд╣рдореА рдПрдХрд╛рдЪ partition рд╡рд░ рдЬрд╛рддреЗ.
- Write-sharding тАФ hot key рд▓рд╛ suffix рдЬреЛрдбрд╛ (
class-3A#0тАж#39, random рдирд┐рд╡рдбрд▓реЗрд▓рд╛ рдХрд┐рдВрд╡рд╛ рджреБрд╕рд▒реНрдпрд╛ field рд╡рд░реВрди) рдореНрд╣рдгрдЬреЗ рддрд┐рдЪреЗ writes рдкрд╕рд░рддрд╛рдд. рдордЧ reads рдирд╛ рдкреНрд░рддреНрдпреЗрдХ suffix рд▓рд╛ рд╡рд┐рдЪрд╛рд░реВрди рдПрдХрддреНрд░ рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧрддреЗ. - Amazon DynamoDB тАФ рдПрдХ key-value рдЖрдгрд┐ document database рдЬреЛ рддреБрдордЪреНрдпрд╛рд╕рд╛рдареА partitioning рдХрд░рддреЛ:
- рдкреНрд░рддреНрдпреЗрдХ partition рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд 3,000 RCU + 1,000 WCU рджреЗрддреЛ тАФ read рдЖрдгрд┐ write capacity
units, рдлрдХреНрдд "reads" рдЖрдгрд┐ "writes" рдирд╛рд╣реА:
- 1 RCU = 4 KB рдкрд░реНрдпрдВрддрдЪреНрдпрд╛ item рдЪрд╛ рджрд░ рд╕реЗрдХрдВрджрд╛рд▓рд╛ рдПрдХ strongly consistent read, рдХрд┐рдВрд╡рд╛ рддреНрдпрд╛рдЪ рдЖрдХрд╛рд░рд╛рдЪреЗ рджреЛрди eventually consistent reads;
- 1 WCU = 1 KB рдкрд░реНрдпрдВрддрдЪреНрдпрд╛ item рдЪрд╛ рджрд░ рд╕реЗрдХрдВрджрд╛рд▓рд╛ рдПрдХ write;
- рдореЛрдареЗ items рдЬрд╛рд╕реНрдд units рд╡рд╛рдкрд░рддрд╛рдд: 3 KB рдЪрд╛ write 3 WCU рдЦрд░реНрдЪ рдХрд░рддреЛ, рдореНрд╣рдгреВрди рдПрдХ partition рд╕реЗрдХрдВрджрд╛рд▓рд╛ 1,000 рдирд╛рд╣реА рддрд░ рд╕реБрдорд╛рд░реЗ 333 рдЕрд╕реЗ writes рдШреЗрддреЛ;
- adaptive capacity тАФ рдорджрдд рдХрд░рддреЗ: рддреА рд╡реНрдпрд╕реНрдд partition рд▓рд╛ table рдЪреНрдпрд╛ рдХреНрд╖рдорддреЗрддрд▓рд╛ рдЬрд╛рд╕реНрдд рд╡рд╛рдЯрд╛ рджреЗрддреЗ рдЖрдгрд┐ hot items рднреЛрд╡рддреА partitions рд╡рд┐рднрд╛рдЧреВ рд╢рдХрддреЗ. рдкрдг рддреА рдПрдХрд╛ item рд▓рд╛ рдПрдХрд╛ partition рдЪреНрдпрд╛ рдорд░реНрдпрд╛рджреЗрдкреЗрдХреНрд╖рд╛ рдЬрд▓рдж рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА. рдЦрд░рд╛ рдЙрдкрд╛рдп рдореНрд╣рдгрдЬреЗ рдкрд╕рд░рдгрд╛рд░реА key.
- on-demand mode тАФ рдкреНрд░рддреНрдпреЗрдХ request рдиреБрд╕рд╛рд░ рдкреИрд╕реЗ, рдХреНрд╖рдорддреЗрдЪреЗ рдирд┐рдпреЛрдЬрди рдирд╛рд╣реА; provisioned mode тАФ RCU/WCU рдард░рд╡рд╛ (auto scaling рд╕рд╣), рд╕реНрдерд┐рд░, рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ load рд╕рд╛рдареА рд╕реНрд╡рд╕реНрдд.
- рдкреНрд░рддреНрдпреЗрдХ partition рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд 3,000 RCU + 1,000 WCU рджреЗрддреЛ тАФ read рдЖрдгрд┐ write capacity
units, рдлрдХреНрдд "reads" рдЖрдгрд┐ "writes" рдирд╛рд╣реА:
- Cross-partition query тАФ рдкреНрд░рддреНрдпреЗрдХ partition рд▓рд╛рдЧрдгрд╛рд░рд╛ рдкреНрд░рд╢реНрди ("рд╕рдЧрд│реЗ рд╡рд┐рджреНрдпрд╛рд░реНрдереА grade рдиреБрд╕рд╛рд░ рдХреНрд░рдорд╛рдиреЗ"). Keys рдЕрд╢рд╛ design рдХрд░рд╛ рдХреА рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдирд╛ рдПрдХрдЪ partition рд▓рд╛рдЧреЗрд▓.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг replicas рдЖрдгрд┐ caches (рдзрдбреЗ 09тАУ10) рдлрдХреНрдд reads рд▓рд╛ рдорджрдд рдХрд░рддрд╛рдд. рдирд┐рдХрд╛рд▓рд╛рдЪрд╛ рджрд┐рд╡рд╕ рд╕реЗрдХрдВрджрд╛рд▓рд╛ рд╣рдЬрд╛рд░реЛ writes рдЖрдгрддреЛ, рдХрд┐рдВрд╡рд╛ data рдПрдХрд╛ machine рд╕рд╛рдареА рдЦреВрдк рдореЛрдард╛ рд╣реЛрддреЛ, рддреЗрд╡реНрд╣рд╛ рдкреБрдвреЗ рдЬрд╛рдгреНрдпрд╛рдЪрд╛ рдПрдХрдЪ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛рдЪреА рд╡рд┐рднрд╛рдЧрдгреА. рд╡рд┐рднрд╛рдЧрдгреА key рдЗрддрдХреАрдЪ рдЪрд╛рдВрдЧрд▓реА рдЕрд╕рддреЗ: рдкрд╕рд░рдгрд╛рд░реА key рдЕрд╕реЗрд▓ рддрд░ N partitions N рдкрдЯ рдХрд╛рдо рдХрд░рддрд╛рдд; рдПрдХрдЪ hot value рдЕрд╕рд▓реЗрд▓реА key рдЕрд╕реЗрд▓ рддрд░ N partitions рдПрдХрд╛рдЪреЗ рдХрд╛рдо рдХрд░рддрд╛рдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
scale/sim.py рдордзрд▓реЗ shard_of(key, shards) рдореНрд╣рдгрдЬреЗ md5(key) mod shards тАФ
рдПрдХ рд╕реНрдерд┐рд░ hash, рдореНрд╣рдгрдЬреЗ рдПрдХрдЪ key рдиреЗрд╣рдореА рдПрдХрд╛рдЪ рдард┐рдХрд╛рдгреА рдЬрд╛рддреЗ. spread(keys, shards)
рдкреНрд░рддреНрдпреЗрдХ partition рдордзреНрдпреЗ рдХрд┐рддреА keys рдЬрд╛рддрд╛рдд рддреЗ рдореЛрдЬрддреЗ. shards() рдЖрдзреА 1,000 pupil ids рдкрд╕рд░рд╡рддреЗ, рдордЧ
class рдиреЗ key рдХреЗрд▓реЗрд▓реЗ 1,000 writes (рддреНрдпрд╛рддрд▓реЗ 900 3A), рдордЧ рддреЗрдЪ writes 3A рдЪреЗ 40 рднрд╛рдЧ рдХрд░реВрди.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 scale/demo.py shards
python3 - <<'EOF'
import sys; sys.path.insert(0, "scale"); from sim import spread, shard_of
keys = [f"pupil-{i}" for i in range(1000)]
for n in (2, 4, 8):
print(f"{n} partitions тЖТ", spread(keys, n))
print("class-3A always lands on partition", shard_of("class-3A", 4))
hot = ["class-3A"] * 900 + [f"class-{c}" for c in range(100)]
for suffixes in (4, 10, 40):
fixed = [f"class-3A#{i % suffixes}" for i in range(900)] + [f"class-{c}" for c in range(100)]
print(f"write-sharding with {suffixes:>2} suffixes тЖТ", spread(fixed, 4))
share = max(spread(hot, 4)) / 1000
print(f"at 2,000 writes/s the hot partition gets ~{2000 * share:.0f} writes/s (limit 1,000 WCU per partition)")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
shards рд╣реЗ рдЫрд╛рдкрддреЗ:
тФАтФА 1,000 pupils hashed across 4 partitions тЖТ [245, 262, 249, 244]
partition key = class, results day (900 of 1,000 writes are 3A) тЖТ [19, 31, 928, 22] тАФ one HOT partition
write-sharding the hot key (class-3A#0 тАж #39) тЖТ [179, 253, 277, 291]
DynamoDB: a partition gives up to 3,000 RCU + 1,000 WCU (1 RCU = one strong 4 KB read/s, 1 WCU = one 1 KB write/s)
bigger items use more units; adaptive capacity helps a bit тАФ a key that spreads is still the real fix
рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:
2 partitions тЖТ [494, 506]
4 partitions тЖТ [245, 262, 249, 244]
8 partitions тЖТ [106, 133, 129, 128, 139, 129, 120, 116]
class-3A always lands on partition 2
write-sharding with 4 suffixes тЖТ [244, 31, 253, 472]
write-sharding with 10 suffixes тЖТ [109, 121, 478, 292]
write-sharding with 40 suffixes тЖТ [179, 253, 277, 291]
at 2,000 writes/s the hot partition gets ~1856 writes/s (limit 1,000 WCU per partition)
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдЕрдиреЗрдХ values рдЕрд╕рд▓реЗрд▓реА key 2, 4 рдХрд┐рдВрд╡рд╛ 8 partitions рд╡рд░ рд╕рд╛рд░рдЦреА рдкрд╕рд░рддреЗ. Class key 1,000 рдкреИрдХреА 928 writes partition 2 рдордзреНрдпреЗ рдЯрд╛рдХрддреЗ тАФ рд╕реЗрдХрдВрджрд╛рд▓рд╛ 2,000 writes рдЕрд╕рддрд╛рдирд╛ рддреЗ рд╕реЗрдХрдВрджрд╛рд▓рд╛ рд╕реБрдорд╛рд░реЗ 1,856 рд╣реЛрддрд╛рдд, DynamoDB рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ partition рдЪреНрдпрд╛ 1,000 WCU рдкреЗрдХреНрд╖рд╛ рдЦреВрдк рдЬрд╛рд╕реНрдд (рдЖрдгрд┐ рд╣реЗ 1 KB рдХрд┐рдВрд╡рд╛ рддреНрдпрд╛рд╣реВрди рд▓рд╣рд╛рди items рд╕рд╛рдареА; рдореЛрдареЗ items рдкрд░рд┐рд╕реНрдерд┐рддреА рдЖрдгрдЦреА рдмрд┐рдШрдбрд╡рддрд╛рдд). рдЖрдгрд┐ рдереЛрдбреЗ suffixes рдкреБрд░реЗрд╕реЗ рдирд╛рд╣реАрдд: 4 рдХрд┐рдВрд╡рд╛ 10 рдЕрд╕рддреАрд▓ рддрд░ hash рдЕрдЬреВрдирд╣реА рджреЛрди рдХрд┐рдВрд╡рд╛ рдЬрд╛рд╕реНрдд suffixes рдПрдХрд╛рдЪ рдХрдкреНрдкреНрдпрд╛рдд рдЯрд╛рдХрддреЛ (472, 478). 40 рдЕрд╕рддреАрд▓ рддрд░ рдкрд╕рд░рдг рдкреБрд░реЗрд╢реА рд╕рд╛рд░рдЦреА рд╣реЛрддреЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдереЛрдбреНрдпрд╛рдЪ values рдЕрд╕рд▓реЗрд▓реА partition key (status, class, date) рдЬрд┐рдЪреНрдпрд╛рд╡рд░ рд╕рдЧрд│реЗ рдПрдХрд╛рдЪ рд╡реЗрд│реА writes рдХрд░рддрд╛рдд
- date рд╣реА key: рдЖрдЬрдЪреЗ рд╕рдЧрд│реЗ writes рдПрдХрд╛рдЪ partition рд╡рд░ рдЬрд╛рддрд╛рдд
- рдЦреВрдк рдХрдореА suffixes рд╕рд╣ write-sharding, рдХрд┐рдВрд╡рд╛ рдЖрддрд╛ reads рдирд╛ рдкреНрд░рддреНрдпреЗрдХ suffix рд▓рд╛рдЧрддреЛ рд╣реЗ рд╡рд┐рд╕рд░рдгреЗ
- adaptive capacity рдПрдХрд╛ рдЦреВрдк hot item рд▓рд╛ рд╡рд╛рдЪрд╡реЗрд▓ рдЕрд╢реА рдЕрдкреЗрдХреНрд╖рд╛
- WCU рдРрд╡рдЬреА "writes" рдореЛрдЬрдгреЗ тАФ 3 KB рдЪрд╛ item рдкреНрд░рддреНрдпреЗрдХ write рд▓рд╛ 3 WCU рдЦрд░реНрдЪ рдХрд░рддреЛ
- tables SQL рд╕рд╛рд░рдЦреЗ design рдХрд░реВрди рдордЧ scan рдХрд░рдгреЗ тАФ DynamoDB рдордзреНрдпреЗ keys рдкреНрд░рд╢реНрдирд╛рдВрд╡рд░реВрди design рдХрд░рд╛
- caches, replicas рдЖрдгрд┐ рдЪрд╛рдВрдЧрд▓реЗ indexes рд╡рд╛рдкрд░реВрди рдкрд╛рд╣рдгреНрдпрд╛рдЖрдзреАрдЪ relational database рд╣рд╛рддрд╛рдиреЗ рд╡рд┐рднрд╛рдЧрдгреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ sharded class рдЖрдгрд┐ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдпрд╛рдВрдиреА key рдХреЗрд▓реЗрд▓реЗ on-demand DynamoDB table:
aws dynamodb create-table --table-name results \
--attribute-definitions AttributeName=pk,AttributeType=S AttributeName=sk,AttributeType=S \
--key-schema AttributeName=pk,KeyType=HASH AttributeName=sk,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
Suffix рд╕рд╣ write рдХрд░рд╛; рд╕рдЧрд│реЗ suffixes рд╡рд╛рдЪреВрди рдПрдХрддреНрд░ рдХрд░рд╛ (Python, boto3):
import random, boto3
from boto3.dynamodb.conditions import Key
table = boto3.resource("dynamodb").Table("results")
SUFFIXES = 40
def save(cls, pupil, grade):
table.put_item(Item={"pk": f"class-{cls}#{random.randrange(SUFFIXES)}", "sk": f"pupil#{pupil}", "grade": grade})
def class_results(cls):
items = []
for n in range(SUFFIXES): # one query per suffix тАФ run them in parallel in real code
items += table.query(KeyConditionExpression=Key("pk").eq(f"class-{cls}#{n}"))["Items"]
return items
DynamoDB рд╕рд╛рдареА CloudWatch Contributor Insights рдиреЗ hot keys рд╢реЛрдзрд╛:
aws dynamodb update-contributor-insights --table-name results --contributor-insights-action ENABLE
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: key рдирд┐рд╡рдбрдгреНрдпрд╛рдЖрдзреА app рд╡рд┐рдЪрд╛рд░рдд рдЕрд╕рд▓реЗрд▓реЗ рдкрд╛рдЪ рдореБрдЦреНрдп рдкреНрд░рд╢реНрди рд▓рд┐рд╣реВрди рдХрд╛рдврд╛, рдЖрдгрд┐ рдирд┐рдХрд╛рд▓рд╛рдЪреНрдпрд╛ рджрд┐рд╡рд╕рд╛рдЪреНрдпрд╛ data рдиреЗ load test рдЪрд╛рд▓рд╡рд╛ тАФ рдЬрд┐рдереЗ рдПрдХ value рдмрд╛рдХреАрдЪреНрдпрд╛рдВрдкреЗрдХреНрд╖рд╛ рдЦреВрдкрдЪ рд▓реЛрдХрдкреНрд░рд┐рдп рдЕрд╕рддреЗ тАФ рд╕рд╛рд░рдЦреНрдпрд╛ random test data рдиреЗ рдирд╛рд╣реА.
тПня╕П рдкреБрдвреЗ
рдЬреЗ рдХрд╛рдо рдЖрддреНрддрд╛рдЪ рд╡реНрд╣рд╛рдпрдЪреА рдЧрд░рдЬ рдирд╛рд╣реА тАФ рдкреНрд░рдорд╛рдгрдкрддреНрд░реЗ, emails, PDFs тАФ рддреЗ token рд░рд╛рдВрдЧреЗрдд рдЬрд╛рддреЗ. рдЖрдгрд┐ рдордЧ рд╕рдВрдкреВрд░реНрдг рдЬрддреНрд░рд╛, рд╕реНрддрд░рд╛рдиреБрд╕рд╛рд░.
git checkout lesson-12-queues-and-blueprint