Cache Stampede mobil inkişafda: bu nədir və qorunma üsulları

Müəllif: IT Sectr Dərc olunub: 2026-06-13 Oxuma vaxtı: 9 dəq

Cache Stampede — bu, bir çox klient və ya axın eyni anda keş boşluğu aşkar etdikdə məlumat mənbəyinə sorğuların selvari artımıdır. Mobil tətbiqlərdə Cache Stampede populyar keş yazısı müddəti bitdikdə və yüzlərlə cihaz eyni anda məlumatı yenidən yükləməyə çalışaraq serverin həddindən artıq yüklənməsinə səbəb olduqda baş verir. Medium Engineering (2024) tədqiqatına görə, Cache Stampede-dən düzgün konfiqurasiya edilmiş qorunma serverin pik yükünü 95% azaldır.

Əsas Məqamlar

  • Cache Stampede — populyar keş yazısının eyni vaxtda müddəti bitdikdə mənbəyə sorğu seli.
  • Probabilistic Early Expiration — hər bir klient TTL müddəti bitməzdən əvvəl təsadüfi olaraq aktuallığı yoxlayır.
  • Mutex bloklaması — ilk sorğu keş yeniləməsi üçün bloklama alır, qalanları gözləyir.
  • XFetch — qalan ömür müddəti əsasında vaxtından əvvəl yeniləmə ehtimalını hesablayan adaptiv alqoritm.
  • Öncədən yeniləmə — fon tapşırığı keş müddəti bitməzdən əvvəl yeniləyərək boşluğu aradan qaldırır.

Cache Stampede nədir?

Cache Stampede (həmçinin cache thundering herd kimi tanınır) — bu, çox sayda sorğunun eyni anda keş boşluğu aşkar edərək məlumat mənbəyinə yönəlməsi vəziyyətidir. Bu, sistemin deqradasiyasına və ya tam sıradan çıxmasına səbəb ola biləcək pik yük yaradır.

Tipik ssenari: mobil tətbiq ümumi məhsul siyahısını TTL = 5 dəqiqə ilə keşləyir. Saat 14:00-da keş müddəti bitir. 500 aktiv istifadəçi eyni anda kataloqu açır, hər biri boş keş aşkar edir və bütün 500 sorğu serverə göndərilir. Məlumat bazası və ya xarici API qəfil axının öhdəsindən gələ bilmir, səhifə 10-15 saniyə yüklənir, sorğuların bir hissəsi timeouta düşür.

Vattani et al. (SOCC, 2015) məlumatlarına görə, Cache Stampede müddəti bitən yazıları olan istənilən keşləmə qatında baş verir, o cümlədən CDN, Redis, Memcached, brauzerin HTTP-keşi və tətbiqin yaddaşdaxili keşi. Yazı nə qədər populyardırsa, stampede-dən potensial zərər bir o qədər yüksəkdir.

python
def mutex_get(key, lock_timeout=5):
    cached = cache.get(key)
    if cached is not None:
        return cached
    if lock.acquire(key, lock_timeout):
        data = source.load(key)
        cache.set(key, data)
        lock.release(key)
        return data
    sleep(0.01)
    return mutex_get(key, lock_timeout)

Bu nümunə mutex vasitəsilə qorunmanı göstərir: yalnız birinci axın keşi yeniləyir, qalanları hazır nəticəni gözləyir. Bloklama mexanizmi — orta yüklər üçün stampede-nin qarşısını almağın ən sadə, lakin effektiv üsuludur.

Keş boşluğunda niyə sorğu seli yaranır

Kütləvi TTL müddətinin bitməsi — Cache Stampede-nin əsas səbəbi. Populyar keş yazısı bütün klientlər üçün eyni TTL-ə malik olduqda, hamısı eyni anda onun olmadığını aşkar edir. Bu, ümumi məlumatlar üçün xarakterikdir: valyuta məzənnələri, ölkə siyahısı, tətbiqin əsas konfiqurasiyası.

Serverin yenidən başladılması zamanı kolaps — Redis və ya Memcached sıfırlanarsa, bütün keş boş olur. İlk trafik pikində bütün sorğular məlumat bazasına gedir. Amazon AWS Architecture Blog (2024) məlumatlarına görə, yenidən başlatmadan sonra keşin qızdırılması tövsiyə olunur: populyar yazıları tədricən yükləyərək kəskin yük artımının qarşısını almaq.

İnvalidasiya məntiqində səhv — tərtibatçı bir element dəyişdikdə bütün istifadəçilər üçün keşi təmizlədikdə baş verir. Məsələn, xəbər tətbiqində bir məqalə dərc edildikdə bütün xəbər siyahısı invalid edilir. Yüzlərlə istifadəçi eyni anda boş keş aşkar edir — və server çökür. Nöqtəvi invalidasiya (yalnız dəyişdirilmiş yazının) bu problemi aradan qaldırır.

Tətbiqin soyuq başlanğıcı — mobil cihazlarda keş yalnız prosesin yaddaşında mövcuddur. Tətbiq yenidən başladıqdan sonra keş boşdur və bütün sorğular serverə gedir. Həll yolu: seanslar arasında keşi diskdə saxlamaq (Room, SQLite) və başlanğıcda əsas məlumatların ilkin yüklənməsindən istifadə etmək.

Keşin qorunması üçün mutex bloklaması

Metodun ideyası — keş boşluğu aşkar edildikdə birinci axın bloklamanı (lock) ələ keçirir və mənbədən məlumat yükləməyə başlayır. Qalan axınlar bloklamanın bitməsini gözləyir və yenilənmiş keşi oxuyur. Bloklama Redis SETNX, ZooKeeper və ya hətta yaddaşdaxili mutex vasitəsilə həyata keçirilə bilər.

Əsas parametr — lock_timeout. Çox qısa olduqda, birinci axın keşi yeniləməyə vaxt tapmaya bilər və ikinci axın da məlumat yükləməyə cəhd edərək mini-stampede yaradar. Çox uzun olduqda, klientlər lazım olduğundan daha çox gözləyir. Tövsiyə olunan dəyər: tipik məlumat bazası sorğuları üçün 2-5 saniyə.

Tək axın problemi — birinci axının xətası (istisna, timeout) zamanı bloklama ələ keçirilmiş qalır və bütün digər axınlar lock_timeout-un bitməsini gözləyir. Həll yolu: bloklamanı finally blokunda silmək. Redis Best Practices (2025) məlumatlarına görə, bloklamaların atomik qurulması və buraxılması üçün Lua skriptlərindən istifadə tövsiyə olunur.

lua
-- Atomic lock acquisition script for Redis
if redis.call("SET", KEYS[1], "locked", "NX", "EX", ARGV[1]) then
    return true
else
    return false
end

Bu Lua skripti atomik olaraq bloklamanı TTL ilə yoxlayır və qurur. Atomiklik iki eyni vaxtda sorğunun bloklama ala bilməməsini təmin edir — yalnız biri, bu da Cache Stampede-ni tamamilə qarşısını alır.

Probabilistic Early Expiration və XFetch alqoritmi

Probabilistic Early Expiration (PEE) — bloklamasız zərif metod. İdeya ondan ibarətdir ki, hər bir klient müəyyən ehtimalla keşi faktiki müddəti bitməzdən əvvəl yenidən hesablayır. Yazı müddətin bitməsinə nə qədər yaxındırsa, ehtimal bir o qədər yüksəkdir. Bu, yenidən yükləmələri təbii olaraq zamanda paylayır və pik yük hamarlanır.

XFetch alqoritmi — Vattani, Chierichetti və Panconesi (2015) tərəfindən təklif edilmişdir. Ehtimal düsturu: p = max(0, 1 - (beta * age / ttl)), burada beta — qeyri-bərabərlik parametridir (adətən 1.0). age = 0 olduqda → p = 1 (sıfır yaşda zəmanətli yeniləmə, bu düzgün deyil). Buna görə modifikasiyadan istifadə olunur: p = max(0, (ttl - age) / (ttl * beta)).

Etsy Engineering (2024) məlumatlarına görə, Memcached-də XFetch-in tətbiqi stampede hadisələrinin sayını gündə 12-dən 0-a endirdi, məlumat bazasına pik yük isə 78% azaldı. Randomizə edilmiş yeniləmə bloklama və sinxronizasiya tələb etmir, bu da XFetch-i mikroservis arxitekturası üçün ideal edir.

Mobil klientlər üçün PEE tətbiq tərəfində tətbiq oluna bilər: klientlər təsadüfi olaraq keş rəsmi olaraq müddəti bitməzdən əvvəl yeniləməyə başlayır. Məsələn, age > 80% TTL olduqda hər sorğu 20% ehtimalla məlumatları yeniləyir. Paylanmış mobil cihazlar sinxron zərbə ehtimalını əlavə olaraq azaldan təbii səs-küy yaradır.

Keşin öncədən yenilənməsi

Yanaşmanın ideyası — keş müddəti bitməzdən əvvəl yeniləmək, boşluğu tamamilə aradan qaldırmaq. Fon prosesi (cron, Kubernetes-də scheduler) vaxtaşırı populyar açarları yoxlayır və onları yeni TTL ilə yenidən yazır. Klientlər həmişə keşi etibarlı tapır — stampede tərifinə görə qeyri-mümkündür.

Time-To-Refresh (TTR) — müddət bitməsinə nə qədər qalmış yeniləməyə başlamağı müəyyən edən parametr. Məsələn, TTL = 300 saniyə, TTR = 60 saniyə: 240 saniyə işarəsində fon prosesi məlumatları yenidən yazır. Bu, klientlərin heç vaxt boş keş görməməsinə zəmanət verir.

Öncədən yeniləmənin mənfi cəhəti — daimi yük məlumat mənbəyinə, heç kim yazını tələb etməsə belə. Az istifadə olunan məlumatlar üçün bu səmərəsizdir. Həll yolu: açarın sorğu tezliyini (access frequency) izləmək və yalnız populyar yazıları yeniləmək. Adaptiv TTR — yeniləmə intervalının sorğu tarixçəsi əsasında dinamik hesablandığı qabaqcıl texnikadır.

Hansı qorunma üsulunu seçməli

Mutex bloklaması — orta yükü olan sistemlər üçün uyğundur (açar başına 10 000 rps-ə qədər). Tətbiqi sadədir və mənbəyin yalnız bir yeniləmə sorğusu almasını təmin edir. Minus — bloklamalar gözləyən axınlar üçün gecikmə yaradır.

Probabilistic Early Expiration / XFetch — yüksək yüklər və paylanmış sistemlər üçün optimaldır. Bloklama tələb etmir, üfüqi miqyaslanır, pik yük təbii şəkildə hamarlanır. Minlərlə klienti olan Redis-klasterləri və Memcached üçün tövsiyə olunur.

Öncədən yeniləmə — proqnozlaşdırıla bilən giriş nümunəsi olan kritik məlumatlar üçün idealdır (konfiqurasiyalar, arayış kitabçaları, əsas metadata). Fon prosesi üçün əlavə infrastruktur tələb edir.

Disk keşi klientdə — mobil tətbiqlər üçün ən vacib qorunma səviyyəsidir. Server keşi invalid edilsə belə, mobil klient yeni sorğu icra olunarkən diskdən məlumat göstərə bilər. Room + Stale-While-Revalidate — Google (2025) tərəfindən tövsiyə olunan nümunədir və klient tərəfdə Cache Stampede-ni tamamilə aradan qaldırır.

Tez-tez verilən suallar

Cache Stampede DDoS hücumundan nə ilə fərqlənir?

Cache Stampede — eyni anda boş keş aşkar edən qanuni klientlərin normal davranışının nəticəsidir. DDoS — qəsdən hücumdur. Stampede üçün qoruyucu alqoritmlər kifayətdir; DDoS üçün əlavə trafik filtrasiya infrastrukturu tələb olunur.

Sistemdə Cache Stampede olduğunu necə yoxlamaq olar?

Məlumat mənbəyində RPS qrafiklərini (məlumat bazası, API) izləyin. Keş müddətinin bitmə anı ilə sinxronlaşan müntəzəm yük pikləri görürsünüzsə — bu Cache Stampede-dir. Hər populyar açar üçün cache miss rate metrikasını əlavə edin.

Cache Stampede mobil klient tərəfdə yarana bilərmi?

Bəli, tətbiqdə bir neçə axın ümumi yaddaşdaxili keşdən istifadə edərsə. Məsələn, 10 korutin eyni anda istifadəçi profilini tələb edir — birincisi bloklayır, qalan 9-u sorğunu təkrarlaya bilər. Kotlin kitabxanası kotlinx.coroutines bunu CoroutineCache və ya Flow.distinctUntilChanged vasitəsilə həll edir.

XFetch üçün hansı beta parametrini seçməli?

beta = 1.0 — bərabər paylanma verən standart dəyər. Daha aqressiv qorunma üçün (az qaçırma ehtimalı) beta-nı 1.5-2.0-ə qədər artırın. Mənbə resurslarına qənaət etmək üçün — 0.5-ə qədər azaldın. Tövsiyə olunan diapazon: 0.8-1.2.

Probabilistic Early Expiration CDN ilə işləyirmi?

Bəli, Cache-Control: stale-while-revalidateCache-Control: stale-if-error mexanizmi vasitəsilə. CDN köhnəlmiş versiyanı qaytarır və fonda keşi yeniləyir, bu da PEE-nin CDN analoqudur. Cloudflare və Fastly bu direktivləri 2023-cü ildən dəstəkləyir.

Nəticə

  • Cache Stampede — kütləvi keş boşluğu zamanı mənbəyə sorğu seli, sistemin sıradan çıxmasına səbəb ola bilər.
  • Əsas səbəb — populyar yazının TTL-nin bir çox klient və ya axında eyni vaxtda bitməsi.
  • Mutex bloklaması — birinci axın keşi yeniləyir, qalanları gözləyir; sadə, lakin gecikmə yaradır.
  • Probabilistic Early Expiration — hər bir klient keşi müddəti bitməzdən əvvəl təsadüfi yenidən hesablayaraq pikləri hamarlayır.
  • XFetch — qalan ömür müddəti və beta parametri əsasında yenidən hesablama ehtimalını hesablayan adaptiv alqoritm.
  • Öncədən yeniləmə — fon prosesi populyar açarlar üçün keşi müddəti bitməzdən əvvəl yenidən yazaraq boşluğu aradan qaldırır.
  • Mobil tətbiqlər üçün ən yaxşı qorunma — disk keşinin (Room) Stale-While-Revalidate ilə və server qorunmasının XFetch vasitəsilə kombinasiyası.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun