Request Deduplication — bu bir xil parallel so‘rovlarni bitta so‘rovga birlashtirish mexanizmi bo‘lib, ma’lumot manbai o‘nlab chaqiriqlar o‘rniga faqat bitta chaqiriq oladi. Mobil ilovalarda deduplikatsiya ayniqsa muhim: bir nechta ekranlar bir vaqtning o‘zida bir xil foydalanuvchi profili yoki mahsulot ro‘yxatini so‘rashi mumkin. Square Engineering (2024) ma’lumotlariga ko‘ra, deduplikatsiyani joriy etish server mantig‘ini o‘zgartirmasdan ularning API yukini 30% ga kamaytirdi.
Asosiy
Request Deduplication — bir vaqt oynasida bir ma’lumot manbaiga bir nechta bir xil so‘rovlarning bajarilishini oldini oluvchi texnika. 10 ta bir xil HTTP so‘rovini yuborish o‘rniga, tizim bittasini yuboradi, qolgan 9 tasi esa uning natijasini kutadi.
Takrorlanuvchi so‘rovlar muammosi, ayniqsa, holatga asoslangan arxitektura (MVVM, MVI, Redux) bilan mobil ilovalarda keskin namoyon bo‘ladi. Bir nechta kuzatuvchilar qisqa vaqt oralig‘ida bir xil ma’lumotlarga obuna bo‘lganda, har biri o‘z so‘rovini ishga tushiradi va ortiqcha yuk hosil qiladi. Uber Engineering (2024) ma’lumotlariga ko‘ra, Uber mobil mijozlaridagi barcha so‘rovlarning 18% gacha takrorlanadi va mijoz tomonidagi deduplikatsiya ularning sonini 4 baravar kamaytirdi.
Deduplikatsiya keshlash bilan bir xil narsa emas. Kesh so‘rov natijasini bajarilgandan keyin saqlaydi. Deduplikatsiya ortiqcha so‘rovlarning oldini va bajarilish vaqtida oldini oladi. So‘rov tugagandan so‘ng, kesh ishga tushadi va natijani saqlaydi.
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()
}
Ushbu Kotlin sinfi har bir kalit uchun faqat bitta korutin bajarilishini kafolatlaydi. Xuddi shu kalit bilan barcha parallel chaqiriqlar bitta Deferred ni kutadi. Tugagandan so‘ng kalit o‘chiriladi va keyingi so‘rov normal bajariladi.
Server yukini kamaytirish — birinchi va eng aniq sabab. Har bir takrorlanuvchi so‘rov server resurslarini (CPU, xotira, ma’lumotlar bazasi ulanishlari) iste’mol qiladi. Millionlab qurilmalar miqyosida hatto 10–15% takrorlanuvchi so‘rovlar qo‘shimcha serverlarni talab qiladigan sezilarli yuk hosil qiladi.
Batareya va trafikni tejash — mobil qurilmadagi har bir HTTP so‘rovi radiomodul energiyasini sarflaydi. Google I/O (2025) ma’lumotlariga ko‘ra, bitta muvaffaqiyatsiz yoki takrorlanuvchi so‘rov bir tarmoq seansining 15% gacha energiyasini sarflashi mumkin. Deduplikatsiya radiomodulning yoqilish sonini kamaytirib, qurilmaning batareyada ishlash vaqtini uzaytiradi.
Ma’lumotlar ziddiyatlarining oldini olish — agar ikkita takrorlanuvchi so‘rov mahalliy xotiraga ma’lumot yozsa, race condition yuz berishi mumkin: ikkinchi so‘rov birinchining natijasini eskirgan ma’lumotlar bilan qayta yozishi mumkin. Deduplikatsiya mahalliy xotiraga bir marta yozilishini ta’minlab, poygalarni bartaraf qiladi.
UX ni yaxshilash — foydalanuvchi bir xil ma’lumotlar uchun bir nechta yuklash ko‘rsatkichlarini ko‘rmaydi. UI holati (loading / success / error) raqobatlashuvchi bir nechta so‘rovlar emas, balki yagona haqiqat manbai tomonidan boshqariladi.
Memoization (memizatsiya) — funksiya natijasini bajarilish vaqti davomida keshlash. Agar funksiya allaqachon bir xil argumentlar bilan bajarilayotgan bo‘lsa, yangi chaqiriq ikkinchi jarayonni boshlamaydi, balki birinchining natijasini oladi. Bu protsess ichidagi stsenariylar uchun deduplikatsiyaning eng sodda shaklidir.
Mobil ilovalardagi odatiy tatbiq — Deferred yoki Promise dagi kalitlarning HashMap i. Kalit odatda so‘rov URL satri yoki parametrlarning birlashmasidir. Yozuvning umri — birinchi so‘rovdan javob tugagunigacha. Dropbox Engineering (2024) ma’lumotlariga ko‘ra, Dropbox mobil mijozidagi memizatsiya API ga takrorlanuvchi so‘rovlar sonini 40% ga kamaytirdi.
Flawed deduplication — xavfli xato: xatodan keyin kalitni o‘chirmasangiz, barcha keyingi so‘rovlar doim bir xil xatoni qaytaradi. To‘g‘ri tatbiq xato va muvaffaqiyatsizliklarni qayta ishlashi, keshlarni tozalashi va qayta urinishlarga ruxsat berishi kerak.
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 xatolarni to‘g‘ri qayta ishlash uchun Result<T> dan foydalanadi: muvaffaqiyatda — keshlaydi, xatoda — qayta urinishga imkon beradi. Ushbu yondashuv vaqtinchalik tarmoq nosozligi keyingi so‘rovlarni bloklamasligini kafolatlaydi.
Request Merging (so‘rovlarni birlashtirish) — bir manbaga bir nechta turli so‘rovlarning bir guruhda to‘planib, bitta batch so‘rov sifatida yuboriladigan texnikasi. Deduplikatsiyadan farqli o‘laroq, so‘rovlar bir xil emas — parametrlari bilan farqlanadi, lekin bitta resursga murojaat qiladi.
Odatiy stsenariy: ilovaning 5 ta ekrani turli foydalanuvchilarning profillarini so‘raydi. /api/users/1, /api/users/2 va hokazo uchun 5 ta alohida so‘rov yuborish o‘rniga, tizim 20 ms kutadi, barcha ID larni to‘playdi va bitta /api/users?ids=1,2,3,4,5 so‘rovi yuboradi. Oyna vaqti chegarasi — asosiy parametr: juda uzun oyna UX ni yomonlashtiradi, juda qisqa oyna esa yetarlicha so‘rov to‘plashga imkon bermaydi.
Netflix Engineering (2023) ma’lumotlariga ko‘ra, GraphQL BFF (Backend for Frontend) agregatorida so‘rovlarni birlashtirish qatlamlar orasidagi HTTP chaqiriqlar sonini 65% ga va o‘rtacha javob vaqtini 120 ms ga qisqartirib, ortiqcha RTT larni bartaraf etdi. Asinxron oyna (debounce) — korutinlar yoki RxJava orqali standart tatbiq.
class BatchMergerT {
private val pending = ConcurrentLinkedQueue<Pair<String, CompletableDeferred<T>>>()
suspend fun get(id: String): T = suspendCoroutine { cont ->
pending.add(Pair(id, cont))
scheduleFlush()
}
}
Ushbu miksin har bir so‘rovni to‘xtatish uchun suspendCoroutine dan va guruhni to‘plash uchun 30 ms oyna dan foydalanadi. Taymer tugagandan so‘ng, barcha to‘plangan ID lar bitta batch so‘rov bilan yuboriladi va har bir korutin o‘z natijasini oladi.
DataLoader — server tomonida batching va memizatsiyani amalga oshiruvchi kutubxona (dastlab JavaScript/GraphQL uchun). Event loop ning bir ticki davomida bir ma’lumot manbaiga barcha so‘rovlarni guruhlab, ularni bitta chaqiriq bilan bajaradi. DataLoader GraphQL bilan keng qo‘llaniladi, lekin istalgan REST ilovasida qo‘llanishi mumkin.
Ishlash prinsipi: bir mikrotopshiriq davomida barcha loader.load(id) chaqiriqlari ID massiviga to‘planadi va batch funksiyasiga uzatiladi. Natijalar olingandan so‘ng, har bir ID o‘z massiv elementini oladi. DataLoader da keshlash faqat bitta HTTP so‘rovi doirasida ishlaydi — keyingi so‘rovda kesh tozalanadi, bu esa ma’lumotlarning dolzarbligini ta’minlaydi.
Meta Engineering (2024) ma’lumotlariga ko‘ra, Facebook ning GraphQL qatlamida DataLoader ni joriy etish N+1 muammosini bartaraf etib, odatdagi sahifa uchun ma’lumotlar bazasiga so‘rovlar sonini 200 dan 10 ga tushirdi. Batch scheduling — DataLoader ning asosiy innovatsiyasi — guruhlashni optimallashtirish uchun process.nextTick (Node.js) yoki DispatchQueue.main (iOS) dan foydalanadi.
Memoization — bitta jarayon uchun optimal (mobil ilova, mikroxizmat). Amalga oshirish oson va bir xil parallel chaqiriqlar uchun samarali. Kamchiligi — jarayonlar yoki qurilmalar orasida ishlamaydi.
Request Merging — BFF qatlami yoki agregator xizmati uchun mos. Server tomonida batch endpoint larning qo‘llab-quvvatlanishini talab qiladi. Frontend bir xil turdagi turli ma’lumotlarga ko‘plab kichik so‘rovlar yuborganda eng yaxshi tanlov.
DataLoader — GraphQL serverlari uchun deduplikatsiya standarti. N+1 muammosini avtomatik hal qiladi va keshlarni qo‘lda sozlashni talab qilmaydi. GraphQL qatlami bo‘lgan har qanday server uchun tavsiya etiladi.
Deduplikatsiya bilan HTTP keshi — OkHttp (Android) yoki URLSession (iOS) darajasida Interceptor yoki delegate orqali deduplikatsiya sozlanishi mumkin. OkHttp CacheInterceptor — bir xil URL bilan so‘rov allaqachon bajarilayotganligini tekshiruvchi va ularni birlashtiruvchi maxsus tutqich. Bu usul biznes mantig‘idan pastroq darajada ishlaydi va funksional kodini o‘zgartirmasdan ilovaning barcha so‘rovlarini qamrab oladi.
Tez-tez beriladigan savollar
Deduplikatsiya birinchi so‘rov hali bajarilayotganda takrorlanuvchi so‘rovning bajarilishini oldini oladi. Keshlash bajarilgandan keyin natijani saqlaydi. Ular bir-birini to‘ldiradi: deduplikatsiya yuklash vaqtida takrorlanuvchi so‘rovlardan himoya qiladi, kesh esa keyingi takrorlanuvchi so‘rovlardan.
Agar deduplikatsiya kaliti noto‘g‘ri tanlangan bo‘lsa. Masalan, barcha foydalanuvchilar bitta kalitdan foydalansa, birinchi so‘rov qolgan barchasini bloklaydi. Kalit maxsus bo‘lishi kerak: URL, parametrlar, foydalanuvchi ID sini o‘z ichiga olishi kerak. Shuningdek, deduplikatsiya server muammolarini niqoblab, metrikalarda so‘rovlarning haqiqiy chastotasini yashirishi mumkin.
Optimal oyna — foydalanuvchi stsenariylari uchun 20–50 ms. Bu so‘rovlar guruhini to‘plash uchun yetarli, lekin foydalanuvchi kechikishni sezishi uchun yetarli emas. Fondagi operatsiyalar (loglar, analitika) uchun oynani 200–500 ms gacha oshirish mumkin. Empirik qoida: oyna bitta so‘rovning bajarilish vaqtining 10% dan oshmasligi kerak.
Ha, prinsip bir xil: ilovaning bir nechta qismlari bir xil WebSocket kanaliga obuna bo‘lsa, deduplikator bitta ulanish ochadi va xabarlarni barcha obunachilarga yuboradi. RxJava Share yoki Kotlin SharedFlow — mijoz tomonida WebSocket xabarlarini deduplikatsiya qilish uchun ideal vositalar.
Android uchun MockWebServer (OkHttp) yoki iOS uchun OHHTTPStubs dan foydalaning. Bir xil parametrlar bilan 10 ta parallel so‘rovni ishga tushiring va server aynan bitta chaqiriq olganini tekshiring. CountDownLatch yoki coroutineScope testda parallel chaqiriqlarni sinxronlashtirishga yordam beradi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.