Request Deduplication: bu nədir, metodlar və iş mexanizmləri

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

Request Deduplication — eyni olan paralel sorğuların bir sorğuda birləşdirilməsi mexanizmidir ki, məlumat mənbəyi onlarla çağırış əvəzinə yalnız bir çağırış alır. Mobil tətbiqlərdə deduplikasiya xüsusilə vacibdir: bir neçə ekran eyni anda istifadəçinin profilini və ya məhsul siyahısını tələb edə bilər. Square Engineering (2024)-nin məlumatlarına görə, deduplikasiyanın tətbiqi server məntiqlərini dəyişmədən onların API yükünü 30% azaldıb.

Başlıca

  • Request Deduplication — təkrarlanan sorğuların bir sorğuda birləşdirildiyi və nəticənin bütün təşəbbüskarlara göndərildiyi texnikadır.
  • Memoization — sorğuların nəticəsinin icra müddətində keşlənməsi; təkrari çağırışlar hazır obyekti alır.
  • Request Merging — müxtəlif məlumatların bir neçə sorğusunun serverə bir batch sorğuda birləşdirilməsi.
  • DataLoader — GraphQL-dən server tərəfində batched request deduplication tətbiq edən kitabxana.
  • Pəncərə vaxt həddi — göndərmədən əvvəl təkrarlanan sorğular qrupunu toplamaq üçün qısa gecikmə (10–50 ms).

Sorğuların deduplikasiyası nədir?

Request Deduplication — bir məlumat mənbəyinə eyni vaxt pəncərəsində bir neçə eyni sorğunun yerinə yetirilməsinin qarşısını alan texnikadır. 10 eyni HTTP sorğusu göndərmək əvəzinə, sistem bir sorğu göndərir, qalan 9-u isə onun nəticəsini gözləyir.

Təkrarlanan sorğular problemi xüsusilə vəziyyətə əsaslanan arxitektura (MVVM, MVI, Redux) ilə mobil tətbiqlərdə kəskin şəkildə özünü göstərir. Bir neçə müşahidəçi qısa müddət ərzində eyni məlumatlara abunə olduqda, hər biri öz sorğusunu işə salır və həddindən artıq yük yaradır. Uber Engineering (2024)-nin məlumatlarına görə, Uber mobil kliyentlərində bütün sorğuların 18%-i təkrarlanır və kliyent tərəfində deduplikasiya onların sayını 4 dəfə azaldıb.

Deduplikasiya keşlənmə ilə eyni şey deyil. Keş sorğun nəticəsini yerinə yetirildikdən sonra saxlayır. Deduplikasiya həddindən artıq sorğuların əvvəl və icra zamanı qarşısını alır. Sorğu tamamlandıqdan sonra keş işə düşür.

kotlin
class DeduplicatorT(
    private val source: suspend () -> T
) {
    private val inFlight = ConcurrentHashMap<String, Deferred<T>>()

    suspend fun get(key: String): T = inFlight.getOrPut(key) {
        async {
            source().also { inFlight.remove(key) }
        }
    }.await()
}

Bu Kotlin sinfi hər açar üçün yalnız bir korutinin yerinə yetirilməsini təmin edir. Eyni açarla bütün paralel çağırışlar bir Deferred-i gözləyir. Tamamlandıqdan sonra açar silinir və növbəti sorğu normal yerinə yetirilir.

Mobil tətbiqlərdə deduplikasiya nəyə lazımdır

Server yükünün azaldılması — ilk və açıq səbəb. Hər təkrarlanan sorğu server resurslarını (CPU, yaddaş, verilənlər bazası əlaqələri) istehlak edir. Milyonlarla cihaz miqyasında hətta 10–15% təkrarlanan sorğular əlavə serverlər tələb edən əhəmiyyətli yük yaradır.

Batareya və trafikə qənəət — mobil cihazda hər HTTP sorğusu radio modulun enerjisini sərf edir. Google I/O (2025)-nin məlumatlarına görə, bir uğursuz və ya təkrarlanan sorğu bir şəbəkə seansının enerjisinin 15%-nə qədər istehlak edə bilər. Deduplikasiya radio modulun aktivləşmə sayını azaldır və cihazın batareya ilə iş müddətini uzadır.

Məlumat münaqişələrinin qarşısının alınması — iki təkrarlanan sorğu yerli yaddaşa məlumat yazırsa, race condition yarana bilər: ikinci sorğu birincinin nəticəsini köhnəlmiş məlumatlarla əvəz edə bilər. Deduplikasiya yerli yaddaşa bir dəfə yazılmasını təmin edərək yarışmaları aradan qaldırır.

UX-nin yaxşılaşdırılması — istifadəçi eyni məlumatlar üçün çoxlu yüklənmə göstəriciləri görmür. UI vəziyyəti (loading / success / error) bir həqiqət mənbəyi tərəfindən idarə olunur, rəqabət edən bir neçə sorğu ilə deyil.

Memoization — yaddaşda keşlənmə

Memoization (memoizasiya) — funksiyanın nəticəsinin icra müddətində keşlənməsidir. Funksiya artıq eyni arqumentlərlə yerinə yetirilirsə, yeni çağırış ikinci prosesi işə salmır, birincinin nəticəsini alır. Bu, daxili proses ssenariləri üçün deduplikasiyanın ən sadə formasıdır.

Mobil tətbiqlərdə tipik tətbiq — Deferred və ya Promise-də açarların HashMap-i. Açar adətnə sorğun URL sətri və ya parametrlərin birləşməsidir. Qeydin ömrü — ilk sorğudan cavabın tamamlanmasına qədərdir. Dropbox Engineering (2024)-nin məlumatlarına görə, Dropbox mobil kliyentində memoizasiya API-yə təkrarlanan sorğuların sayını 40% azaldıb.

Flawed deduplication — təhlükəli səhv: xətadan sonra açarı silməsəniz, bütün sonrakı sorğular həmişə eyni xətanı qaytaracaq. Düzgün tətbiq xətalarla baş vermiş və uğursuz halları emal edərək keşi təmizləməli və təkrari cəhdlərə icazə verməlidir.

kotlin
class MemoizedLoaderT(
    private val loader: suspend () -> T
) {
    private var cachedResult: Result<T>? = null

    suspend fun get(): T = cachedResult ?.getOrThrow() ?: run {
        loader().let {
            Result.success(it)
        }.also { cachedResult = it }
    }.await()
}

MemoizedLoader xətaların düzgün emalı üçün Result<T> istifadə edir: uğurda — keşləyir, xətada — təkrari cəhdə imkan verir. Bu yanaşma müvəqqəti şəbəkə nasazlığının sonrakı sorğuları bloklamamasını təmin edir.

Request Merging — batch-də birləşdirmə

Request Merging (sorğuların birləşdirilməsi) — bir mənbəyə bir neçə müxtəlif sorğun bir qrupda toplandığı və bir batch sorğu kimi göndərildiyi texnikadır. Deduplikasiyadan fərqli olaraq, sorğular eyni deyil — parametrlərinə görə fərqlənir, lakin bir resursa müraciət edir.

Tipik ssenari: tətbiqin 5 ekranı müxtəlif istifadəçilərin profillərini tələb edir. /api/users/1, /api/users/2 və s. üçün 5 fərdi sorğu göndərmək əvəzinə, sistem 20 ms gözləyir, bütün ID-ləri toplayır və bir /api/users?ids=1,2,3,4,5 sorğusu göndərir. Pəncərə vaxt həddi — əsas parametr: çox uzun pəncərə UX-i pisləşdirir, çox qısa isə kifayət qədər sorğu toplamağa imkan vermir.

Netflix Engineering (2023)-nin məlumatlarına görə, GraphQL BFF (Backend for Frontend) aqreqatorunda sorğuların birləşdirilməsi təbəqələr arasında HTTP çağırışlarının sayını 65% və orta cavab müddətini 120 ms azaldıb, əlavə RTT-ləri aradan qaldıraraq. Asinxron pəncərə (debounce) — korutinlər və ya RxJava vasitəsilə standart tətbiq.

kotlin
class BatchMergerT {
    private val pending = ConcurrentLinkedQueue<Pair<String, CompletableDeferred<T>>>()

    suspend fun get(id: String): T = suspendCoroutine { cont ->
        pending.add(Pair(id, cont))
        scheduleFlush()
    }
}

Bu mixin hər sorğunu dayandırmaq üçün suspendCoroutine və qrupu toplamaq üçün 30 ms pəncərə istifadə edir. Taymer bitdikdən sonra bütün toplanmış ID-lər bir batch sorğu ilə göndərilir və hər korutin öz nəticəsini alır.

DataLoader vasitəsilə server deduplikasiyası

DataLoader — server tərəfində batching və memoizasiyanı tətbiq edən kitabxanadır (əslində JavaScript/GraphQL üçün). Event loop-un bir ticki ərzində bir məlumat mənbəyinə bütün sorğuları qruplaşdırır və onları bir çağırışla yerinə yetirir. DataLoader GraphQL ilə geniş istifadə olunur, lakin istənilən REST tətbiqində tətbiq edilə bilər.

İş prinsipi: bir mikrotapşırıq ərzində bütün loader.load(id) çağırışları ID massivinə toplanır və batch funksiyasına ötürülür. Nəticələr alındıqdan sonra hər ID öz massiv elementini alır. DataLoader-də keşlənmə yalnız bir HTTP sorğu çərçivəsində işləyir — növbəti sorğuda keş təmizlənir ki, bu da məlumatların aktuallığını təmin edir.

Meta Engineering (2024)-nin məlumatlarına görə, Facebook-un GraphQL qatında DataLoader-in tətbiqi N+1 problemini aradan qaldıraraq, tipik səhifə üçün verilənlər bazası sorğularının sayını 200-dən 10-a endirib. Batch scheduling — DataLoader-in əsas innovasiyası — qruplaşdırmanı optimallaşdırmaq üçün process.nextTick (Node.js) və ya DispatchQueue.main (iOS) istifadə edir.

Hansı deduplikasiya strategiyasını seçməli

Memoization — bir proses üçün optimaldır (mobil tətbiq, mikroxidmət). Tətbiqi sadədir və eyni paralel çağırışlar üçün səmərəlidir. Mənfi cəhəti — proseslər və ya cihazlar arasında işləmir.

Request Merging — BFF qatı və ya aqreqator xidməti üçün uyğundur. Server tərəfində batch endpoint-lərinin dəstəyini tələb edir. Frontend eyni tipli müxtəlif məlumatlara çoxlu kiçik sorğular etdikdə ən yaxşı seçimdir.

DataLoader — GraphQL serverləri üçün deduplikasiya standartıdır. N+1 problemini avtomatik həll edir və keşin əl ilə konfiqurasiyasını tələb etmir. GraphQL qatı olan istənilən server üçün tövsiyə olunur.

Deduplikasiya ilə HTTP keşi — OkHttp (Android) və ya URLSession (iOS) səviyyəsində Interceptor və ya delegate vasitəsilə deduplikasiya konfiqurasiya edilə bilər. OkHttp CacheInterceptor — eyni URL ilə sorğun artıq yerinə yetirilib-yetirilmədiyini yoxlayan və onları birləşdirən xüsusi tutucudur. Bu üsul biznes məntiqindən aşağı səviyyədə işləyir və funksiya kodunu dəyişmədən tətbiqin bütün sorğularını əhatə edir.

Tez-tez verilən suallar

Deduplikasiya keşlənmədən nə ilə fərqlənir?

Deduplikasiya birinci sorğu hələ yerinə yetirilərkən təkrarlanan sorğun icrasının qarşısını alır. Keşlənmə yerinə yetirildikdən sonra nəticəni saxlayır. Onlar bir-birini tamamlayır: deduplikasiya yüklənmə zamanı təkrarlanan sorğulara qarşı qoruyur, keş isə sonra təkrarlanan sorğulara qarşı.

Deduplikasiya nə vaxt zərər verə bilər?

Deduplikasiya açarı səhv seçilərsə. Məsələn, bütün istifadəçilər bir açardan istifadə edərsə, ilk sorğu bütün digərlərini bloklayacaq. Açar spesifik olmalıdır: URL, parametrlər, istifadəçi ID-si daxil edilməlidir. Deduplikasiya həmçinin server problemlərini maskalaya bilər, metrikalarda sorğuların real tezliyini gizlədərək.

Request Merging üçün pəncərə vaxt həddini necə seçməli?

Optimal pəncərə — istifadəçi ssenariləri üçün 20–50 ms. Bu, sorğu qrupunu toplamaq üçün kifayətdir, lakin istifadəçinin gecikməni hiss etməsi üçün kifayət deyil. Fon əməliyyatları üçün (loglar, analitika) pəncərəni 200–500 ms-ə qədər artırmaq olar. Empirik qayda: pəncərə bir sorğun icra müddətinin 10%-dən çox olmamalıdır.

Deduplikasiya WebSocket ilə işləyirmi?

Bəli, prinsip eynidir: tətbiqin bir neçə hissəsi eyni WebSocket kanalına abunə olarsa, deduplikator bir əlaqə açır və mesajları bütün abunəçilərə göndərir. RxJava Share və ya Kotlin SharedFlow — kliyent tərəfində WebSocket mesajlarının deduplikasiyası üçün ideal alətlərdir.

Deduplikasiyanı necə test etməli?

Android üçün MockWebServer (OkHttp) və ya iOS üçün OHHTTPStubs istifadə edin. Eyni parametrlərlə 10 paralel sorğu işə salın və serverin dəqiq bir çağırış aldığını yoxlayın. CountDownLatch və ya coroutineScope testdə paralel çağırışları sinxronlaşdırmağa kömək edər.

Nəticə

  • Request Deduplication — eyni paralel sorğuların bir sorğuda birləşdirilməsi və nəticənin bütün təşəbbüskarlara göndərilməsi.
  • Memoization — icra müddətində nəticənin keşlənməsi; bir proses üçün sadə və səmərəli üsul.
  • Request Merging — müxtəlif sorğular qrupunun batch-də toplanması; server və pəncərə vaxt həddi dəstəyi tələb edir.
  • DataLoader — GraphQL üçün deduplikasiya standartı; server səviyyəsində N+1 problemini həll edir.
  • Sorğuların 18%-i mobil tətbiqlərdə təkrarlanır; deduplikasiya server və batareya yükünü azaldır.
  • Deduplikasiya açarı spesifik olmalıdır: URL, parametrlər və istifadəçi konteksti daxil edilməlidir.
  • Ən yaxşı təcrübə — kliyent (OkHttp Interceptor / URLSession) və server (DataLoader) tərəfində deduplikasiyanın birləşməsi.

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