ЁЯУМ рдзрдбрд╛ 09 тАФ Database рдЪреЗ caching: рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рд╕рдореЛрд░рдЪрд╛ рд╕реВрдЪрдирд╛ рдлрд▓рдХ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 13 рдкреИрдХреА рдзрдбрд╛ 09 ┬╖ рдорд╛рдЧреАрд▓: lesson-08-serverless-scaling ┬╖ рдкреБрдвреАрд▓: lesson-10-replicas-and-pools
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ08, рдЖрдгрд┐ database рд╕реНрддрд░рд╛рд╕рд╛рдареАрдЪреЗ рдкрд╣рд┐рд▓реЗ рд╕рд╛рдзрди: рддреНрдпрд╛рдЪреНрдпрд╛рд╕рдореЛрд░ рдПрдХ cache
(Redis рдХрд┐рдВрд╡рд╛ Valkey рд╕рд╛рдареА ElastiCache). рддреБрдореНрд╣реА cache-aside, TTLs, write рдЭрд╛рд▓реНрдпрд╛рд╡рд░
рдХрд╛рдп рдХрд░рд╛рдпрдЪреЗ, рдЖрдгрд┐ рд▓реЛрдХрдкреНрд░рд┐рдп key expire рдЭрд╛рд▓реНрдпрд╛рд╡рд░ stampede рдХрд╕рд╛ рдерд╛рдВрдмрд╡рд╛рдпрдЪрд╛ рд╣реЗ рд╢рд┐рдХрддрд╛.
scale/demo.py рдордзрд▓реЗ cache() рдпрд╛рддрд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рджрд╛рдЦрд╡рддреЗ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рд▓рдХ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рд▓рд╛ рдПрдХрдЪ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддреЛ: "3A рд╡рд░реНрдЧрд╛рдЪреЗ рдирд┐рдХрд╛рд▓ рдХрд╛рдп рдЖрд╣реЗрдд?" рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рддрд▓рд╛ рдХрд╛рд░рдХреВрди рдорд╛рдЧрдЪреНрдпрд╛ рдЦреЛрд▓реАрддрд▓реНрдпрд╛ рдореЛрдареНрдпрд╛ рдиреЛрдВрджрд╡рд╣реАрдХрдбреЗ рдЬрд╛рддреЛ, 3A рд╢реЛрдзрддреЛ, рдкрд░рдд рдпреЗрддреЛ рдЖрдгрд┐ рдЙрддреНрддрд░ рджреЗрддреЛ. рдкреБрдиреНрд╣рд╛. рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛. рдПрдХрд╛ рдорд┐рдирд┐рдЯрд╛рдд 6,000 рд╡реЗрд│рд╛.
рдореНрд╣рдгреВрди рджреАрдкрд┐рдХрд╛ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдмрд╛рд╣реЗрд░ рдПрдХ рд╕реВрдЪрдирд╛ рдлрд▓рдХ ЁЯУМ рд▓рд╛рд╡рддреЗ. рдкрд╣рд┐рд▓реНрдпрд╛рдВрджрд╛ рдХреЛрдгреА рд╡рд┐рдЪрд╛рд░рд▓реЗ рдХреА, рдХрд╛рд░рдХреВрди рдиреЛрдВрджрд╡рд╣реА рдПрдХрджрд╛рдЪ рд╡рд╛рдЪрддреЛ рдЖрдгрд┐ рдЙрддреНрддрд░ рдлрд▓рдХрд╛рд╡рд░ рдПрдХрд╛ рдЪрд┐рдареНрдареАрд╕рд╣ рд▓рд╛рд╡рддреЛ: "30 рд╕реЗрдХрдВрдж рдЪрд╛рд▓реЗрд▓". рдмрд╛рдХреА рд╕рдЧрд│реЗ рдлрд▓рдХ рд╡рд╛рдЪрддрд╛рдд.
рдПрдХреЗ рджрд┐рд╡рд╢реА 500 рдкрд╛рд▓рдХ рдлрд▓рдХрд╛рд╕рдореЛрд░ рдЙрднреЗ рдЕрд╕рддрд╛рдирд╛рдЪ рдЪрд┐рдареНрдареАрдЪреА рдореБрджрдд рд╕рдВрдкрддреЗ. рд╕рдЧрд│реЗ 500 рдПрдХрд╛рдЪ рдХреНрд╖рдгреА рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдд рдШреБрд╕рддрд╛рдд, рдЖрдгрд┐ рдХрд╛рд░рдХреВрди рдкреБрд░рд╛ рдкрдбрдд рдирд╛рд╣реА. рдпрд╛рд▓рд╛рдЪ stampede рдореНрд╣рдгрддрд╛рдд.
рдкреБрдврдЪреНрдпрд╛ рд╡реЗрд│реА, рдЪрд┐рдареНрдареАрдЪреА рдореБрджрдд рд╕рдВрдкрд▓реЗрд▓реА рдкрд╛рд╣рдгрд╛рд░рд╛ рдкрд╣рд┐рд▓рд╛ рдкрд╛рд▓рдХ рдореНрд╣рдгрддреЛ: "рдореА рдЖрдгрддреЛ тАФ рдмрд╛рдХреАрдЪреНрдпрд╛рдВрдиреА рдПрдХ рдХреНрд╖рдг рдерд╛рдВрдмрд╛." рдиреЛрдВрджрд╡рд╣реАрдХрдбреЗ рдПрдХрдЪ рдлреЗрд░реА, рдЖрдгрд┐ рдордЧ 500 рдЖрдирдВрджреА рдкрд╛рд▓рдХ. рдпрд╛рд▓рд╛рдЪ single-flight рдореНрд╣рдгрддрд╛рдд.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
app["ЁЯН│ API"] -->|"1 GET results:3A"| rc["ЁЯУМ Redis / Valkey<br/>ElastiCache"]
rc -->|"hit"| app
app -->|"2 miss: SELECT"| db["ЁЯУТ database"]
app -->|"3 SET results:3A EX 30"| rc
w["тЬПя╕П teacher saves a grade"] -->|"UPDATE, then DEL results:3A"| db
st["ЁЯРШ 500 waiting on one expired key<br/>single-flight off тЖТ 500 DB reads<br/>on тЖТ 1"]
ЁЯЧ║я╕П рд░реЗрдЦрд╛рдЯрд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/scaling/lesson-diagrams.html#l09
тЭУ рдХрд╛рдп
- Cache тАФ database рдиреЗ рдЖрдзреА рджрд┐рд▓реЗрд▓реА рдЙрддреНрддрд░реЗ рдареЗрд╡рдгрд╛рд░реА рдЬрд▓рдж рд╕рд╛рдард╡рдг (memory). Amazon ElastiCache рддреБрдордЪреНрдпрд╛рд╕рд╛рдареА Redis OSS, Valkey (Redis рдЪрд╛ open-source fork) рдХрд┐рдВрд╡рд╛ Memcached рдЪрд╛рд▓рд╡рддреЗ; serverless рдкрд░реНрдпрд╛рдпрд╣реА рдЖрд╣реЗ.
- Cache-aside (lazy loading) тАФ рдХрд╛рдо app рдХрд░рддреЗ:
- cache рд╡рд╛рдЪрд╛; hit рдЭрд╛рд▓рд╛ рддрд░ рдХрд╛рдо рд╕рдВрдкрд▓реЗ;
- miss рдЭрд╛рд▓рд╛ рддрд░ database рд╡рд╛рдЪрд╛;
- рдЙрддреНрддрд░ cache рдордзреНрдпреЗ TTL рд╕рд╣ рд╕рд╛рдард╡рд╛. Write рдЭрд╛рд▓рд╛ рдХреА: database update рдХрд░рд╛, рдордЧ рддреА key delete рдХрд░рд╛ (рдкреБрдврдЪрд╛ read рддреА рдкреБрдиреНрд╣рд╛ рднрд░рддреЛ).
- Write-through тАФ рдкреНрд░рддреНрдпреЗрдХ write рдПрдХрд╛рдЪ рд╡реЗрд│реА database рдЖрдгрд┐ cache рджреЛрдиреНрд╣реАрдХрдбреЗ рдЬрд╛рддреЛ. Cache рдиреЗрд╣рдореА рддрд╛рдЬрд╛ рд░рд╛рд╣рддреЛ, рдкрдг рдкреНрд░рддреНрдпреЗрдХ write рдЪреА рдХрд┐рдВрдордд рджреБрдкреНрдкрдЯ рд╣реЛрддреЗ рдЖрдгрд┐ рдХреЛрдгреА рди рд╡рд╛рдЪрдгрд╛рд░рд╛ data cache рднрд░рддреЛ.
- TTL тАФ key рдХрд┐рддреА рд╡реЗрд│ рдЬрдЧрддреЗ. рдЬрд╛рд╕реНрдд TTL рдореНрд╣рдгрдЬреЗ рдХрдореА database reads рдЖрдгрд┐ рдЬреБрдирд╛ data. Write рд╡рд░ delete рдХрд░рдд рдЕрд╕рд▓рд╛рдд рддрд░реА TTL рдиреЗрд╣рдореА рдареЗрд╡рд╛, рдореНрд╣рдгрдЬреЗ рдЪреБрдХрд▓реЗрд▓рд╛ delete рдХрд╛рд▓рд╛рдВрддрд░рд╛рдиреЗ рдЖрдкреЛрдЖрдк рд╕реБрдзрд╛рд░рддреЛ.
- Hit ratio тАФ hits ├╖ reads. Database рд▓рд╛ рдлрдХреНрдд misses рджрд┐рд╕рддрд╛рдд.
- Cache stampede (thundering herd) тАФ рд▓реЛрдХрдкреНрд░рд┐рдп key expire рд╣реЛрддреЗ рдЖрдгрд┐ рдЕрдиреЗрдХ callers рдПрдХрджрдо miss рдХрд░рддрд╛рдд; рддреЗ рд╕рдЧрд│реЗ database рд▓рд╛ query рдХрд░рддрд╛рдд.
- Stampede рдерд╛рдВрдмрд╡рдгреЗ:
- single-flight / lock тАФ рдкрд╣рд┐рд▓рд╛ caller рдЫреЛрдЯрд╛ lock рдШреЗрддреЛ (
SET key:lock NX EX 5) рдЖрдгрд┐ key рдкреБрдиреНрд╣рд╛ рднрд░рддреЛ; рдмрд╛рдХреАрдЪреЗ рдПрдХ рдХреНрд╖рдг рдерд╛рдВрдмреВрди рдирд╡реАрди value рд╡рд╛рдЪрддрд╛рдд; - jittered TTLs тАФ рдкреНрд░рддреНрдпреЗрдХ TTL рдордзреНрдпреЗ рдереЛрдбреА random рднрд░ рдШрд╛рд▓рд╛, рдореНрд╣рдгрдЬреЗ рдЕрдиреЗрдХ keys рдПрдХрд╛рдЪ рд╕реЗрдХрдВрджрд╛рд▓рд╛ expire рд╣реЛрдд рдирд╛рд╣реАрдд;
- рд▓рд╡рдХрд░ refresh тАФ hot key expire рд╣реЛрдгреНрдпрд╛рдЪреНрдпрд╛ рдереЛрдбреЗ рдЖрдзреАрдЪ рдкреБрдиреНрд╣рд╛ рднрд░рд╛.
- single-flight / lock тАФ рдкрд╣рд┐рд▓рд╛ caller рдЫреЛрдЯрд╛ lock рдШреЗрддреЛ (
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг database рд╣рд╛ scale рдХрд░рд╛рдпрд▓рд╛ рд╕рд░реНрд╡рд╛рдд рдХрдареАрдг рд╕реНрддрд░ рдЖрд╣реЗ тАФ рдПрдХрд╛ рдорд┐рдирд┐рдЯрд╛рдд 20 рдкреНрд░рддреА рдЬреЛрдбрддрд╛ рдпреЗрдд рдирд╛рд╣реАрдд тАФ рдЖрдгрд┐ рдирд┐рдХрд╛рд▓рд╛рдЪреНрдпрд╛ рджрд┐рд╡рд╢реА рддреНрдпрд╛рдЪреЗ рдмрд╣реБрддреЗрдХ reads рдПрдХрдЪ рдкреНрд░рд╢реНрди рдЕрд╕рддрд╛рдд. Cache рддреА рдЙрддреНрддрд░реЗ memory рдордзреВрди рдПрдХрд╛ millisecond рдкреЗрдХреНрд╖рд╛ рдЦреВрдк рдХрдореА рд╡реЗрд│рд╛рдд рджреЗрддреЛ, рдЖрдгрд┐ database рд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ key рд╕рд╛рдареА рдкреНрд░рддреНрдпреЗрдХ TTL рдордзреНрдпреЗ рдПрдХрдЪ read рджрд┐рд╕рддреЛ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
scale/sim.py рдордзрд▓реЗ CacheAside(ttl, single_flight=False) рдкреНрд░рддреНрдпреЗрдХ key рд╕рд╛рдареА
рдПрдХ timestamp рдареЗрд╡рддреЗ. entry ttl рдкреЗрдХреНрд╖рд╛ рд▓рд╣рд╛рди рд╡рдпрд╛рдЪреА рдЕрд╕реЗрдкрд░реНрдпрдВрдд read(key, t, concurrent=1) рдПрдХ hit
рдореЛрдЬрддреЗ; рдирд╛рд╣реАрддрд░ рддреЗ database reads рдореЛрдЬрддреЗ тАФ single-flight рдмрдВрдж рдЕрд╕реЗрд▓ рддрд░ concurrent рдЗрддрдХреЗ
(рдерд╛рдВрдмрд▓реЗрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ caller database рдХрдбреЗ рдЬрд╛рддреЛ), рдЪрд╛рд▓реВ рдЕрд╕реЗрд▓ рддрд░ рдПрдХ тАФ рдЖрдгрд┐ key refresh рдХрд░рддреЗ.
cache() 60 рд╕реЗрдХрдВрдж рджрд░ рд╕реЗрдХрдВрджрд╛рд▓рд╛ 100 рд╡реЗрд│рд╛ results:3A рд╡рд╛рдЪрддреЗ, рдЖрдгрд┐ рдордЧ 500 рдерд╛рдВрдмрд▓реЗрд▓реНрдпрд╛ callers
рдЕрд╕рддрд╛рдирд╛ key expire рдХрд░рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 scale/demo.py cache
python3 - <<'EOF'
import sys; sys.path.insert(0, "scale"); from sim import CacheAside
for ttl in (1, 5, 30, 300):
c = CacheAside(ttl=ttl)
for t in range(60):
for _ in range(100): c.read("results:3A", t)
print(f"TTL {ttl:>3} s тЖТ database reads {c.db_reads:>3} ┬╖ hit ratio {c.hits / 6000:.1%}")
for waiting in (50, 500, 2000):
off, on = CacheAside(30), CacheAside(30, single_flight=True)
off.read("results:3A", 0, concurrent=waiting); on.read("results:3A", 0, concurrent=waiting)
print(f"{waiting:>4} waiting on an expired key тЖТ DB reads {off.db_reads:>4} (single-flight off), {on.db_reads} (on)")
EOF
python3 scale/test_scale.py
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
cache рд╣реЗ рдЫрд╛рдкрддреЗ:
тФАтФА 6,000 reads of results:3A in a minute, cache TTL 30 s тЖТ database reads: 2, hits: 5,998
the key expires while 500 parents are waiting тАФ single-flight off тЖТ database reads: 500
the key expires while 500 parents are waiting тАФ single-flight on тЖТ database reads: 1
рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:
TTL 1 s тЖТ database reads 60 ┬╖ hit ratio 99.0%
TTL 5 s тЖТ database reads 12 ┬╖ hit ratio 99.8%
TTL 30 s тЖТ database reads 2 ┬╖ hit ratio 100.0%
TTL 300 s тЖТ database reads 1 ┬╖ hit ratio 100.0%
50 waiting on an expired key тЖТ DB reads 50 (single-flight off), 1 (on)
500 waiting on an expired key тЖТ DB reads 500 (single-flight off), 1 (on)
2000 waiting on an expired key тЖТ DB reads 2000 (single-flight off), 1 (on)
(100.0% рдореНрд╣рдгрдЬреЗ 6,000 рдкреИрдХреА 5,998, рдкреВрд░реНрдгрд╛рдВрдХрд┐рдд.) Tests рдордзреНрдпреЗ тЬЕ L09 single-flight stops a stampede рдЖрд╣реЗ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
1 рд╕реЗрдХрдВрджрд╛рдЪрд╛ TTL рд╕реБрджреНрдзрд╛ 6,000 database reads рдЪреЗ 60 рдХрд░рддреЛ. рдкрдг expire рд╣реЛрдгреНрдпрд╛рдЪрд╛ рдХреНрд╖рдг рдзреЛрдХрд╛рджрд╛рдпрдХ рдЕрд╕рддреЛ: single-flight рдирд╕реЗрд▓ рддрд░ database рд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ рдерд╛рдВрдмрд▓реЗрд▓реНрдпрд╛ caller рдорд╛рдЧреЗ рдПрдХ read рдорд┐рд│рддреЛ тАФ рдПрдХрджрдо 2,000. Single-flight рдЕрд╕реЗрд▓ рддрд░ рдПрдХ тАФ рдЧрд░реНрджреА рдХрд┐рддреАрд╣реА рдореЛрдареА рдЕрд╕реЛ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- TTL рдирд╛рд╣реА тАФ рдПрдХ delete рдЪреБрдХрд▓рд╛ рдХреА data рдХрд╛рдпрдордЪрд╛ рд╢рд┐рд│рд╛
- рдЖрдзреА cache рдЖрдгрд┐ рдордЧ database update рдХрд░рдгреЗ рдЕрд╢рд╛ рдЪреБрдХреАрдЪреНрдпрд╛ рдХреНрд░рдорд╛рдиреЗ, рдХрд┐рдВрд╡рд╛ delete рдХрд░рдгреНрдпрд╛рдРрд╡рдЬреА update рдХрд░рдгреЗ тАФ рджреЛрди writers рдорд┐рд│реВрди cache рдордзреНрдпреЗ рдЬреБрдиреА value рдареЗрд╡реВ рд╢рдХрддрд╛рдд
- рдкреНрд░рддреНрдпреЗрдХ user рдЪрд╛ data shared key рдЦрд╛рд▓реА cache рдХрд░рдгреЗ (
results:katrinaрдРрд╡рдЬреАresults) - рдкреНрд░рддреНрдпреЗрдХ key рд▓рд╛ рд╕рд╛рд░рдЦрд╛рдЪ TTL, рдЖрдгрд┐ deploy рдореБрд│реЗ рд╕рдЧрд│реНрдпрд╛ рдПрдХрд╛рдЪ рдХреНрд╖рдгреА set тАФ рддреНрдпрд╛ рд╕рдЧрд│реНрдпрд╛ рдПрдХрддреНрд░ expire рд╣реЛрддрд╛рдд
- cache рд▓рд╛рдЪ database рд╕рдордЬрдгреЗ: cache рд░рд┐рдХрд╛рдорд╛ рд╣реЛрдКрди restart рдЭрд╛рд▓рд╛ рддрд░реА database рд▓рд╛ misses рдЭреЗрд▓реВрди рдЯрд┐рдХрддрд╛ рдЖрд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ (рд╕рд░реНрд╡рд╛рдд hot keys рдЖрдзреА warm рдХрд░рд╛)
- app рдкреЗрдХреНрд╖рд╛ рд╡реЗрдЧрд│реНрдпрд╛ Availability Zone рдХрд┐рдВрд╡рд╛ Region рдордзрд▓рд╛ cache, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ hit рдордзреНрдпреЗ network рд╡реЗрд│ рд╡рд╛рдврд╡рддреЛ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ рдПрдХ serverless Valkey cache:
aws elasticache create-serverless-cache --serverless-cache-name school-cache --engine valkey \
--subnet-ids subnet-0aaa1111bbbb2222c subnet-0ddd3333eeee4444f \
--security-group-ids sg-0123456789abcdef0
aws elasticache describe-serverless-caches --serverless-cache-name school-cache \
--query 'ServerlessCaches[0].Endpoint'
Jittered TTL рдЖрдгрд┐ lock рд╕рд╣ cache-aside (Python, redis client тАФ Valkey рддреЛрдЪ
protocol рдмреЛрд▓рддреЛ):
import json, random, time, redis
r = redis.Redis(host="school-cache-abc123.serverless.aps1.cache.amazonaws.com", port=6379, ssl=True)
def results_for(cls):
key = f"results:{cls}"
for _ in range(50): # wait up to ~2.5 s for another refill
hit = r.get(key)
if hit is not None:
return json.loads(hit)
if r.set(f"{key}:lock", "1", nx=True, ex=5): # single-flight: only one caller refills
try:
rows = db_query("SELECT pupil, grade FROM results WHERE class = %s", cls)
r.set(key, json.dumps(rows), ex=30 + random.randint(0, 5)) # jittered TTL
return rows
finally:
r.delete(f"{key}:lock")
time.sleep(0.05)
return db_query("SELECT pupil, grade FROM results WHERE class = %s", cls) # give up waiting
def save_grade(pupil, cls, grade):
db_execute("UPDATE results SET grade = %s WHERE pupil = %s", grade, pupil)
r.delete(f"results:{cls}") # on a write: delete the key
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: cache рдЪрд╛ hit rate рдЖрдгрд┐ database рдЪреЗ read IOPS рдПрдХрддреНрд░ рдкрд╛рд╣рд╛. Hit rate рдШрд╕рд░рд▓рд╛ рдХреА рддреЛ рдПрдХрд╛ рд╕реЗрдХрдВрджрд╛рдиреЗ database рд╡рд░ рджрд┐рд╕рддреЛ.
тПня╕П рдкреБрдвреЗ
рд╕реВрдЪрдирд╛ рдлрд▓рдХ рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рдпреЗрдгрд╛рд░реЗ рдкреНрд░рд╢реНрди рд╣рд╛рддрд╛рд│рддреЛ. рдмрд╛рдХреАрдЪреЗ рдЕрдЬреВрдирд╣реА рдПрдХрд╛рдЪ database рдХрдбреЗ рдЬрд╛рддрд╛рдд. рдкреБрдвреЗ: рд╡рд╛рдЪрдгреНрдпрд╛рд╕рд╛рдареА рдиреЛрдВрджрд╡рд╣реАрдЪреНрдпрд╛ рдкреНрд░рддреА, рдЖрдгрд┐ connections рд╡рд╛рдЯреВрди рджреЗрдгрд╛рд░рд╛ proxy.
git checkout lesson-10-replicas-and-pools