Кэштеу стратегиялары
1) Неліктен кешіктіру керек және оны қайда жасау керек
Кэш - бұл қымбат ресурстарға (CPU/БД/сыртқы API) жасырындылық пен жүктемені азайтатын жылдам жады қабаты. Маңызды мақсаттар:- Жылдамдық (p95/p99 төмен), құн (egress/CPU аз), тұрақтылық (шыңға тәуелділіктен аз).
- Шулы көршілерден оқшаулау және шыңдарды тегістеу.
1. Клиент (браузер/ұялы) - HTTP-кеш, IndexedDB, local storage.
2. Edge/CDN - POP тораптары пайдаланушыға жақын, статиканы және API бөлігін кэштейді.
3. L7-шлюз/Reverse-proxy - Nginx/Envoy/Varnish (шағын кеш, SWR).
4. Сервистік кэш - Кластер ішіндегі Redis/Memcached.
5. Процессішілік - in-memory (Caffeine/Guava/LRU-map).
6. ДБ-дағы кэш - материалдық көріністер, қайталама индекстер.
Ереже: тұтынушыға мүмкіндігінше жақын кешіктіріңіз, бірақ шындықты бір рет сақтаңыз.
2) Кешіктіру үлгілері
2. 1 Cache-aside (“lazy loading”)
бағдарламасы алдымен кэштен оқиды; қате жіберілсе - көзден, содан кейін кэшке жазады.
Артықшылықтары: қарапайымдылық, бақылау. Кемшіліктері: суық старттар, келіспеу терезелері.
2. 2 Read-through
Оқылым әрқашан кэш арқылы, ол дереккөзге (кітапхана/проксирлеу қабаты) бара жатыр.
TTL/серилизация саясатын орталықтандыру ыңғайлы.
2. 3 Write-through / Write-back (write-behind)
Write-through: кэшке жазу және көзі синхронды → жоғары үйлесімділік, жоғары жасырындылық.
Write-back: кэшке жазу, көзіне асинхронды флеш жазу → жылдам, бірақ жоғалту және жанжал қаупі.
2. 4 Refresh-ahead (proactive)
«Жақында TTL аяқталады» деп болжайды және stampede болдырмау үшін фонда кілтті жаңартады.
2. 5 Negative caching
Қысқа TTL үшін «деректер жоқ/404/бос» кэші көздің жүктемесін азайтады.
2. 6 Micro-caching
Өте қысқа TTL (0. 5-5 с) L7-де «динамика дерлік» үшін (тізімдер, басты) - қалдықтарды күрт төмендетеді.
3) HTTP-кэш: тақырыптар және бақылау
3. 1 Негізгі тақырыптар
`Cache-Control`: `max-age`, `s-maxage` (для shared кэшей), `public/private`, `no-store`, `stale-while-revalidate`, `stale-if-error`.
Валидаторлар: 'ETag' (хэш мазмұны), 'Last-Modified'.
Шарттары бар сұраулар: 'If-None-Match', 'If-Modified-Since' → 304 Not Modified.
3. 2 Vary және кілттер
'Vary: Accept-Encoding, Authorization, Cookie, Accept-Language' - кэштің әртүрлі нұсқаларын қалыптастырады. Кардиналдылықты «жару» үшін 'Vary' дегенді азайтыңыз.
3. 3 HTTP жауабының мысалы
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=60
ETag: "a1b2c3"
Vary: Accept-Encoding
4) Кілттер мен TTL жобалау
4. 1 Кілттер
Құрылымдаңыз: 'tenant: user: {id}: profile: v3' (схеманың нұсқасын қосыңыз).
Кілтте PII болдырмаңыз.
Жинақтар үшін - кілт + сұрау параметрлері (қалыпқа келтірілген және сұрыпталған).
4. 2 TTL және келісім
Қысқа TTL келіспеушілікті азайтады, бірақ қателіктерді арттырады.
Сыни деректер үшін - валидаторлар ('ETag') және SWR (stale-while-revalidate).
Сирек өзгеретіндер үшін - ұзақ TTL + «бомбочка» мүгедектігі.
4. 3 Нұсқалау/бастинг
Үйлеспейтін өзгерістер кезінде префиксті/кілттің нұсқасын ('v2 → v3') өзгертіңіз.
Статикалық ресурстар үшін - файл атауындағы content hash.
5) Мүгедектігі: стратегиясы мен практикасы
5. 1 Тікелей жою
'DEL key '/' PURGE' проксиді. Қауіптілік: алып тастау мен көп реттік оқырмандар арасындағы жарыс.
5. 2 Тегтер/Surrogate keys
Құжатты тегтер жиынымен байланыстырыңыз (санат/автор). Мүгедектік - тегпен.
В Varnish/Edge — `Surrogate-Key: article:42 tag:author:7` + `BAN tag:author:7`.
5. 3 Event-driven мүгедектігі
Pub/Sub (Kafka/NATS): көз өзгергенде - «invalidate» оқиғасын жариялаймыз.
Кэш консумерлері кілттерді тыңдайды және жойады/жаңартады.
5. 4 Екі фазалы
Алдымен кілтті ескірген деп белгілейміз (soft TTL), stale қызмет көрсетеміз, фонында жаңартамыз және атомарлы түрде ауыстырамыз.
6) stampede/dogpile және ыстық кілттермен күресу
6. 1 Request coalescing (singleflight)
Бір продюсер кілтті жаңартады, қалғандары нәтижені күтеді (мьютекс/лейбл «жаңартылады»).
6. 2 Jitter к TTL
Синхронды ісінуді болдырмау үшін TTL-ге кездейсоқтық (10-20% ±) қосыңыз.
6. 3 Soft-TTL + hard-TTL
soft-TTL дейін refresh триггериміне параллель кэштен қызмет көрсетеміз; hard-TTL бойынша - қателіктер деп есептейміз.
6. 4 Ыстық кілттер
Жалпының үстінен жергілікті кэштер (two-tier).
Ыстық кілтті бірнеше шардқа репликалау және рандомды таңдау (тек read-only үшін).
Нақты кілтті жаңарту үшін Rate limit.
6. 5 Redis + Lua мысалы (singleflight-эскиз)
lua
-- SETNX lock with TTL to avoid deadlocks local ok = redis. call("SET", KEYS[1], "1", "NX", "EX", ARGV[1])
if ok then return "LOCKED"
else return "WAIT"
end
7) Көшіру саясаты және кэшке қабылдау
7. 1 Eviction
LRU: қарапайым және жергілікті үшін жақсы.
LFU: «ұзақ» ыстық кілттермен жақсы.
ARC/TinyLFU: баланс recency/frequency.
7. 2 Admission (енгізу)
Үлкен сирек кездесетін нысандарды (TinyLFU/Bloom сүзгілері) жібермеңіз.
«Өлшем/жасырындылық» шекарасындағы үлкен мәндерді (LZ4/Zstd) компрессиялау.
8) Шардалау және топологиялар
8. 1 Consistent hashing
Кілттерді нод бойынша тұрақты бөледі, кластердің өсуі/қысылуы кезінде қозғалысты азайтады.
8. 2 Redis/Memcached топологиялары
Redis Cluster (слоттар/шардар), Sentinel (фейловер), репликациясы read-only.
Memcached - клиент-сайд шардинг (ketama hashing), сервер деңгейінде репликалаусыз.
8. 3 Жергілікті + таратылған
Каскад: in-proc (микро-TTL/LRU) → Redis (TTL ұзын) → дереккөз.
TTL қос нүктелерімен және кэш валидаторлармен сақ болыңыз.
9) Edge, CDN және L7-кэш
9. 1 Micro-cache на Nginx
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:100m inactive=10m;
map $request_method $skip_cache { default 0; POST 1; PUT 1; DELETE 1; }
server {
location /api/list {
if ($skip_cache) { add_header Cache-Control "no-store"; }
proxy_cache api;
proxy_cache_valid 200 2s; # micro-cache proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on; # SWR add_header X-Cache $upstream_cache_status;
proxy_pass http://upstream;
}
}
9. 2 Envoy (SWR және шарттар)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. http. cache. file_system_http_cache. v3. FileSystemHttpCacheConfig cache_path: "/var/cache/envoy"
9. 3 Varnish (Surrogate keys)
Топтық мүгедектікке арналған 'Surrogate-Key' және 'ban' тегтерін пайдаланыңыз.
10) Кэш және деректердің келісімділігі
10. 1 Read-your-writes
Пайдаланушылық профильдер/себеттер үшін қысқа TTL немесе кэш арқылы жазуды (write-through) немесе клиентті таңбалауды (жазылғаннан кейін N секундқа bypass) қамтамасыз етіңіз.
10. 2 Eventual vs Strong
Ұсыным/талдау үшін - eventual + ұзын TTL.
Ақша/тапсырыс мәртебесі үшін - қысқа TTL, валидация, кейде қатер шегіндегі жолдарда кэшсіз.
10. 3 Инварианттар
Қатаң TTL және қайта тексерусіз қауіпсіздікке/ACL әсер ететін өрістерді кешірмеңіз.
11) Бақылау, SLO және басқару
11. 1 Өлшемдері
hit_ratio (общий и per-route), byte_hit_ratio, miss_rate.
stampede_prevented_total, refresh_ahead_total, ban/purge_total.
Жасырындылығы: p50/p95/p99 қайнар көзінен vs кэшінен.
hot_keys_topN және олардың QPS/байттары.
11. 2 Логи және трассировка
'X-Cache: HIT/MISS/STALE/UPDATING' логині.
Трестерде жауап көзін белгілеңіз ('cache = true', 'tier = edge' service 'local').
11. 3 SLO тәсілі
Мысал: "API/catalog p99 ≤ 250 мс, cache hit ≥ 85%, stampede ≤ 0. Сұраулардың 1%".
11. 4 Runbooks
«Қателер өсуде» → TTL, жылыту/мүгедектік, hot-keys, кэш мөлшері және қабылдау саясатын тексеру.
12) Қауіпсіздік және мульти-тенанттық
tenant-id кілттеріне (және HTTP 'Vary' дегенге) кірістіріңіз.
Жеке жауаптарды 'public' деп кешірмеңіз.
Сезімтал деректері бар кэшті шифрлаңыз немесе тек PII/ID емес кэшті сақтаңыз.
13) Типтік рецептілер
13. 1 Каталог/таспа (динамика дерлік)
Edge-микрокеш 1-3 с + SWR, ішінде - 15-60 с Redis, жаңарту оқиғалары бойынша мүгедектік.
13. 2 Пайдаланушы профилі
Cache-aside TTL 30-120 с, bypass 5-10 с профилін жаңартқаннан кейін (cookie/хедер) немесе write-through.
13. 3 Валюта бағамдары/анықтамалықтары
Ұзын TTL (минут-сағат) + жаңа деректерді жариялау кезіндегі мақсатты мүгедектік; шартты GET үшін 'ETag'.
13. 4 Іздеу нәтижесі
Edge-микрокеш 1-2 с, ішінде - refresh-ahead және coalescing, кілтте query-параметрлерді қалыпқа келтіру.
14) Қарсы үлгілер
Мүгедектіксіз кэш: тек TTL үміт → ұзақ терезелер өзекті емес.
Үлкен 'Vary': «жарылыс» нұсқалары → төмен hit-rate.
prod/experiments → ластану үшін бірыңғай кэш.
TTL аяқталғанда көзде stampede → шыңынан қорғанысы жоқ.
Қатаң кепілдіксіз ақша/құқық/ACL кэші.
«Қатарынан барлығы» компрессиясы - артық CPU, ұсақ объектілерде p99 нашарлауы.
15) Енгізу чек-парағы
- Кэш деңгейлерін және олардың мақсаттарын анықтаңыз (edge/service/local).
- Кілттерді жобалаңыз (нұсқалау, tenant, параметрлерді қалыпқа келтіру).
- Үлгіні таңдаңыз (cache-aside/read-through/refresh-ahead).
- TTL/soft-TTL/jitter бағдарламасын теңшеңіз, SWR қосыңыз.
- coalescing/singleflight, stampede қорғанысын іске асырыңыз.
- Мүгедектікті ұйымдастырыңыз (оқиғалар, тегтер, purge/ban).
- hit-ratio/жасырындылық өлшемдерін және 'X-Cache' дашбордтарын енгізіңіз.
- Ыстық кілттермен жүктеме сынақтарын өткізіңіз.
- SLO және runbooks жазыңыз.
- Қауіпсіздік/tenant-оқшаулау және 'Vary' тексеріңіз.
16) FAQ
Q: Не таңдау керек - cache-aside немесе read-through?
A: Қарапайым сервистер үшін - cache-aside. Орталықтандыру және бірыңғай саясат қажет - read-through.
Q: оңтайлы TTL қалай түсінуге болады?
A: Рұқсат етілген ескіруден, жаңарту жиілігінен және мақсатты hit-rate-ден бастаңыз; jitter қосыңыз және p95/p99/құнын қадағалаңыз.
Q: write-back қашан орынды?
A: eventual-консистенттілік қолайлы және «қосымша жазу» үшін сенімді кезек/лог бар жоғары жүктелген ағындар үшін.
Q: Авторизацияланған жауаптарды кешіктіруге бола ма?
A: Иә, бірақ 'private' және/немесе tenant/user белгісін/' Vary 'кілтіне қосыңыз. truly-private үшін - клиенттік кэш.
Q: Кэшті қалай жылыту керек?
А: Танымал кілттердің тізімдері, бэкграунд-вормер, логтардан реплай, релизге/пикке дейін жылыту (қара жұма және т.б.).
17) Қорытынды
Тиімді кэштеу - бұл кілттердің дизайны + ақылға қонымды TTL + оқиғалар бойынша мүгедектікпен күшейтілген сауатты таңдалған паттерн, SWR/refresh-ahead және stampede қорғанысы. Кэшті деңгейлерге (клиент/edge/сервис) бөліңіз, бақылау және SLO қосыңыз - және тұрақты латенттілік қалдықтарын, болжамды құнды және ең жоғары жүктемелерге төзімділікті алыңыз.