Prowid Photos-un yük balanslaşdırıcısının arxasında üç API nüsxəsi var, amma verilənlər bazası birdir — PostgreSQL. Pikdə saniyədə 350 sorğu gəlir və hər biri foto kartı və ya müəllifin profili üçün bazaya gedir, halbuki fotolar həftələrlə dəyişmir. Keş məlumatın elə yerdə saxlanan müvəqqəti nüsxəsidir ki, ondan oxumaq daha sürətlidir. Sorğunun yolunda keşlərin harada yaşadığını, faydasını necə hesablamağı, hansı strategiyaların olduğunu, məlumatı necə təzə saxlamağı, populyar açar «köhnələndə» bazanı necə çökdürməməyi, həmçinin CDN-in və Cache-Control-un necə işlədiyini öyrənəcəyik.
Keş niyə lazımdır: əvvəlcə rəqəmlər
Bənzətmə — iş masası və arxiv. Hər saat lazım olan sənədlər masanın üstündədir: tez götürmək olur, amma yer azdır. Qalanı zirzəmi arxivindədir: yer çoxdur, amma getmək uzundur. Keş masadır. Lazım olanı keşdə tapdınızsa — bu keşdə tapılma (cache hit), tapmadınızsa — tapılmama (cache miss) və mənbəyə, yəni bazaya getmək lazım gəlir. Tapılma payı hit ratio adlanır.
Bazaya yalnız tapılmayanlar çatır, yəni pik × (1 − hit ratio). Orta gecikmə hit × t(hit) + (1 − hit) × t(miss) düsturu ilə hesablanır. Tutaq ki, Redis-dən oxuma təxminən 2 ms çəkir, tapılmama isə PostgreSQL-ə 40 ms-lik sorğu və dəyərin keşə yazılması deməkdir, cəmi təxminən 44 ms:
const peakRps = 350;
const hitMs = 2; // Redis lookup inside the data center
const missMs = 44; // lookup + 40 ms DB query + saving the value
for (const hit of [0, 0.5, 0.9, 0.99]) {
const avgMs = hit * hitMs + (1 - hit) * missMs;
const dbRps = peakRps * (1 - hit);
const pct = Math.round(hit * 100);
const line = `${pct}% hits: ${avgMs.toFixed(1)} ms`;
console.log(`${line}, DB ${dbRps.toFixed(1)} RPS`);
}| Hit ratio | Bazaya (pik 350 RPS) | Orta cavab |
|---|---|---|
| 0% | 350 RPS | 44 ms |
| 50% | 175 RPS | 23 ms |
| 90% | 35 RPS | 6,2 ms |
| 99% | 3,5 RPS | 2,4 ms |
Hit ratio-dakı hər əlavə «doqquz» bazanın yükünü dəfələrlə azaldır: 90%-dən 99%-ə keçəndə — on dəfə. Amma keş sürəti təzəlik və sadəlik hesabına alır: məlumat köhnələ (stale) bilər, sistemə daha bir komponent əlavə olunur və onu yeniləməyi unutmaq olar. Tez-tez oxunan, nadir dəyişən və kiçik geriləməyə dözən məlumatı keşləyin. Bir dəfə oxunan məlumatı və köhnəlməyə yol verilməyən hər şeyi (məsələn, pul çıxarılanda hesabın qalığını) keşləməyin.
Keş harada yaşayır: beş səviyyə
Sorğu səviyyələrdən aşağı «düşür» və nüsxə tapılan ilk səviyyədə dayanır:
- Brauzer. Nüsxə cihazdadır, şəbəkə ümumiyyətlə lazım deyil;
Cache-Controlbaşlığı ilə idarə olunur. Bu keş şəxsidir: Leylanın öz keşi var, Muradın isə öz keşi. - CDN. Dünyanın hər yerində insanlara yaxın yerləşən serverlər. Regionda hamı üçün ortaq keş; şəkillər və açıq API cavabları üçün idealdır.
- Reverse proxy. Tətbiqin qarşısındakı Nginx cavabları saxlaya (
proxy_cache) və API-ni təkrar sorğulardan qoruya bilər. - Tətbiq keşi. Redis: hazır obyektlər və sorğu nəticələri, cavab 1–2 ms-ə.
- Verilənlər bazası. PostgreSQL isti səhifələri özü yaddaşda saxlayır (
shared_buffersvə əməliyyat sisteminin keşi).
Səviyyə istifadəçiyə nə qədər yaxındırsa, istifadəçi o qədər az gözləyir, amma təzəliyi idarə etmək o qədər çətindir: milyon insanın brauzerindəki nüsxəni silmək olmaz. Prowid Photos-da nəyi harada keşləyirik: