ЁЯУМ рдзрдбрд╛ 08 тАФ Caching: рд╕реВрдЪрдирд╛ рдлрд▓рдХ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 08 ┬╖ рдорд╛рдЧреЗ: lesson-07-throttling ┬╖ рдкреБрдвреЗ: lesson-09-cors
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ07, рдЖрдгрд┐ stage cache: TTL рд╕рдВрдкреЗрдкрд░реНрдпрдВрдд office рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рдпреЗрдгрд╛рд▒реНрдпрд╛ GET рдЪреЗ рдЙрддреНрддрд░
рдЖрдкрд▓реНрдпрд╛ рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рд╡рд░реВрди рджреЗрддреЗ, рдЖрдгрд┐ kitchen рд▓рд╛ рдлрдХреНрдд рдПрдХрджрд╛рдЪ рд╡рд┐рдЪрд╛рд░рд▓реЗ рдЬрд╛рддреЗ. рддреБрдореНрд╣рд╛рд▓рд╛
cache key рдХрд╛рдо рдХрд░рддрд╛рдирд╛ рджрд┐рд╕реЗрд▓ рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ user рдЪреА рд╡реЗрдЧрд│реА рдЙрддреНрддрд░реЗ рдПрдХрдЪ key рдХрдзреАрдЪ рдХрд╛ рд╡рд╛рдЯреВрди рдШреЗрдК рдирдпреЗрдд рддреЗ рдХрд│реЗрд▓.
apigw/demo.py рдордзрд▓реЗ cache() рдкрд╛рдЪ рдорд┐рдирд┐рдЯрд╛рдВрдд рдПрдХрд╛рдЪ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдмрджреНрджрд▓ рдЪрд╛рд░ рд╡реЗрд│рд╛
рд╡рд┐рдЪрд╛рд░рддреЗ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдЕрдиреЗрдХ рдкрд╛рд▓рдХ clerk рд▓рд╛ рддреЛрдЪ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддрд╛рдд: "рдРрд╢реНрд╡рд░реНрдпрд╛ рдХреЛрдгрддреНрдпрд╛ рд╡рд░реНрдЧрд╛рдд рдЖрд╣реЗ?" рдкрд╣рд┐рд▓реНрдпрд╛ рд╡реЗрд│реА clerk kitchen рдкрд░реНрдпрдВрдд рдЪрд╛рд▓рдд рдЬрд╛рдКрди рд╡рд┐рдЪрд╛рд░рддреЛ. рдордЧ clerk рдЙрддреНрддрд░ рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рд╡рд░ рд▓рд╛рд╡рддреЛ ЁЯУМ, рд╕реЛрдмрдд рдПрдХ рдЪрд┐рдареНрдареА: "5 рдорд┐рдирд┐рдЯрд╛рдВрд╕рд╛рдареА рд╡реИрдз".
рдкреБрдврдЪрд╛ рдкрд╛рд▓рдХ рд╡рд┐рдЪрд╛рд░рддреЛ тАФ clerk рдлрд▓рдХ рд╡рд╛рдЪрддреЛ. Kitchen рдкрд░реНрдпрдВрдд рдЪрд╛рд▓рдд рдЬрд╛рдпрдЪреА рдЧрд░рдЬ рдирд╛рд╣реА. 5 рдорд┐рдирд┐рдЯрд╛рдВрдирдВрддрд░ рдЪрд┐рдареНрдареА рдЬреБрдиреА рд╣реЛрддреЗ, рдореНрд╣рдгреВрди clerk рддреА рдХрд╛рдвреВрди рдЯрд╛рдХрддреЛ рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛ kitchen рд▓рд╛ рд╡рд┐рдЪрд╛рд░рддреЛ.
рдлрд▓рдХ рдиреЗрдордХреНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдиреБрд╕рд╛рд░ рдорд╛рдВрдбрд▓реЗрд▓рд╛ рдЕрд╕рддреЛ. "рдРрд╢реНрд╡рд░реНрдпрд╛рдЪрд╛ рд╡рд░реНрдЧ" рдЖрдгрд┐ "рдРрд╢реНрд╡рд░реНрдпрд╛рдЪрд╛ рд╡рд░реНрдЧ, рдорд░рд╛рдареАрдд" рдпрд╛ рджреЛрди рд╡реЗрдЧрд│реНрдпрд╛ рдЪрд┐рдареНрдареНрдпрд╛ рдЖрд╣реЗрдд. рдЖрдгрд┐ clerk рдиреЗ "рдорд╛рдЭреЗ рдЧреБрдг" рдХрдзреАрдЪ рдлрд▓рдХрд╛рд╡рд░ рд▓рд╛рд╡реВ рдирдпреЗрдд тАФ рдирд╛рд╣реАрддрд░ рдкреБрдврдЪрд╛ рдкрд╛рд▓рдХ рджреБрд╕рд▒реНрдпрд╛рдЪреЗ рдЧреБрдг рд╡рд╛рдЪреЗрд▓.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
q0["+0 s GET /students/7"] -->|"Miss"| k["ЁЯН│ kitchen<br/>calls = 1"]
k --> board["ЁЯУМ notice board<br/>key: prod GET /students/7<br/>good until +300 s"]
q1["+10 s"] -->|"Hit"| board
q2["+210 s"] -->|"Hit"| board
q3["+511 s тАФ TTL passed"] -->|"Miss"| k2["ЁЯН│ kitchen<br/>calls = 2"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/apigateway/lesson-diagrams.html#l08
тЭУ рдХрд╛рдп
- Stage cache тАФ рдлрдХреНрдд REST APIs. рддреБрдореНрд╣реА рддреЗ рдкреНрд░рддреНрдпреЗрдХ stage рд╕рд╛рдареА рдЪрд╛рд▓реВ рдХрд░рддрд╛ рдЖрдгрд┐ рдЖрдХрд╛рд░ рдирд┐рд╡рдбрддрд╛ (0.5 GB рдкрд╛рд╕реВрди 237 GB рдкрд░реНрдпрдВрдд). рд╡рд╛рдкрд░рд▓реЗ рдЕрд╕реЛ рд╡рд╛ рдирд╕реЛ, рдЖрдХрд╛рд░рд╛рдиреБрд╕рд╛рд░ рддрд╛рд╕рд╛рд▓рд╛ bill рд╣реЛрддреЗ тАФ 0.5 GB рд╕рд╛рдареА рд╕рд╛рдзрд╛рд░рдг $0.02 рдкреНрд░рддрд┐ рддрд╛рд╕, рдореНрд╣рдгрдЬреЗ рдорд╣рд┐рдиреНрдпрд╛рд▓рд╛ рд╕реБрдорд╛рд░реЗ $15 (рдЕрдВрджрд╛рдЬреЗ; рддреБрдордЪрд╛ Region рддрдкрд╛рд╕рд╛).
- TTL тАФ рдЙрддреНрддрд░ рдХрд┐рддреА рдХрд╛рд│ рдЯрд┐рдХрддреЗ: default 300 рд╕реЗрдХрдВрдж, 0 рддреЗ 3600 рдкрд░реНрдпрдВрдд. 0 рдореНрд╣рдгрдЬреЗ caching рдмрдВрдж. рддреБрдореНрд╣реА рддреЗ рдкреНрд░рддреНрдпреЗрдХ method рд╕рд╛рдареА рдмрджрд▓реВ рд╢рдХрддрд╛.
- Cache key тАФ default рдиреБрд╕рд╛рд░ method рдЖрдгрд┐ resource path. рдХреЛрдгрддреНрдпрд╛ query
strings рдЖрдгрд┐ headers рд╕реБрджреНрдзрд╛ key рдордзреНрдпреЗ рдЬрд╛рддреАрд▓ рддреЗ рддреБрдореНрд╣реА рдирд┐рд╡рдбрддрд╛. Default рдиреБрд╕рд╛рд░ рдлрдХреНрдд
GETcache рд╣реЛрддреЗ. - Invalidation тАФ рд╕рдВрдкреВрд░реНрдг stage cache flush рдХрд░рд╛, рдХрд┐рдВрд╡рд╛ рддрд╛рдЬреЗ рдЙрддреНрддрд░ рдорд┐рд│рд╡рдгреНрдпрд╛рд╕рд╛рдареА client рд▓рд╛
Cache-Control: max-age=0рдкрд╛рдард╡реВ рджреНрдпрд╛. require authorization рдЪрд╛рд▓реВ рдХрд░рд╛, рдореНрд╣рдгрдЬреЗ рдлрдХреНрддexecute-api:InvalidateCacheрдЕрд╕рд▓реЗрд▓реЗ callers рд╣реЗ рдХрд░реВ рд╢рдХрддреАрд▓; рдирд╛рд╣реАрддрд░ рдХреЛрдгреАрд╣реА рддреБрдордЪрд╛ cache рдирд┐рд░реБрдкрдпреЛрдЧреА рдХрд░реВ рд╢рдХрддреЛ. - Metrics тАФ
CacheHitCountрдЖрдгрд┐CacheMissCount(рдзрдбрд╛ 11). - HTTP APIs рдирд╛ cache рдирд╕рддреЛ: рд╕рдореЛрд░ CloudFront рдареЗрд╡рд╛, рдХрд┐рдВрд╡рд╛ application рдордзреНрдпреЗ cache рдХрд░рд╛.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рдЕрдиреЗрдХ APIs рддреЗрдЪ рддреЗрдЪ рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рд╡рд╛рдЪрддрд╛рдд тАФ рд╡реЗрд│рд╛рдкрддреНрд░рдХ, рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдЪреЗ рдХрд╛рд░реНрдб, рдПрдЦрд╛рджреА рдХрд┐рдВрдордд-рдпрд╛рджреА. рдкреНрд░рддреНрдпреЗрдХ cache hit рдореНрд╣рдгрдЬреЗ рдПрдХ Lambda run рдХрдореА, рдПрдХ database read рдХрдореА, рдЖрдгрд┐ рдЬрд▓рдж рдЙрддреНрддрд░. рдкрдг TTL рд╕рдВрдкреЗрдкрд░реНрдпрдВрдд cache рдЬреБрдиреА рдЙрддреНрддрд░реЗрд╣реА рджреЗрддреЛ, рдЖрдгрд┐ рдЪреБрдХреАрдЪреА cache key рджреБрд╕рд▒реНрдпрд╛рдЪреЗ рдЙрддреНрддрд░ рджреЗрддреЗ. рджреЛрдиреНрд╣реА рдЦрд░реЛрдЦрд░ рдШрдбрд▓реЗрд▓реНрдпрд╛ incidents рдЖрд╣реЗрдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
Gateway._handle() (apigw/gateway.py) рдордзреНрдпреЗ, TTL рдЕрд╕рд▓реЗрд▓реНрдпрд╛ stage рд╡рд░рдЪрд╛
(prod рд╡рд░ CACHE_TTL = 300, dev рд╡рд░ 0) cache=True рдЕрд╕рд▓реЗрд▓рд╛ route
(stage, method, path, sorted query) рдкрд╛рд╕реВрди key рдмрдирд╡рддреЛ. TTL рдкреЗрдХреНрд╖рд╛ рдХрдореА рд╡рдпрд╛рдЪреЗ рд╕рд╛рдард╡рд▓реЗрд▓реЗ рдЙрддреНрддрд░
X-Cache: Hit рд╕рд╣ рдкрд░рдд рджрд┐рд▓реЗ рдЬрд╛рддреЗ рдЖрдгрд┐ integration рд▓рд╛ call рд╣реЛрдд рдирд╛рд╣реА; рдирд╛рд╣реАрддрд░ рддреЛ
Miss рдЕрд╕рддреЛ, рдЖрдгрд┐ 200 рдЙрддреНрддрд░ рд╕рд╛рдард╡рд▓реЗ рдЬрд╛рддреЗ. рдлрдХреНрдд 200s рд╕рд╛рдард╡рд▓реЗ рдЬрд╛рддрд╛рдд. apigw/demo.py
рдордзрд▓реЗ рдмрдирд╛рд╡рдЯ Clock demo рд▓рд╛ рдХреНрд╖рдгрд╛рдд 301 рд╕реЗрдХрдВрдж рдкреБрдвреЗ рдЙрдбреА рдорд╛рд░реВ рджреЗрддреЗ.
рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛: рд╣реЗ model рдкреНрд░рддреНрдпреЗрдХ query string key рдордзреНрдпреЗ рдШрд╛рд▓рддреЗ; рдЦрд░реЗ API Gateway рдлрдХреНрдд
рддреБрдореНрд╣реА рдирд┐рд╡рдбрд▓реЗрд▓реНрдпрд╛рдЪ рд╡рд╛рдкрд░рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 apigw/demo.py cache
python3 - <<'EOF'
import sys; sys.path.insert(0, "apigw"); from demo import office, Clock, calls
c = Clock(); gw, _ = office(c, cache_ttl=60); calls["n"] = 0
for path, q in (("/students/7", {}), ("/students/7", {}), ("/students/7", {"lang": "mr"}), ("/students/9", {}), ("/students/404", {}), ("/students/404", {})):
st, hd, _ = gw.handle("GET", path, query=q)
print(f"{path:<14} {str(q):<16} {st} {hd.get('X-Cache')} kitchen calls: {calls['n']}")
c.t += 61; print("after 61 s:", gw.handle("GET", "/students/7")[1], "kitchen calls:", calls["n"])
print({k: gw.metrics[k] for k in ("CacheHitCount", "CacheMissCount")})
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
cache рд╣реЗ рдЫрд╛рдкрддреЗ:
+0 s 200 Miss kitchen calls so far: 1
+10 s 200 Hit kitchen calls so far: 1
+200 s 200 Hit kitchen calls so far: 1
+301 s 200 Miss kitchen calls so far: 2
(рд╡реЗрд│рд╛ рдмреЗрд░реАрдЬ рд╣реЛрдд рдЬрд╛рддрд╛рдд: рдЪреМрдереА request 511 s рд▓рд╛ рдЖрд╣реЗ, рдореНрд╣рдгрдЬреЗ 0 s рд▓рд╛ рд╕рд╛рдард╡рд▓реЗрд▓реНрдпрд╛ рдЙрддреНрддрд░рд╛рдЪреНрдпрд╛ 300 s TTL рдЪреНрдпрд╛ рдкрд▓реАрдХрдбреЗ).
рддреБрдордЪрд╛ snippet (TTL 60 s) /students/7 рд╕рд╛рдареА рдЖрдзреА Miss рдордЧ Hit рдЫрд╛рдкрддреЛ (1 kitchen call),
{'lang': 'mr'} рд╕рд╛рдареА Miss (рдирд╡реА key тЖТ 2 calls), /students/9 рд╕рд╛рдареА Miss (3 calls),
рдЖрдгрд┐ /students/404 рд╕рд╛рдареА рджреЛрдирджрд╛ 404 Miss (4 рдЖрдгрд┐ 5 calls тАФ errors рд╕рд╛рдард╡рд▓реЗ рдЬрд╛рдд рдирд╛рд╣реАрдд).
рдордЧ after 61 s: {'X-Cache': 'Miss'} kitchen calls: 6 рдЖрдгрд┐
{'CacheHitCount': 1, 'CacheMissCount': 6}.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рддреБрдореНрд╣реА рдкреНрд░рддреНрдпреЗрдХ hit рдЖрдгрд┐ miss рдЖрдзреАрдЪ рд╕рд╛рдВрдЧреВ рд╢рдХрддрд╛: рддреАрдЪ key рдЖрдгрд┐ TTL рдкреЗрдХреНрд╖рд╛ рдХрдореА рд╡рдп тЖТ рдлрд▓рдХ рдЙрддреНрддрд░ рджреЗрддреЛ; рдирд╡реА query, рдирд╡рд╛ path, рдПрдЦрд╛рджреА error, рдХрд┐рдВрд╡рд╛ рдЬреБрдиреА рдЪрд┐рдареНрдареА тЖТ kitchen рд▓рд╛ рд╡рд┐рдЪрд╛рд░рд▓реЗ рдЬрд╛рддреЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдкреНрд░рддреНрдпреЗрдХ user рдЪрд╛ рд╡реЗрдЧрд│рд╛ route (
/students/me,Authorizationheader рд╡рд╛рдкрд░рдгрд╛рд░реЗ рдХрд╛рд╣реАрд╣реА) рддреЛ header cache key рдордзреНрдпреЗ рди рдШрд╛рд▓рддрд╛ cache рдХрд░рдгреЗ тАФ users рдирд╛ рдПрдХрдореЗрдХрд╛рдВрдЪрд╛ data рджрд┐рд╕рддреЛ - invalidation рд╕рдЧрд│реНрдпрд╛рдВрд╕рд╛рдареА рдЦреБрд▓реЗ рдареЗрд╡рдгреЗ тАФ рдХреЛрдгреАрд╣реА
max-age=0рдиреЗ cache рдЯрд╛рд│реВ рд╢рдХрддреЛ - рд╢рд╛рдВрдд API рд╡рд░ рдореЛрдард╛ cache тАФ рддреНрдпрд╛рдЪреЗ рджрд░ рддрд╛рд╕рд╛рд▓рд╛ bill рд╣реЛрддреЗ
- write (
POST /marks) cache рдХреЗрд▓реЗрд▓рд╛GETрд╕рд╛рдл рдХрд░реЗрд▓ рдЕрд╢реА рдЕрдкреЗрдХреНрд╖рд╛ тАФ рддрд╕реЗ рд╣реЛрдд рдирд╛рд╣реА; TTL рдЫреЛрдЯрд╛ рдареЗрд╡рд╛ рдХрд┐рдВрд╡рд╛ cache flush рдХрд░рд╛
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ prod рд╕рд╛рдареА 0.5 GB cache рдЪрд╛рд▓реВ рдХрд░рд╛, рдПрдХ method 300 s рд╕рд╛рдареА cache рдХрд░рд╛,
рдЖрдгрд┐ рддреЛ flush рдХрд░рд╛:
aws apigateway update-stage --rest-api-id abc123 --stage-name prod --patch-operations \
op=replace,path=/cacheClusterEnabled,value=true \
op=replace,path=/cacheClusterSize,value=0.5 \
op=replace,path=/~1students~1{id}/GET/caching/enabled,value=true \
op=replace,path=/~1students~1{id}/GET/caching/ttlInSeconds,value=300
aws apigateway flush-stage-cache --rest-api-id abc123 --stage-name prod
Terraform тАФ рддреНрдпрд╛рдЪ route рд╕рд╛рдареА method settings:
resource "aws_api_gateway_method_settings" "student_cache" {
rest_api_id = aws_api_gateway_rest_api.school.id
stage_name = aws_api_gateway_stage.prod.stage_name
method_path = "students/{id}/GET"
settings {
caching_enabled = true
cache_ttl_in_seconds = 300
require_authorization_for_cache_control = true
}
}
ЁЯПн Production рдордзреНрдпреЗ рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: рд╕рдЧрд│реНрдпрд╛рдВрд╕рд╛рдареА рд╕рд╛рд░рдЦреЗ рдЕрд╕реЗрд▓ рддреЗрд╡рдвреЗрдЪ cache рдХрд░рд╛, key рд╡рд┐рдЪрд╛рд░рдкреВрд░реНрд╡рдХ рдирд┐рд╡рдбрд╛, hit ratio рдкрд╛рд╣рдд рд░рд╛рд╣рд╛ (
CacheHitCount├╖ рд╕рдЧрд│реНрдпрд╛ cached requests), рдЖрдгрд┐ ratio рдХрдореАрдЪ рд░рд╛рд╣рд┐рд▓рд╛ рддрд░ cache рдХрд╛рдвреВрди рдЯрд╛рдХрд╛ тАФ рддреНрдпрд╛рдЪреЗ рдкреИрд╕реЗ рддреБрдореНрд╣реА рджрд░ рддрд╛рд╕рд╛рд▓рд╛ рднрд░рддрд╛.
тПня╕П рдкреБрдвреЗ
Office рдЬрд▓рдж рдЙрддреНрддрд░ рджреЗрддреЗ. рдкрдг рджреБрд╕рд▒реНрдпрд╛ site рд╡рд░рдЪреЗ рдПрдХ web page рддреНрдпрд╛рд▓рд╛ call рдХрд░реВ рдЗрдЪреНрдЫрд┐рддреЗ, рдЖрдгрд┐ browser рдЖрдзреА рдкрд░рд╡рд╛рдирдЧреА рд╡рд┐рдЪрд╛рд░рддреЛ тАФ CORS.
git checkout lesson-09-cors