dars.uz/K7xQm2/darslar/url-qisqartiruvchi-qanday-ishlaydi
02o'rta165 daqiqa

URL qisqartiruvchi qanday ishlaydi

TinyURL'dan goo.gl yopilishigacha: kalit maydoni, Feistel, chekka kesh va havola umri — bitta kalit-qiymat qidiruv qanday qilib sekundiga 19 000 redirect'ga aylanadi.

Base62FeistelTug'ilgan kun paradoksi301 vs 302Cache stampedeHot keyBloom filtriHyperLogLogZipf va yarim yemirilishIzchil xeshlashOchiq redirectSSRF

Bu darsda nima o‘rganasiz

Do‘stingiz Telegram’da havola yubordi: dars.uz/K7xQm2. Siz bosasiz va bir lahzada uzun manzilli sahifa ochiladi. Bu bosishning ortida kichik, lekin qattiq talabli tizim ishlaydi. U olti belgini to‘g‘ri manzilga aylantirishi kerak: har safar, sekundiga o‘n minglab marta, dunyoning istalgan nuqtasidan, va havola bosmaxonada chop etilgan bo‘lsa — o‘n yil o‘tib ham.

URL qisqartiruvchi — intervyularda eng ko‘p so‘raladigan tizim dizayni savoli va eng ko‘p yuzaki javob beriladigani. “Xeshlaymiz, bazaga yozamiz, redirect qilamiz” — bu javob 30 soniyada tugaydi va hech narsani ko‘rsatmaydi.

Aslida bu masala aldamchi darajada chuqur. Unda kalit maydoni matematikasi, tug‘ilgan kun paradoksi, taqsimlangan ID generatsiya, kesh strategiyalari, hot key, CDN semantikasi, ochiq redirect zaifligi va analitika quvuri bor. Aynan shuning uchun u yaxshi birinchi mashq: kichik masala ichida katta tizimning deyarli barcha naqshlari mavjud.

Dars noldan hozirgi holatigacha boradi. Avval 2002-yilda bitta dasturchi velosiped forumi uchun yozgan oddiy xizmat ko‘riladi. Keyin u oyiga milliardlab bosishga xizmat qiladigan, chekka serverlarda yashaydigan tizimga aylanadi. Oxirida Google o‘z qisqartiruvchisini yopganda nima bo‘lgani — havolaning umri haqidagi eng muhim saboq.

SavolJavob shu darsdaBo‘lim
Kalit uzunligini qanday tanlaysiz?Base62 va tug‘ilgan kun paradoksi3
Tasodifiy kalit qachon to‘qnashadi?To‘qnashuv ehtimoli hisobi3.2
301 va 302 orasida qaysi biri?Redirect semantikasi va analitika2.3
Nega bitta havola butun tizimni yiqitadi?Hot key va cache stampede5.2, 10.1
Kesh qancha so‘rovni yutadi?Zipf, yarim yemirilish va urish darajasi8
100 million havolaga qancha joy kerak?Saqlash hisobi4.2
Kuniga 73 GB analitika bilan nima qilamiz?Oqim quvuri va HyperLogLog6-bo‘lim, 8-qadam
Ochiq redirect nima uchun xavfli?Xavfsizlik11.1
Qisqartiruvchi yopilsa, havolalar nima bo‘ladi?goo.gl saboqi11.5

1. Muammo: uzun havola va uning taqdiri

1.1 Qisqa havola oddiy tilda

Oddiy tilda: katta kutubxonada har kitobning to‘liq “manzili” bor — “uchinchi qavat, sharqiy zal, 14-javon, yuqoridan ikkinchi tokcha, chapdan 37-kitob”. Buni telefonda aytib berish noqulay. Shuning uchun kutubxona har kitobga qisqa katalog raqami beradi va kartochkada yozib qo‘yadi: “K7xQm2 — uchinchi qavat, sharqiy zal, ...”. Siz faqat raqamni aytasiz, kutubxonachi kartochkaga qarab kitobni topadi.

Qisqartiruvchi aynan shu kutubxonachi. Qisqa kalit — katalog raqami, uzun URL — to‘liq manzil, baza — kartochkalar qutisi, redirect esa “kitob anavi yerda” deb ko‘rsatish. Butun dars davomida uchta savol qayta-qayta keladi:

  1. Raqamni qanday berish kerak, toki ikki kitob bir xil raqam olmasin va begona odam raqamlarni sanab chiqib, hamma kitobni topa olmasin? (3-bo‘lim)
  2. Kartochkani qanday tez topish kerak, agar sekundiga o‘n minglab odam so‘rasa? (6–8-bo‘limlar)
  3. Kutubxona yopilsa nima bo‘ladi? Qisqa havola bannerda, kitobda, vizitkada qoladi. Xizmat yopilsa, ularning hammasi bir kunda “o‘ladi”. (11.5)

1.2 Qisqa tarix: forumdan milliardlab bosishgacha

2002-yil yanvar. Amerikalik dasturchi Kevin Gilbertson TinyURL ni ishga tushiradi. Sabab oddiy edi: u bir g‘ildirakli velosiped (unicycle) ixlosmandlarining Usenet forumlarida yozardi. Uzun havolalar xatlarda bir necha qatorga bo‘linib, buzilib qolardi. TinyURL — birinchi mashhur qisqartiruvchi va hozir ham ishlab turgan eng eskilaridan biri.

Keyingi o‘n yilda qisqa havola Twitter bilan portladi: xabar 140 belgi bilan cheklangan, uzun havola esa uning yarmini yeb qo‘yardi. 2008-yilda bit.ly paydo bo‘ldi va qisqartirishni analitika biznesiga aylantirdi: “havolangizni kim, qayerdan, qachon bosdi”. 2009-yilda Google o‘zining goo.gl xizmatini ochdi. 2011-yilda Twitter o‘z t.co qisqartiruvchisini ishga tushirdi: o‘sha yilning 10-oktabridan boshlab xabarlardagi barcha havolalar avtomatik t.co orqali o‘tadigan bo‘ldi. Endi qisqartirish foydalanuvchining tanlovi emas, platformaning xavfsizlik va o‘lchash vositasi edi.

2002
TinyURL
Usenet forumlarida buzilayotgan uzun havolalar uchun. Birinchi mashhur qisqartiruvchi.
2008
bit.ly
Qisqartirish + analitika: kim, qayerdan, qachon bosdi. Twitter davri.
2009
goo.gl
Google'ning qisqartiruvchisi. Ishonchli brend — milliardlab havola.
2011
t.co
Twitter hamma havolani o'zi o'raydi: zararli havolalarni to'sish va bosishlarni o'lchash.
2018-2019
goo.gl yangi havola yaratishni to'xtatadi
2018-yil martida e'lon qilindi, 2019-yil 30-martdan yangi havola yaratib bo'lmaydi. Eskilari ishlashda davom etadi.
2024-2025
goo.gl redirectlari o'chiriladi
2024-yil iyulda e'lon: havolalarning 99% dan ortig'i o'tgan oyda bosilmagan. 2025-yil 25-avgustdan nofaol havolalar 404 qaytaradi.

Bugungi yetakchi qisqartiruvchilar o‘zlari haqida oyiga yuzlab million yangi havola va o‘n milliardga yaqin bosish deb yozadi. Bu raqamlar kompaniyalarning o‘z da’vosi va yildan-yilga o‘zgaradi, lekin ular dars davomida ishlatadigan farazlarimizning tartibini beradi.

Hisob · O'n milliard bosish sekundiga nechta
Oyiga bosishlar (yetakchi xizmat da'vosi): ~10 000 000 000 Oydagi soniyalar: 30 x 86 400 = 2 592 000 O'rtacha: 10e9 / 2.592e6 = 3 858 redirect / soniya Cho'qqi (5x): ~19 300 redirect / soniya Taqqoslash uchun: bitta oddiy veb-server bo'sh javob (302) bilan 10 000+ / soniya -> muammo "bitta server yetmaydi" emas, muammo — kechikish, geografiya va ishonchlilik
Natija: Oyiga 10 mlrd bosish — o'rtacha ~3 860 redirect/s. Bu aynan 1.5 dagi farazimiz: darsdagi raqamlar bozor yetakchisining tartibida

Oxirgi qator darsning birinchi muhim xulosasi: bu tizimda xom quvvat asosiy muammo emas. Muammo — har bosish foydalanuvchiga yaqin joyda, tez va xatosiz tugashi va havolalar o‘n yillar yashashi.

1.3 Funksional talablar

  1. Uzun URL berilganda qisqa havola qaytarish
  2. Qisqa havola ochilganda foydalanuvchini asl manzilga yo‘naltirish
  3. Foydalanuvchi o‘z kalitini tanlashi (dars.uz/kafka)
  4. Havolaning amal qilish muddati va o‘chirilishi
  5. Bosishlar statistikasi: soni, geografiya, qurilma, manba

1.4 Nofunksional talablar

TalabAniq ko‘rsatkichNega aynan shunday
Redirect kechikiship99 ≤ 50 ms (server tomonda)Bu foydalanuvchi kutayotgan “o‘lik” vaqt
Mavjudlik (o‘qish)99.99%Havola ishlamasa, u chop etilgan hamma joyda ishlamaydi
Mavjudlik (yozish)99.9%Yangi havola yaratish biroz kutishi mumkin
Kalit takrorlanmasligi100%Bitta kalit ikkita manzilga ketsa — halokat
Havola muddatiCheksiz (agar belgilanmagan bo‘lsa)Havolalar qog‘ozda, kitobda, bannerda qoladi
MasshtabOyiga 100M yangi havolaBozor yetakchilariga yaqin tartib

1.5 Konvert orqasidagi birinchi hisob

~19 300/s
Redirect cho'qqisi
O'rtacha 3 860/s x 5
~200/s
Yangi havola cho'qqisi
Oyiga 100 mln
6 mlrd
5 yildagi havolalar
Kalit uzunligini belgilaydi
~3 soat
Havolaning yarim yemirilishi
bit.ly tadqiqoti, 2011
Hisob · Yuk va sig'im
Farazlar: Oyiga yangi havola 100 000 000 O'qish / yozish nisbati 100:1 Cho'qqi koeffitsienti 5x Yozish: 100e6 / (30 x 86400) = 38.6 yozuv / soniya Cho'qqida: ~200 / soniya O'qish: 38.6 x 100 = 3860 redirect / soniya Cho'qqida: ~19 300 / soniya 5 yildan keyingi jami havola: 100e6 x 12 x 5 = 6 000 000 000 (6 milliard)
Natija: Yozish 38/s — bitta oddiy server uddalaydi. O'qish cho'qqisi 19 000/s — mana shu haqiqiy masala

Bu son — 6 milliard havola — keyingi bo‘limdagi kalit uzunligini tanlashning asosi bo‘ladi. To‘rtinchi raqam — yarim yemirilish — esa 8-bo‘limda keshning nega bunchalik yaxshi ishlashini tushuntiradi.

Nazorat savoli · javobni ko‘rishNega 2011-yilda Twitter barcha havolalarni o'zi qisqartira boshladi, axir foydalanuvchilar allaqachon bit.ly ishlatardi?

Uchta sabab bor va ularning hech biri “belgilarni tejash” emas.

  1. Xavfsizlik. Har bosish Twitter serveridan o‘tsa, zararli deb topilgan manzilni keyin ham to‘sish mumkin — hatto u millionlab xabarda tarqalib bo‘lgan bo‘lsa ham. Begona qisqartiruvchining ichida nima borligini Twitter nazorat qila olmasdi.
  2. O‘lchash. Qaysi havola bosildi va qayerdan — bu reklama va tavsiya tizimi uchun xom ashyo. Uni boshqa kompaniyaga berish — o‘z biznesingizni berish.
  3. Bog‘liqlik. Agar begona qisqartiruvchi yopilsa yoki sekinlashsa, Twitter’dagi havolalar ham buziladi. O‘z qisqartiruvchingiz bu xavfni yo‘qotadi.

Bu — qisqartiruvchining asl qiymati: u har bosishning ustidan nazorat nuqtasi. Shu sabab analitika va xavfsizlik bo‘limlari (6-bo‘lim 8, 11-qadamlar; 11-bo‘lim) “qo‘shimcha” emas, mahsulotning o‘zi.

2. Nol nuqta: redirect qanday ishlaydi

Butun mahsulot bitta HTTP mexanizmiga tayanadi. Uni aniq bilmasdan qolgan hamma narsani tushunib bo‘lmaydi.

Oddiy tilda: siz eski manzilga xat yubordingiz, pochtachi esa konvertga “bu odam ko‘chib ketgan, yangi manzili — falon” degan yorliq yopishtirib, xatni qaytaradi. Siz yorliqdagi manzilga qaytadan yuborasiz. Redirect — aynan shu yorliq: server sahifani bermaydi, faqat “boshqa joyga bor” deydi va brauzer o‘zi qaytadan boradi. Yorliqda “doimiy ko‘chdi” yoki “vaqtincha boshqa joyda” deb yozilishi mumkin — bu farq 2.3 da butun mahsulotni o‘zgartiradi.

2.1 Bayt darajasida nima sodir bo‘ladi

Foydalanuvchi dars.uz/K7xQm2 ni bosdi:

GET /K7xQm2 HTTP/1.1
Host: dars.uz
User-Agent: Mozilla/5.0 ...

Server javobi:

HTTP/1.1 302 Found
Location: https://example.com/juda/uzun/manzil?utm_source=newsletter
Cache-Control: private, max-age=0, no-store
Content-Length: 0

Brauzer Location sarlavhasini ko‘radi va avtomatik yangi so‘rov yuboradi. Foydalanuvchi uchun bu bir soniyaning ulushi, tizim uchun esa — bitta to‘liq HTTP aylanmasi.

Diqqat qiling: javob tanasi bo‘sh. Ya’ni redirect juda arzon — 200–400 bayt. Butun mahsulotning asosiy operatsiyasi shu.

2.2 To‘liq kechikish byudjeti

Hisob · Foydalanuvchi bosgandan sahifa ochilgunicha
DNS qidiruv (keshlanmagan) 20-100 ms TCP qo'l siqish (RTT) 30 ms TLS qo'l siqish (1-2 RTT) 30-60 ms So'rov -> server 15 ms Server ishlov berishi: kesh o'qish 1 ms (kesh yo'q bo'lsa: baza) 5-10 ms Javob -> brauzer 15 ms ================================ Redirect uchun jami: ~110-220 ms Keyin ASL sahifa uchun butun sikl qaytadan boshlanadi
Natija: Server tomondagi 5 ms — umumiy vaqtning 3% i. Qolgani tarmoq. Shuning uchun geografik joylashuv keshdan ham muhimroq

Bu jadvaldan ikkita muhandislik xulosasi chiqadi:

  1. Serverni 5 ms dan 2 ms ga tushirish deyarli hech narsa bermaydi. Tarmoq hukmron.
  2. Foydalanuvchiga yaqin bo‘lish esa 50–100 ms tejaydi. Shuning uchun anycast, ko‘p mintaqa va chekka (edge) yechimlari kesh optimallashtirishdan muhimroq.

2.3 301 va 302: eng ko‘p munozara qilinadigan qaror

KodMa’nosiBrauzer keshlaydimiOqibati
301 Moved PermanentlyDoimiy ko‘chirildiHa, agressivTakroriy bosishlar serverga umuman yetib kelmaydi
302 FoundVaqtinchaYo‘q (odatda)Har bosish serverga keladi
307 Temporary RedirectVaqtincha, metodni saqlaydiYo‘qPOST so‘rovlar uchun to‘g‘ri
308 Permanent RedirectDoimiy, metodni saqlaydiHa301 ning aniqroq versiyasi
Hisob · 301 tanlansa nima o'zgaradi
Faraz: bitta havola o'rtacha 5 marta bosiladi (bir xil brauzerda) 302 bilan: 5 ta bosish = 5 ta server so'rovi Analitika: 5 ta hodisa yozildi 301 bilan: 5 ta bosish = 1 ta server so'rovi (qolgani brauzer keshidan) Analitika: 1 ta hodisa yozildi Serverga yuk: 5 barobar kam
Natija: 301 serverga yukni 5 barobar kamaytiradi, lekin analitikaning 80% ini o'ldiradi va havolani abadiy qotirib qo'yadi
▸Chuqurroq: Redirect zanjirlari va cheksiz sikl

Foydalanuvchi bitta qisqartiruvchining havolasini boshqasiga qisqartirishi mumkin, ular esa bir-biriga. Natijada:

  • Uzun zanjir — har bir bo‘g‘in ~150 ms qo‘shadi; 5 bo‘g‘in = 1 soniyadan ko‘p kutish
  • Sikl — A → B → A. Brauzer odatda 20 ta redirectdan keyin to‘xtaydi va xato ko‘rsatadi

Chora: yaratish paytida maqsad URL ni tekshirish (o‘z domenimizga ko‘rsatyaptimi?), zanjirni oldindan yechib, oxirgi manzilni saqlash, va bosish paytida Location ni sanitizatsiya qilish. Bu shunchaki tozalik emas — bu ham xavfsizlik (11-bo‘lim), ham kechikish masalasi.

2.4 So‘rov serverni qanday topadi: DNS va anycast

dars.uz/K7xQm2 bosilganda brauzer avval qayerga so‘rov yuborishini bilishi kerak. Bu qadam 2.2-bo‘limdagi byudjetning eng katta o‘zgaruvchan qismi.

1. Brauzer keshi        ->  0 ms   (agar oldin ochgan bo'lsa)
2. OS keshi             ->  0 ms
3. Rekursiv resolver    ->  5-20 ms  (provayder DNS'i)
4. Avtoritativ server   ->  20-100 ms (birinchi marta)

Ko‘p mintaqaga tarqalishning ikki usuli bor va ular tubdan farq qiladi:

GeoDNS
  • So'rovchining joylashuviga qarab boshqa IP qaytariladi
  • Amalga oshirish oson, har qanday DNS provayderda bor
  • Aniqligi past: resolver joylashuvi foydalanuvchi joylashuvi emas
  • Failover DNS TTL'ga bog'liq — 60 soniya kutish kerak
Anycast
  • Bir xil IP yuzlab nuqtadan e'lon qilinadi (BGP)
  • Marshrutlash tarmoq darajasida — eng yaqin nuqta
  • Failover deyarli darhol: marshrut o'zgaradi
  • Murakkabroq: o'z AS raqami yoki CDN provayderi kerak
▸Chuqurroq: DNS TTL: ikki tomonlama tanlov

TTL qisqa bo‘lsa (60 s) — o‘zgarishlar tez tarqaladi, failover tez ishlaydi, lekin DNS so‘rovlari ko‘payadi va har bir yangi foydalanuvchi qo‘shimcha kechikish oladi.

TTL uzun bo‘lsa (1 soat) — kechikish kam, lekin nosozlikda bir soat davomida trafik ishlamayotgan manzilga ketaveradi. Bundan ham yomoni: ba’zi resolverlar TTL ni hurmat qilmaydi va o‘z minimumini qo‘yadi.

Amaliy yechim: anycast — u bu tanlovni butunlay yo‘q qiladi, chunki failover DNS orqali emas, marshrutlash orqali bo‘ladi. Shuning uchun jiddiy qisqartiruvchilar deyarli hammasi CDN yoki anycast tarmoqda o‘tiradi.

2.5 Demak, biz nima quryapmiz?

Barcha bezaklarni olib tashlasak, mahsulot — bu juda katta va juda tez kalit-qiymat qidiruv:

kalit:   "K7xQm2"           (6-7 belgi)
qiymat:  "https://example.com/..."  (o'rtacha 100-500 bayt)

Operatsiyalar:
  GET(kalit) -> qiymat      19 000 / soniya, p99 < 50 ms
  PUT(kalit, qiymat)        200 / soniya

Butun qolgan dars — shu ikki operatsiyani ishonchli, arzon va tez qilish haqida.

Nazorat savoli · javobni ko‘rishNega redirect javobining tanasi bo'sh bo'lishi muhim?

Chunki bu asosiy operatsiyani juda arzon qiladi: ~300 bayt javob, hech qanday shablon render qilish, hech qanday statik fayl yo‘q. Bitta oddiy server sekundiga o‘n minglab shunday javob bera oladi va tarmoq trafigi ham minimal.

Solishtiring: agar redirect o‘rniga “yo‘naltirilmoqda…” degan HTML sahifa qaytarsangiz (ba’zi qisqartiruvchilar reklama uchun shunday qiladi), javob 50 KB ga chiqadi — bu 150 barobar ko‘p trafik, sekinroq foydalanuvchi tajribasi va sezilarli darajada qimmatroq egress hisobi.

3. Kalit maydoni: eng muhim dizayn qarori

Kalit uzunligi — bu bitta son, lekin u tizimning umrini, xavfsizligini va bazasining hajmini belgilaydi.

3.1 Base62 nima uchun

Oddiy tilda: avtomobil raqamlarini o‘ylang. Faqat raqamlardan foydalansangiz (123456), olti belgida bor-yo‘g‘i million mashina sig‘adi. Harflarni qo‘shsangiz (01 A 123 BC), xuddi shu uzunlikda yuz millionlab raqam paydo bo‘ladi. Qisqa kalit ham shunday: har belgi uchun qancha ko‘p variant bo‘lsa, kalit shuncha qisqa bo‘lishi mumkin. Lekin har belgi URL ichida xavfsiz bo‘lishi va odam uni chalkashtirmasligi kerak.

URL da xavfsiz ishlatiladigan belgilar: a-z, A-Z, 0-9 — jami 62 ta. Nega aynan shu:

AlifboBelgilar7 belgi bilanMuammosi
Base101010⁷ = 10 millionJuda kichik
Base16162.7×10⁸Kichik, lekin o‘qilishi oson
Base62623.5×10¹²Standart tanlov
Base64644.4×10¹²+ va / URL da muammo qiladi
Base58582.2×10¹²0, O, l, I olib tashlangan — qo‘lda yozishga qulay
Hisob · Kalit uzunligi va sig'im
62^5 = 916 132 832 (0.9 milliard) 62^6 = 56 800 235 584 (56 milliard) 62^7 = 3 521 614 606 208 (3.5 trillion) 62^8 = 218 340 105 584 896 (218 trillion) Bizga 5 yilda 6 milliard kerak edi. 6 belgi: 6e9 / 5.68e10 = maydonning 10.6% i band 7 belgi: 6e9 / 3.52e12 = maydonning 0.17% i band
Natija: 6 belgi 5 yilga yetmaydi (6 mlrd kerak, 56 mlrd bor - lekin to'qnashuv boshlanadi). 7 belgi to'g'ri tanlov: 3.5 trillion

3.2 Nega bandlik foizi muhim

Agar kalitlarni tasodifiy tanlasak, maydon qanchalik to‘lsa, to‘qnashuv shuncha tez-tez sodir bo‘ladi. Har bir to‘qnashuv — bazaga qo‘shimcha so‘rov va qayta urinish.

Hisob · To'qnashuv ehtimoli
Bitta yangi kalit mavjud kalitga tushish ehtimoli = n / N n = mavjud kalitlar soni N = maydon hajmi n = 6 milliard bo'lganda: 6 belgi: 6e9 / 5.68e10 = 0.1056 -> har 9.5 yozuvdan biri 7 belgi: 6e9 / 3.52e12 = 0.0017 -> har 587 yozuvdan biri 8 belgi: 6e9 / 2.18e14 = 0.000027 -> har 36 000 yozuvdan biri
Natija: 7 belgida har 587 yozuvdan bittasi to'qnashadi — arzon. 6 belgida har 9 tadan bittasi — bu allaqachon muammo
▸Chuqurroq: Tug'ilgan kun paradoksi: nega intuitsiya aldaydi

“3.5 trillion joy bor, 6 milliard havola — to‘qnashuv deyarli imkonsiz” degan fikr xato. Tug‘ilgan kun paradoksiga ko‘ra, kamida bitta to‘qnashuv ehtimoli:

P(kamida bitta to'qnashuv) ≈ 1 - e^(-n² / 2N)

n = 6e9, N = 3.52e12 uchun:

n² / 2N = 3.6e19 / 7.04e12 = 5 113 636
P ≈ 1 - e^(-5113636) ≈ 1.0  (100%)

Ya’ni to‘qnashuvlar albatta bo‘ladi — millionlab marta. Bu qo‘rqinchli emas, chunki biz har bir yozuvda tekshiramiz va qayta urinamiz. Muhim son — bitta yozuv uchun to‘qnashuv ehtimoli (n/N), chunki u qayta urinishlar sonini belgilaydi.

Xulosa: “to‘qnashuv bo‘lmaydi” deb loyihalash xato; “to‘qnashuv arzon bo‘lsin” deb loyihalash to‘g‘ri.

3.3 Kalit generatsiyasining to‘rt strategiyasi

Tasodifiy + tekshirish
  • 7 ta tasodifiy belgi, bazada bor-yo'qligini tekshirish
  • Koordinatsiya kerak emas — har bir server mustaqil
  • Kalitlar taxmin qilinmaydi (xavfsizlik)
  • Har yozuvda 1 ta qo'shimcha o'qish; to'qnashuvda qayta urinish
Hisoblagich + base62
  • Ketma-ket son base62 ga o'giriladi
  • To'qnashuv umuman bo'lmaydi
  • Kalitlar bashoratli — begona havolalarni sanab chiqish mumkin
  • Taqsimlangan hisoblagich koordinatsiya talab qiladi

Yana ikkita variant:

Hash qilib kesish — base62(md5(url))[0:7]. Jozibali ko‘rinadi, lekin ikkita jiddiy kamchiligi bor: bir xil URL har doim bir xil kalit oladi (ya’ni ikki foydalanuvchi bir xil havolani qisqartirsa, ular bitta statistikani baham ko‘radi va biri ikkinchisining havolasini o‘chira oladi), hamda kesilgan hash to‘qnashuvi baribir tekshirishni talab qiladi. Foydali holati bitta: deduplikatsiya ataylab kerak bo‘lganda.

Oldindan generatsiya (Key Generation Service) — alohida xizmat bo‘sh kalitlarni oldindan yaratib qo‘yadi, ilova serverlari ulardan bloklab oladi (masalan bir marta 10 000 ta). Yozish yo‘lidan tekshirish ham, koordinatsiya ham butunlay yo‘qoladi.

Hisob · Nega blok bo'lib olish koordinatsiyani deyarli nolga tushiradi
Cho'qqi yozish tezligi: 200 / soniya Har yozuvda markaziy hisoblagichni so'rasak: 200 so'rov / soniya markazga -> u tor joy (bottleneck) va SPOF Blok bo'lib olsak (10 000 tadan): 200 / 10 000 = 0.02 so'rov / soniya markazga Bitta blok 50 soniyaga yetadi Narxi: server qayta ishga tushsa, ishlatilmagan kalitlar yo'qoladi Kuniga 100 marta restart x 10 000 = 1M kalit yo'qoladi 3.5e12 maydonda bu 0.00003% — mutlaqo ahamiyatsiz
Natija: Markazga murojaat 200/s dan 0.02/s ga tushadi — 10 000 barobar kam. Bu naqsh Snowflake, Ticket Server va sequence allocator'larda bir xil

3.4 Qaysi birini tanlash kerak

MezonTasodifiyHisoblagichKGS
Yozishda qo‘shimcha o‘qishBorYo‘qYo‘q
KoordinatsiyaYo‘qHar yozuvdaBlok bo‘lib
Kalitlarni taxmin qilishImkonsizOsonImkonsiz (aralashtirilgan bo‘lsa)
Amalga oshirish murakkabligiEng oddiyO‘rtachaYuqori
Boshlash uchun✓
Katta masshtabda✓
Nazorat savoli · javobni ko‘rishSizga 'kalit 5 belgi bo'lsin, chiroyli ko'rinadi' deyishdi. Qanday javob berasiz?

Raqam bilan: base62 da 5 belgi = 916 million kalit. Oyiga 100M havola bilan bu 9 oyda tugaydi. Undan oldin ham muammo boshlanadi: maydon 50% to‘lganda har ikkinchi tasodifiy kalit to‘qnashadi va yozish tezligi keskin tushadi.

Taklif: 7 belgi (3.5 trillion — 100+ yil), lekin birinchi kalitlarni qisqa berish mumkin — masalan hisoblagich kichik bo‘lganda 5 belgili kalit, keyin avtomatik uzayadi. Ko‘pchilik tizimlar aynan shunday qiladi: kalit uzunligi sobit emas, o‘sib boradi.

3.5 Inson omili: chalkash belgilar va nomaqbul so‘zlar

Matematik jihatdan mukammal kalit maydoni amalda ikkita insoniy muammoga uriladi.

Chalkash belgilar. Havolani odam qo‘lda ko‘chirsa yoki telefonda o‘qib aytsa, 0 va O, l, I va 1 farqlanmaydi. Chop etilgan materialda yoki telefon orqali aytilgan havolada bu — to‘g‘ridan-to‘g‘ri yo‘qotilgan tashrif.

Hisob · Chalkash belgilarni olib tashlash nimaga turadi
Base62 dan 4 ta belgini olib tashlaymiz: 0, O, l, I -> Base58 62^7 = 3 521 614 606 208 58^7 = 2 207 984 167 552 Yo'qotish: (3.52e12 - 2.21e12) / 3.52e12 = 37.3% Bir xil sig'imga yetish uchun: 58^7 = 2.2e12 (6 milliard havolaga yetarlidan ortiq) Demak uzunlikni oshirish SHART EMAS
Natija: Maydon 38% qisqaradi, lekin 7 belgida hali ham 2.2 trillion — ya'ni bu deyarli bepul yaxshilanish

Nomaqbul so‘zlar. Tasodifiy generatsiya ertami-kechmi haqoratli yoki nomaqbul ketma-ketlik chiqaradi. Havola brend materialida chop etilsa, bu jiddiy muammo.

Generatsiya -> qora ro'yxat bo'yicha tekshirish -> mos kelsa, yangisini olish

Qora ro‘yxat maydonning juda kichik qismini (odatda 0.001% dan kam) olib tashlaydi, ya’ni sig‘imga ta’siri yo‘q. Lekin tekshiruv kalitning qismlarini ham qamrashi kerak — 7 belgili kalit ichida 4 belgili nomaqbul so‘z bo‘lishi mumkin.

4. v0: eng sodda ishlaydigan yechim

Oddiy tilda: kutubxonachi bitta daftar tutadi. Yangi kitob kelsa — tasodifiy raqam o‘ylab topadi, daftarda band emasligini tekshiradi va yozib qo‘yadi. Kimdir raqam aytsa — daftarni varaqlab, manzilni aytadi. Kichik kutubxona uchun bu yetarli. Sekundiga o‘n ming kishi kelganda esa daftar atrofida navbat paydo bo‘ladi — 5-bo‘lim shu haqda.

4.1 Ma’lumotlar modeli

CREATE TABLE links (
    key         VARCHAR(10) PRIMARY KEY,   -- "K7xQm2"
    target_url  TEXT        NOT NULL,      -- asl manzil
    owner_id    BIGINT,                    -- kim yaratgan (NULL = anonim)
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    expires_at  TIMESTAMPTZ,               -- NULL = cheksiz
    is_active   BOOLEAN     NOT NULL DEFAULT true
);

CREATE INDEX idx_links_owner ON links (owner_id, created_at DESC);
CREATE INDEX idx_links_expiry ON links (expires_at) WHERE expires_at IS NOT NULL;

Va butun ilova:

@app.post("/api/shorten")
def shorten(req):
    for _ in range(5):                              # to'qnashuvda qayta urinish
        key = random_base62(7)
        try:
            db.execute(
                "INSERT INTO links (key, target_url, owner_id) VALUES (%s, %s, %s)",
                (key, req.url, req.user_id))
            return {"short": f"https://dars.uz/{key}"}
        except UniqueViolation:
            continue                                # kalit band, yangisini olamiz
    raise ServiceUnavailable("kalit topilmadi")

@app.get("/<key>")
def redirect(key):
    row = db.query_one("SELECT target_url FROM links WHERE key = %s AND is_active", (key,))
    if not row:
        return render("404.html"), 404
    return Response(status=302, headers={"Location": row.target_url})

Bu kod ishlaydi va to‘g‘ri. Kichik loyihada u yillab xizmat qilishi mumkin. Endi uni raqamlar bilan buzamiz.

4.2 Saqlash hisobi

Hisob · 6 milliard havola qancha joy egallaydi
Bitta yozuv: key 7 bayt + qo'shimcha ~ 16 bayt target_url o'rtacha 400 bayt ~ 410 bayt owner_id 8 bayt created_at, expires_at 16 bayt is_active + qator qo'shimchasi ~ 30 bayt ------------------------------------------------ Jami ~ 480 bayt 6e9 x 480 bayt = 2.88 TB Postgres qo'shimchalari va bo'shliq (~30%): ~3.7 TB Birlamchi kalit indeksi (B-tree): 6e9 x (7 bayt kalit + 6 bayt ko'rsatkich + qo'shimcha) ~ 1.2 TB
Natija: ~3.7 TB ma'lumot + ~1.2 TB indeks. Bitta serverga sig'maydi, lekin 10 ta shardga bemalol
▸Chuqurroq: B-tree chuqurligi: bitta qidiruv nechta diskka murojaat qiladi

Bu — “baza sekin” degan gapni raqamga aylantiradigan hisob.

Sahifa hajmi                  8 KB
Bitta yozuv indeksda        ~20 bayt
Sahifadagi yozuvlar    8192 / 20 = ~400

B-tree chuqurligi = log_400(6e9)
  400^1 = 400
  400^2 = 160 000
  400^3 = 64 000 000
  400^4 = 25 600 000 000   <- 6 milliard shu yerda
  Chuqurlik = 4 daraja

Yuqori ikki daraja doim RAM da (ular kichik: ~2.5 MB). Ya’ni bitta qidiruv 1–2 ta disk o‘qishi. NVMe da bu ~100 µs, ya’ni bitta redirect uchun baza ~0.2 ms. Yaxshi.

Muammo boshqa joyda: sekundiga 19 300 redirect × 2 IO = 38 600 IOPS. Bitta NVMe disk buni uddalaydi (500K IOPS gacha), lekin bitta Postgres instansiyasi ulanishlar, lock va CPU tufayli bunga yetmaydi. Aynan shuning uchun kesh birinchi qadam bo‘ladi — disk emas, ma’lumotlar bazasining o‘zi tor joyga aylanadi.

4.3 API dizayni va idempotentlik

Yaratish API sining bitta nozik joyi bor: tarmoq uzilib qolsa, mijoz qayta yuboradi va ikkita havola paydo bo‘ladi.

POST /api/v1/links
Idempotency-Key: 7f3a9c1e-...        <- mijoz generatsiya qiladi
Content-Type: application/json

{"url": "https://example.com/...", "custom_alias": null, "expires_at": null}

Server kalitni saqlaydi va bir xil Idempotency-Key bilan kelgan takroriy so‘rovga avvalgi javobni qaytaradi — yangi havola yaratmaydi. Kalit muddati odatda 24 soat.

Xato kodlari ham mahsulot qismi:

KodQachonMijoz nima qilishi kerak
400URL noto‘g‘ri formatdaTuzatib qayta yuborish
409Maxsus kalit bandBoshqa kalit taklif qilish
422URL zararli deb topildiFoydalanuvchiga sababni ko‘rsatish
429Tezlik chekloviRetry-After bo‘yicha kutish
503Kalit topilmadi (maydon to‘lgan)Qayta urinish, keyin alert

Redirect tomonida ham kodlar ma’noli bo‘lishi kerak: 404 — bunday kalit yo‘q, 410 Gone — bor edi, o‘chirilgan (bu SEO va mijoz uchun farqli signal), 429 — skanerga qarshi.

▸Chuqurroq: Ro'yxatni sahifalash: nega OFFSET yaramaydi

Foydalanuvchining 50 million havolasi bo‘lishi mumkin. LIMIT 50 OFFSET 1000000 so‘rovi bazani million qatorni o‘qib tashlab yuborishga majbur qiladi — sahifa raqami oshgani sari so‘rov sekinlashadi.

To‘g‘ri usul — kursorli sahifalash: oxirgi ko‘rilgan yozuvning tartiblash kalitini mijozga berib yuboriladi va keyingi sahifa shundan boshlanadi:

SELECT * FROM links
WHERE owner_id = $1 AND (created_at, key) < ($2, $3)
ORDER BY created_at DESC, key DESC
LIMIT 50;

Bu so‘rov indeks bo‘yicha to‘g‘ridan-to‘g‘ri kerakli joyga sakraydi — sahifa raqamidan qat’i nazar bir xil tez. Qo‘shimcha yutuq: yangi yozuv qo‘shilganda sahifalar “siljib” ketmaydi, ya’ni foydalanuvchi bir xil yozuvni ikki marta ko‘rmaydi.

4.4 B-tree va LSM: qaysi biri bu yukka mos

Bazani “Postgres yoki Cassandra” deb tanlash aslida ikki xil saqlash strukturasi orasidagi tanlov. Farqni bilish kerak, chunki u kechikish va disk yukini belgilaydi.

B-tree (Postgres, MySQL)LSM daraxti (Cassandra, RocksDB)
YozishSahifani joyida yangilaydi + WALXotiraga yozadi, keyin ketma-ket disk
Yozish amplifikatsiyasi2–5× (sahifa + WAL)10–30× (compaction)
Yozish tezligiO‘rtacha (tasodifiy IO)Yuqori (ketma-ket IO)
O‘qish1–2 IO (bashoratli)1–5 IO (darajalar bo‘yicha qidiruv)
O‘qish yordamiSahifa keshiBloom filtrlari har bir SSTable uchun
Bo‘sh joyFragmentatsiyaCompaction paytida vaqtincha 2×
▸Chuqurroq: Bizning yukimiz uchun qaysi biri to'g'ri

Ikkita muhim xususiyatimiz bor:

  1. O‘qish ustunlik qiladi (100:1) va o‘qishlar — birlamchi kalit bo‘yicha nuqta qidiruvi, diapazon skani emas
  2. Qiymatlar deyarli o‘zgarmaydi. Havola bir marta yaratiladi va keyin faqat o‘qiladi. Ya’ni yangilash amplifikatsiyasi degan muammo bizda umuman yo‘q

Shu ikki fakt tanlovni erkin qoldiradi:

  • B-tree — o‘qish kechikishi bashoratli (har doim 1–2 IO), operatsion tajriba ko‘p, tranzaksiya va UNIQUE cheklovi tayyor. Maxsus kalitlar uchun bu oxirgi nuqta muhim
  • LSM — yozish arzon (bizga unchalik kerak emas, 200/s), lekin compaction operatsion yuk qo‘shadi va p99 ni vaqti-vaqti bilan buzadi

Xulosa: bu yuk uchun B-tree tabiiyroq, LSM esa yozish hajmi 100 barobar oshganda yoki gorizontal masshtablash boshqaruvi muhimroq bo‘lganda mantiqiy. Amalda tanlov ko‘pincha texnik emas — jamoada qaysi bazani operatsion qilishni biladi degan savolga tayanadi, va bu ham to‘g‘ri mezon.

4.5 Replikatsiya va “o‘zi yozganini o‘qish” muammosi

O‘qish yukini ko‘tarish uchun replikalar qo‘shamiz. Replikatsiya asinxron — kechikish odatda 10–100 ms, yuk paytida sekundlarga chiqishi mumkin. Va shu yerda haqiqiy hayotda juda ko‘p uchraydigan bug paydo bo‘ladi:

1. Foydalanuvchi havola yaratdi        -> asosiy bazaga yozildi
2. 200 ms dan keyin havolani bosdi     -> so'rov replikaga tushdi
3. Replikada hali yozuv yo'q           -> 404

Foydalanuvchi uchun bu “sizning xizmatingiz buzuq” degani. Uch yechim bor:

YechimQanday ishlaydiKamchiligi
Yaratishda keshga yozishYozuv bazaga tushishi bilan keshga ham qo‘yiladiKesh tushsa muammo qaytadi
Yozgandan keyin asosiy bazadan o‘qishN soniya davomida shu foydalanuvchi asosiy bazaga yo‘naltiriladiAsosiy bazaga qo‘shimcha yuk; sessiya holati kerak
Versiya belgisi (LSN)Mijozga yozuv pozitsiyasi beriladi, o‘qishda replika shu pozitsiyaga yetganini tekshiradiMurakkab; barcha qatlamlar qo‘llab-quvvatlashi kerak

Bizning holatimizda birinchisi eng yaxshi: yaratish paytida yozuvni darhol keshga qo‘yamiz. Bu tabiiy, chunki yangi havola deyarli har doim darhol bosiladi — ya’ni u allaqachon “issiq” ma’lumot.

Nazorat savoli · javobni ko‘rishNega 'yozgandan keyin asosiy bazadan o'qish' yechimi bu tizimda yomon ishlaydi?

Chunki havolani yaratgan odam bosmaydi. U havolani boshqa joyga qo‘yadi — xatga, postga, bannerga — va uni butunlay boshqa odamlar, boshqa qurilmalardan, boshqa mintaqalardan bosadi.

“Sessiya bo‘yicha asosiy bazaga yo‘naltirish” faqat yaratuvchining o‘zi uchun ishlaydi, qolgan hammasi uchun emas. Shuning uchun to‘g‘ri yechim — yozuvni global ko‘rinadigan joyga (keshga) darhol qo‘yish, yoki replikatsiya kechikishini havola tarqalish vaqtidan kichik ushlab turish.

5. Nima sindi: v0 ning oltita zaif nuqtasi

Oddiy tilda: kutubxona mashhur bo‘ldi. Endi bitta daftar oldida minglab odam turibdi, ular orasida hammasi bir xil kitobni so‘rayotgan olomon bor, kimdir har kirganni sanab daftarga chiziq tortyapti, kimdir esa ataylab mavjud bo‘lmagan raqamlarni so‘rab kutubxonachini band qilyapti. Va kutubxona boshqa shaharda — odamlar yo‘lda soatlab yuradi. v0 ning har bir zaif nuqtasi shu manzaraning bir bo‘lagi.

5.1 O‘qish yuki bazani bo‘g‘adi

19 300 redirect/s — har biri bitta SELECT. Bitta Postgres instansiyasi yaxshi holatda 5 000–15 000 oddiy so‘rovni uddalaydi. Ya’ni cho‘qqida tizim yiqiladi, va yiqilish sekin emas: ulanishlar to‘lib, kutish vaqti oshib, timeout‘lar boshlanadi.

5.2 Bitta havola butun tizimni yiqitishi mumkin

Mashhur bloger bitta havolani ulashdi. U sekundiga 50 000 marta bosilyapti — bitta kalit, bitta baza qatori. Sharding yordam bermaydi (hammasi bitta shardda), replikatsiya qisman yordam beradi. Bu hot key muammosi.

5.3 Statistika yozish o‘qishdan qimmatroq

Har bosishda UPDATE links SET clicks = clicks + 1 yozsak, bitta qatorga sekundiga 50 000 marta yozish kerak bo‘ladi. Bu qulf raqobati (lock contention): tranzaksiyalar navbatga tizilib, redirect kechikishi sekundlarga chiqadi.

5.4 Yaratish yo‘li koordinatsiyaga bog‘lanib qoldi

Har bir yozuvda INSERT + to‘qnashuvda qayta urinish. Maydon to‘lib borgani sari qayta urinishlar ko‘payadi va yozish kechikishi o‘sadi.

5.5 Geografiya hisobga olinmagan

Server Frankfurtda, foydalanuvchi Toshkentda. Faqat tarmoq 150 ms qo‘shadi — server 5 ms ishlaganida. 2.2-bo‘limdagi byudjetga qarang: bu eng katta yo‘qotish.

5.6 Yo‘q havolalar bazani urib turadi

Bot va skanerlar mavjud bo‘lmagan kalitlarni so‘rab turadi (/aaa, /aab, …). Har biri keshda topilmaydi va to‘g‘ri bazaga tushadi. Bu — cache penetration hujumi va u oddiy skaner tomonidan tasodifan ham amalga oshiriladi.

MuammoBelgisiQaysi qadamda hal qilinadi
O‘qish yukiBaza CPU 100%, timeout2-qadam: kesh
Hot keyBitta shard yonadi3-qadam: chekka kesh, 6-qadam
Statistika yozuviRedirect sekinlashdi8-qadam: asinxron quvur
Yozish koordinatsiyasiYozish kechikishi o‘syapti5-qadam: KGS
Geografiyap99 uzoq mintaqalarda yomon4-qadam: anycast va edge
Yo‘q kalitlarKeshsiz so‘rovlar oqimi7-qadam: Bloom filtri
Nazorat savoli · javobni ko‘rishNega sharding hot key muammosini hal qilmaydi?

Sharding ma’lumotni kalit bo‘yicha bo‘ladi: shard = hash(kalit) % N. Bitta kalit har doim bitta shardga tushadi. Agar shu kalit sekundiga 50 000 marta so‘ralsa, butun yuk o‘sha bitta shardga boradi — qolgan shardlar bo‘sh turadi.

Hot key uchun boshqa vositalar kerak: (1) chekka/CDN keshi — so‘rov umuman origin‘ga yetib kelmaydi, (2) ilova serverlarida mahalliy kesh (bir necha soniyalik TTL bilan ham yetarli), (3) o‘qish replikalari, (4) hot kalitni bir necha shardga replikatsiya qilish. Amalda birinchi ikkitasi 99% holatni yopadi.

6. Evolyutsiya: o‘n to‘rt qadam

Qadamlar mantiqiy tartibda: 1–4 — o‘qish yo‘li (saqlash, kesh, hot key, chekka); 5–7 — kalitlar, shardlar va yo‘q kalitlar; 8 — analitika; 9–11 — mahsulot va suiiste’mol; 12–14 — ko‘p mintaqa, metama’lumot va o‘n yillik umr. Har qadamda yutuq va narx yozilgan: bepul qadam yo‘q.

1

To'g'ri saqlash tanlash

Oddiy tilda: kutubxonada “asosiy katalog” (har kitob haqida hamma ma’lumot) va kirish eshigidagi “tezkor ma’lumotnoma” (faqat raqam va javon) alohida. Katalogni sinchkov kutubxonachi yuritadi, ma’lumotnoma esa tez javob berish uchun.

Bizga kerak bo‘lgan operatsiya — birlamchi kalit bo‘yicha aniq qidiruv. Bu SQL bazasining eng kuchli tomoni emas:

SaqlashKalit bo‘yicha o‘qishNima uchun tanlanadiNima uchun tanlanmaydi
PostgreSQL~0.2 ms (issiq)Tranzaksiya, ikkilamchi indekslar, oddiy operatsiyaBitta tugun o‘qishda cheklangan
DynamoDB / Cassandra~2–5 msChiziqli masshtablanadi, boshqariladiMurakkab so‘rov yo‘q, narx
Redis (asosiy saqlash)~0.1 msEng tezRAM narxi: 3.7 TB uchun juda qimmat
Edge KV (Workers KV va sh.k.)~5 ms, lekin foydalanuvchiga yaqinGeografiya bepul keladiYozish sekin, izchillik bo‘shroq

Amaliy naqsh: manba haqiqat SQL bazada (yaratish, egalik, hisobot, tranzaksiya), o‘qish yo‘li esa kesh va chekka KV orqali. Ikkisi orasidagi izchillik “oxir-oqibat” (eventual) bo‘lishi mumkin — bir necha soniyalik kechikish redirect uchun sezilmaydi.

Yutuq: Yozish va o'qish yo'llari bir-biriga xalaqit bermaydi

Narxi: Ikkita saqlash tizimi = ikkita operatsion yuk

2

Kesh — o'qish yukining 95% ini yechish

Oddiy tilda: kutubxonachi eng ko‘p so‘raladigan yuzta kitobning manzilini yoddan biladi. Har safar daftarni varaqlamaydi — faqat kamdan-kam so‘raladigan kitob uchun.

Havolalarga murojaat Zipf taqsimoti bo‘yicha: kichik qism havolalar trafikning katta qismini oladi.

Hisob · Kesh hajmi va urish darajasi
Faraz: eng faol 20 million havola trafikning 95% ini oladi Kesh yozuvi: kalit (7) + URL (400) + qo'shimcha (~100) = ~510 bayt 20e6 x 510 = 10.2 GB Bitta Redis tuguni (32 GB) bemalol sig'diradi. Bazaga qoladigan yuk: 19 300 x (1 - 0.95) = 965 so'rov / soniya
Natija: 10 GB kesh bilan urish darajasi ~95%. Bazaga qolgan yuk 965/s — bitta instansiya bemalol uddalaydi

Kesh naqshi — cache-aside:

def resolve(key):
    url = cache.get(key)
    if url is not None:
        return None if url == NEGATIVE else url   # 404 ham keshlanadi
    row = db.query_one("SELECT target_url FROM links WHERE key=%s AND is_active", (key,))
    if row is None:
        cache.set(key, NEGATIVE, ttl=60)          # qisqa TTL: yo'q kalitlar uchun
        return None
    cache.set(key, row.target_url, ttl=86400)
    return row.target_url

Ikki nozik nuqta darhol ko‘rinadi:

  1. Salbiy keshlash (negative caching) — yo‘q kalitlar ham keshlanishi kerak, aks holda skanerlar to‘g‘ri bazani uradi (5.6-bo‘lim). TTL qisqa: yangi yaratilgan havola tez ko‘rinsin
  2. TTL va invalidatsiya — havola o‘chirilganda yoki manzili o‘zgarganda keshni ham yangilash kerak. Aks holda o‘chirilgan havola yana bir kun ishlab turadi
▸Chuqurroq: Siqib chiqarish siyosati: nega LRU bu yerda xavfli

Kesh to‘lganda nimani chiqarib tashlaymiz? Tanlov urish darajasiga bevosita ta’sir qiladi.

SiyosatQanday ishlaydiBu yukda
LRUEng uzoq vaqt ishlatilmaganini chiqaradiSkanerlashga chidamsiz
LFUEng kam ishlatilganini chiqaradiEski mashhur havolalar qotib qoladi
W-TinyLFUChastotani ixcham sanab, LRU bilan birlashtiradiEng yaxshi tanlov

Skanerlash muammosi aynan shu yerda ko‘rinadi. Bot sekundiga minglab yangi kalitni so‘raydi. LRU da har bir yangi kalit keshga kiradi va eng issiq havolalarni siqib chiqaradi:

Kesh: 20M yozuv, LRU
Skaner: 5000 yangi kalit / soniya

1 soatda: 18 million yangi (foydasiz) yozuv keshga kirdi
  -> issiq havolalarning katta qismi chiqarib yuborildi
  -> urish darajasi 95% dan 60% ga tushdi
  -> bazaga yuk 4-8 barobar oshdi

Uch himoya: (1) salbiy yozuvlarni alohida, kichik hajmli keshda saqlash, (2) W-TinyLFU — yangi element keshga kirish uchun avval chastota bo‘yicha “imtihondan” o‘tishi kerak, bir martalik so‘rovlar keshni buzmaydi, (3) Bloom filtri (7-qadam) — yo‘q kalitlar keshgacha ham yetib bormaydi.

Yutuq: Bazaga yuk 19 300/s dan ~1000/s ga tushdi

Narxi: Izchillik kechikishi; invalidatsiya mantiqi; yangi nosozlik rejimlari

3

Ikki qatlamli kesh — hot key uchun

Oddiy tilda: hamma bir xil kitobni so‘rasa, kutubxonachi uning manzilini har bir kirish eshigiga qog‘ozga yozib osib qo‘yadi. Odamlar ichkariga kirmay ham javobni o‘qiydi.

Redis ham chegarasiz emas: bitta kalit sekundiga 500 000 marta so‘ralsa, u bitta Redis tuguniga tushadi va tarmoq kartasi to‘yinadi.

Yechim — ilova serverining o‘z xotirasida kichik kesh (L1):

So'rov -> L1 (jarayon xotirasi, 10 000 ta eng issiq kalit, TTL 5 s)
       -> L2 (Redis, 20M kalit, TTL 24 soat)
       -> Baza
Hisob · L1 keshning ta'siri
50 ta ilova serveri, hot kalitga 500 000 so'rov/s L1 kesh TTL = 5 soniya bo'lsa: Har bir server 5 soniyada bir marta Redis'ga boradi 50 server / 5 soniya = 10 so'rov / soniya Redis'ga Redis yuki: 500 000 -> 10
Natija: Atigi 5 soniyalik L1 kesh Redis'ga yukni 5000 barobar kamaytiradi. Narxi: havola o'chirilsa, 5 soniyagacha ishlab turishi mumkin

Yutuq: Bitta havola sekundiga million marta bosilsa ham tizim sezmaydi

Narxi: Bir necha soniyalik nomuvofiqlik: turli serverlar turli javob berishi mumkin

4

Chekka (edge) redirect — geografiyani yechish

Oddiy tilda: bitta markaziy kutubxona o‘rniga har mahallada kichik filial ochiladi va ularda ma’lumotnomaning nusxasi turadi. Odam eng yaqin filialga boradi.

2.2-bo‘limdagi byudjetni eslang: server ishi 5 ms, tarmoq 150 ms. Demak eng katta yutuq — foydalanuvchiga yaqinlashish.

Bitta mintaqa (Frankfurt)
  • Toshkentdan RTT ~120 ms
  • TLS qo'l siqish bilan ~250 ms
  • Oddiy va arzon
  • Mintaqa tushsa — hamma joyda ishlamaydi
Anycast + chekka KV
  • Eng yaqin nuqtagacha ~15 ms
  • TLS ham chekkada tugaydi
  • Redirect origin'ga umuman bormaydi
  • Yangilanish 10-60 soniyada tarqaladi

Chekkada redirect qilish uchun kerak bo‘lgan hamma narsa — kalit va URL. Bu juda kichik ma’lumot, shuning uchun uni yuzlab nuqtaga tarqatish arziydi. Analitika esa chekkadan asinxron ravishda markazga yuboriladi.

▸Chuqurroq: Chekka keshda izchillik: nima bilan to'laymiz

Chekka nuqtalar ma’lumotni o‘nlab soniyada oladi. Amaliy oqibatlari:

  • Yangi havola darhol ishlamasligi mumkin — foydalanuvchi qisqartirdi, darhol bosdi, 404 oldi. Chora: yaratilgan mintaqada darhol yozish va boshqa nuqtalarda “topilmasa origin‘dan so‘rash” (stale-if-error emas, miss-to-origin) siyosati
  • O‘chirilgan havola bir muddat ishlab turishi mumkin — zararli havolani o‘chirishda bu jiddiy: majburiy invalidatsiya (purge) mexanizmi kerak
  • Analitika kechikadi — chekkadan hodisalar paketlab yuboriladi

Bu — CAP teoremasining amaliy ko‘rinishi: redirect uchun mavjudlik va tezlik izchillikdan muhimroq, shuning uchun ataylab eventual consistency tanlanadi.

▸Chuqurroq: CDN keshi va chekka KV: bir xil emas

Ikki xil yondashuvni chalkashtirmaslik kerak.

CDN javob keshi — chekka nuqta sizning origin‘ingizdan kelgan javobni keshlaydi:

HTTP/1.1 302 Found
Location: https://example.com/...
Cache-Control: public, s-maxage=300, stale-if-error=86400

s-maxage — faqat CDN uchun (brauzer uchun emas), ya’ni chekka 5 daqiqa keshlaydi, lekin brauzer keshlamaydi va analitika saqlanadi. stale-if-error esa origin tushganda eskirgan javobni berishga ruxsat beradi — bepul mavjudlik.

Chekka KV — ma’lumotning o‘zi (kalit → URL) chekkaga replikatsiya qilinadi va redirect butunlay o‘sha yerda hisoblanadi. Origin umuman ishtirok etmaydi.

CDN javob keshiChekka KV
Birinchi so‘rovOrigin‘ga boradi (sekin)Chekkada hal bo‘ladi
InvalidatsiyaPurge API, tezReplikatsiya kechikishi
AnalitikaChekkadan yig‘iladiChekkadan yig‘iladi
Origin tushsastale-if-error bilan ishlaydiButunlay ishlaydi
MurakkablikPastYuqori

Amaliy yo‘l: ikkalasi ham. Chekka KV asosiy yo‘l, CDN keshi esa KV da topilmagan va origin‘ga ketgan so‘rovlar uchun qo‘shimcha qatlam.

Yutuq: p99 kechikish 200 ms dan 40 ms ga tushdi

Narxi: Ma'lumotni yuzlab nuqtaga tarqatish; yangilanish kechikishi

5

Kalit generatsiya xizmati (KGS)

Oddiy tilda: har safar markaziy idoraga qo‘ng‘iroq qilib “keyingi raqam qaysi?” deb so‘rash o‘rniga, har filial bir yo‘la mingta raqamli “chiptalar to‘plami”ni olib qo‘yadi va ularni o‘zi tarqatadi.

3.3-bo‘limdagi hisob: kalitlarni blok-blok oldindan tarqatish markazga yukni 10 000 barobar kamaytiradi.

KGS bazasi:  [kalit, band_mi]  yoki oddiyroq — diapazon jadvali

Ilova serveri ishga tushganda:
  1. KGS dan 10 000 talik diapazon oladi        (bitta so'rov)
  2. Xotirasida saqlaydi
  3. Har yozuvda navbatdagisini oladi           (koordinatsiyasiz)
  4. Tugagach yangi diapazon so'raydi

Muhim tafsilot: diapazon ketma-ket bo‘lsa, kalitlar taxmin qilinadigan bo‘lib qoladi (3.4-bo‘limdagi ogohlantirish). Shuning uchun diapazondagi sonlar bijektiv permutatsiya (masalan Feistel shifri) orqali aralashtiriladi: to‘qnashuv baribir bo‘lmaydi, lekin ketma-ketlik ko‘rinmaydi.

Yutuq: Yozish yo'lida tekshirish ham, to'qnashuv ham yo'q

Narxi: Yangi xizmat, uning zaxirasi va monitoringi

6

Sharding va izchil xeshlash

Oddiy tilda: kartochkalar bitta qutiga sig‘may qoldi. Ularni harf bo‘yicha o‘nta qutiga bo‘lamiz — lekin keyin o‘n birinchi quti qo‘shilganda hamma kartochkani qayta saralamaslik kerak.

3.7 TB bitta tugunga sig‘maydi. Kalit bo‘yicha shardlaymiz:

shard = hash(kalit) mod N

Bu oddiy usulning muammosi: N o‘zgarganda deyarli barcha kalitlar joyini o‘zgartiradi. 10 dan 11 shardga o‘tishda ma’lumotning ~91% i ko‘chishi kerak.

▸Chuqurroq: Izchil xeshlash: nega ko'chish 1/N ga tushadi

Izchil xeshlashda shardlar ham, kalitlar ham bitta doiraga (hash halqasiga) joylashtiriladi. Kalit soat yo‘nalishi bo‘yicha o‘ziga eng yaqin shardga tegishli bo‘ladi.

Yangi shard qo‘shilganda faqat uning halqadagi qo‘shnisidan kalitlar ko‘chadi — ya’ni o‘rtacha 1/N qism. 10 dan 11 shardga o‘tishda 91% emas, ~9% ko‘chadi.

Amalda har bir jismoniy shard halqada 100–200 ta virtual tugun sifatida ko‘rsatiladi — aks holda yuk notekis taqsimlanadi (ba’zi shardlar halqaning katta bo‘lagini oladi).

Muqobil usul — jadval asosida marshrutlash: kalit maydoni 4096 ta mantiqiy bo‘lakka bo‘linadi, alohida jadval har bir bo‘lak qaysi shardda ekanini ko‘rsatadi. Ko‘chirish bo‘lak darajasida, nazorat ostida bajariladi. Ko‘p yirik tizimlar aynan shu usulni tanlaydi: u izchil xeshlashdan sodda va bashoratliroq.

Yutuq: Ma'lumot va yuk chiziqli masshtablanadi

Narxi: Qayta shardlash og'riqli; shardlararo so'rovlar murakkab

7

Bloom filtri — yo'q kalitlarni tez rad etish

Oddiy tilda: eshik oldidagi qorovulda “mavjud bo‘lmagan raqamlar” ro‘yxati emas, balki juda ixcham “bo‘lishi mumkin bo‘lganlar” jadvali bor. U ba’zan adashib “bo‘lishi mumkin” deydi, lekin “yo‘q” desa — aniq yo‘q.

Salbiy keshlash (2-qadam) yordam beradi, lekin skaner har safar yangi kalit so‘raydi — kesh unga bo‘sh.

Bloom filtri — ehtimollik strukturasi: “bu kalit aniq yo‘q” yoki “bo‘lishi mumkin” degan javob beradi. Birinchi javob 100% ishonchli, ya’ni yo‘q kalitlarni bazaga yubormasdan rad etish mumkin.

Hisob · Bloom filtri hajmi
Formula: bit_soni = -n x ln(p) / (ln2)^2 n = 6e9 kalit p = 0.01 (1% noto'g'ri ijobiy): bit/element = -ln(0.01) / 0.4805 = 9.59 jami = 6e9 x 9.59 = 5.75e10 bit = 7.2 GB p = 0.1 (10%): bit/element = 2.303 / 0.4805 = 4.79 jami = 3.6 GB Xesh funksiyalar soni: k = (m/n) x ln2 = 9.59 x 0.693 = ~7
Natija: 6 milliard kalit uchun 7.2 GB (1% xato) yoki 3.6 GB (10% xato). Shard bo'yicha bo'linsa, har bir tugunga 720 MB — maqbul

10% noto‘g‘ri ijobiy ham yetarli: skaner so‘rovlarining 90% i darhol rad etiladi, qolgan 10% i bazaga boradi va u yerda topilmaydi. Yuk 10 barobar kamayadi, xotira esa ikki barobar kam ketadi.

Yutuq: Mavjud bo'lmagan kalitlar bazaga umuman yetib bormaydi

Narxi: Xotira; noto'g'ri ijobiy javoblar; o'chirish qo'llab-quvvatlanmaydi

8

Analitika quvuri — redirect yo'lidan chiqarish

Oddiy tilda: kim qaysi kitobni so‘raganini kutubxonachi o‘sha zahoti daftarga yozib o‘tirmaydi — qog‘ozchaga belgilab, savatga tashlaydi. Kechqurun boshqa odam savatni sanaydi.

5.3-bo‘limdagi muammo: har bosishda bazaga yozish redirect‘ni o‘ldiradi.

Bosish hodisasining yo'li
Redirect serveri
302 javobini darhol qaytaradiHodisani mahalliy buferga qo'yadi

Foydalanuvchi kutmaydi. Bufer to'lsa — hodisa TASHLANADI (bu to'g'ri qaror).

Oqim
Kafka yoki shunga o'xshash navbat

Paketlab yuboriladi: 1000 ta hodisa yoki 1 soniya — qaysi biri oldin bo'lsa.

Qayta ishlash
Real-time agregatsiyaXom hodisalarni arxivga yozish

Ikki yo'l: tezkor hisoblagichlar va batafsil tahlil uchun xom ma'lumot.

Saqlash
Hisoblagichlar (Redis)OLAP bazaObyekt xotira (xom)

Har biri boshqa savolga javob beradi.

Hisob · Analitika hajmi
Bitta hodisa: kalit(7) + vaqt(8) + IP(16) + User-Agent(~120) + referrer(~60) + geo(~10) = ~220 bayt O'rtacha yuk: 3860 bosish/s 3860 x 220 = 849 KB/s = 73 GB / kun Cho'qqida: 19 300 x 220 = 4.2 MB/s
Natija: Kuniga 66 GB xom hodisa. Yiliga 24 TB — xom holda saqlash qimmat, shuning uchun agregatsiya va namuna olish kerak
▸Chuqurroq: Noyob tashrif buyuruvchilarni qanday sanaymiz

“Bu havolani nechta noyob odam bosgan?” degan savol qiyin: aniq javob uchun barcha identifikatorlarni saqlash kerak. 10 million bosishli havola uchun bu 160 MB — bitta havola uchun.

HyperLogLog buni ehtimollik bilan yechadi: 12 KB xotirada milliardlab elementni ~1% xato bilan sanaydi. 10 000 barobar tejash.

PFADD link:K7xQm2:visitors <foydalanuvchi_id>
PFCOUNT link:K7xQm2:visitors   ->  1 043 219 (standart xato ~0.8%)

Yana bir yutuq: HLL strukturalarini birlashtirish mumkin. Kunlik HLL larni qo‘shib, aniq noyob elementlarni qayta sanamasdan haftalik yoki oylik ko‘rsatkich olinadi. Oddiy hisoblagichlar bilan bu mumkin emas (kunlik summalar noyoblikni bermaydi).

Yutuq: Redirect 2 ms da qoladi; statistika buzilsa ham havolalar ishlaydi

Narxi: Oxir-oqibat izchillik: statistika bir necha daqiqa kechikadi

9

Maxsus kalitlar (custom alias)

Oddiy tilda: ba’zi o‘quvchilar kitobga o‘z nomini berishni xohlaydi — “kafka”. Ikki kishi bir vaqtda bir xil nomni so‘rasa, faqat bittasi olishi kerak, va “kirish” yoki “yordam” kabi xizmat so‘zlarini hech kim ololmaydi.

dars.uz/kafka — foydalanuvchi o‘zi tanlagan kalit. Uchta muammo darhol paydo bo‘ladi:

  1. Poyga holati: ikki foydalanuvchi bir vaqtda bir xil kalitni so‘raydi. Yechim — bazadagi unikal cheklov (UNIQUE), ilovada tekshirish emas. “Avval tekshirib, keyin yozish” naqshi har doim poyga holatiga olib keladi
  2. Band so‘zlar: api, login, admin, static, health — bular marshrutlar bilan to‘qnashadi. Qora ro‘yxat shart, va u marshrutlar bilan birga o‘sib borishi kerak
  3. Kalit maydonlarining aralashishi: generatsiya qilingan kalit maxsus kalit bilan to‘qnashmasligi uchun ular alohida maydonda bo‘lishi mumkin (masalan generatsiya qilinganlari doim 7 belgi, maxsuslari esa 3–6 yoki 8+)

Yutuq: Mahsulotning eng ko'p so'raladigan xususiyati

Narxi: Poyga holati, band so'zlar, brend nizolari

10

Muddat, o'chirish va tozalash

Oddiy tilda: kitob kutubxonadan chiqarildi. Kartochka yo‘qotilmaydi — ustiga “chiqarilgan” muhri bosiladi, aks holda raqam yangi kitobga berilib, eski raqamni bilganlar boshqa kitobga tushib qoladi.

Havola o‘chirilganda uch joyda yo‘qolishi kerak: bazada, keshda, chekkada. Eng qiyini — oxirgisi (4-qadamdagi izchillik masalasi).

DELETE /api/links/K7xQm2
  1. Bazada is_active = false        (tombstone, qator o'chirilmaydi)
  2. Keshdan o'chirish yoki NEGATIVE qilib belgilash
  3. Chekka nuqtalarga purge signali
  4. Bloom filtridan chiqarilmaydi (o'chirib bo'lmaydi - 7-qadam)

Nega qator butunlay o‘chirilmaydi: kalit qayta ishlatilmasligi kerak. Aks holda eski havolani bosgan odam butunlay boshqa saytga tushadi — bu ham chalkashlik, ham xavfsizlik muammosi. Tombstone kalitni abadiy band qilib turadi.

Muddati o‘tgan havolalarni tozalash fon jarayoni orqali, kichik paketlarda bajariladi — bir vaqtda million qatorni o‘chirish bazani bloklaydi.

Yutuq: Baza cheksiz o'smaydi; huquqiy talablar bajariladi

Narxi: Fon jarayonlari, tombstone'lar, keshni majburiy tozalash

11

Suiiste'molga qarshi himoya

Oddiy tilda: firibgarlar kutubxonaning obro‘sidan foydalanib, odamlarni “kutubxona tavsiya qildi” degan yolg‘on manzilga yuboradi. Kutubxona buni to‘xtatmasa, shahar hokimiyati butun kutubxonani “xavfli” deb belgilaydi.

Bepul qisqartiruvchi — fishing va zararli dastur uchun mukammal vosita: haqiqiy manzil yashiriladi, domeningizning obro‘si esa hujumchiga ishlaydi.

Agar domeningiz qora ro‘yxatga tushsa (Google Safe Browsing, brauzer filtrlari), barcha havolalaringiz — halol foydalanuvchilarniki ham — brauzerda ogohlantirish bilan ochiladi. Bu mahsulot uchun halokat.

ChoraQachon ishlaydiNarxi
Yaratishda URL ni skanerlashMa’lum zararli manzillarYaratishga 100–300 ms
Davriy qayta skanerlashManzil keyin zararli bo‘lsaFon yuki
Domenlar qora ro‘yxatiMa’lum yomon domenlarYangilab turish kerak
Oraliq ogohlantirish sahifasiShubhali havolalarRedirect tezligi yo‘qoladi
Yaratish uchun ro‘yxatdan o‘tishAnonim suiiste’molni kamaytiradiKonversiya tushadi
Tezlik cheklovi (IP, akkaunt)Ommaviy yaratishHalol foydalanuvchiga ham ta’sir
▸Chuqurroq: Tezlik cheklovi algoritmlari: qaysi birini tanlash

Sobit oyna (fixed window) — eng oddiy: INCR key:user:minute, muddat 60 s. Muammosi chegarada:

Limit: daqiqasiga 100 ta

12:00:59 da 100 ta so'rov  (birinchi oyna)
12:01:00 da 100 ta so'rov  (ikkinchi oyna)
-> 2 soniyada 200 ta so'rov o'tdi, limit esa 100 edi

Siljituvchi oyna jurnali (sliding window log) — har bir so‘rov vaqtini saqlaymiz, eski yozuvlarni tashlaymiz. Aniq, lekin xotira: 100 000 foydalanuvchi × 100 ta vaqt belgisi = 80 MB, va har so‘rovda ro‘yxatni tozalash kerak.

Siljituvchi oyna hisoblagichi — oldingi va joriy oynani og‘irlik bilan qo‘shamiz:

joriy oynaning 30% i o'tgan bo'lsa:
  taxminiy = oldingi_oyna x 0.7 + joriy_oyna

Aniq emas, lekin xotirasi ikkita hisoblagich va chegara muammosini yechadi. Amalda eng ko‘p ishlatiladigan variant.

Token bucket — chelakka doimiy tezlikda token quyiladi, har so‘rov bittasini oladi. Portlashlarga (burst) ruxsat beradi, lekin o‘rtacha tezlikni ushlaydi — API uchun eng qulay xatti-harakat.

Taqsimlangan muhitdagi tuzoq: “o‘qish → tekshirish → yozish” ketma-ketligi poyga holatiga olib keladi. Bir nechta server bir vaqtda tekshirsa, limit ikki-uch barobar oshib ketadi. Yechim — Redis‘da Lua skript yoki atomik INCR + EXPIRE: tekshirish va yangilash bitta bo‘linmas amalda bo‘lishi shart.

Yutuq: Domen qora ro'yxatga tushmaydi

Narxi: Yaratish yo'liga kechikish; noto'g'ri bloklashlar

12

Ko'p mintaqali yozish

Oddiy tilda: ikki shahardagi filial bir vaqtda yangi raqam beradi. Ular bir xil raqamni bermasligi uchun oldindan kelishib oladi: biri faqat A–H harflari bilan boshlanadiganini beradi, ikkinchisi — qolganini.

O‘qish yo‘li allaqachon global (4-qadam). Yozish esa odatda bitta mintaqada qoladi — bu oddiy va xavfsiz. Ko‘p mintaqada yozish kerak bo‘lsa, kalit to‘qnashuvi muammosi paydo bo‘ladi.

Eng oddiy va ishonchli yechim — kalit maydonini mintaqalar orasida oldindan bo‘lish:

Mintaqa A: kalitning birinchi belgisi [a-h] dan
Mintaqa B: [i-p] dan
Mintaqa C: [q-z, A-Z, 0-9] dan

Endi ikki mintaqa hech qachon bir xil kalitni bera olmaydi va koordinatsiya umuman kerak emas. Bu — taqsimlangan tizimlardagi umumiy naqsh: konfliktni yechish o‘rniga, uni imkonsiz qilish.

Yutuq: Bitta mintaqa tushsa ham yaratish ishlaydi

Narxi: Konflikt: bir xil kalit ikki mintaqada band bo'lishi mumkin

13

Metama'lumot: oldindan ko'rish va QR

Oddiy tilda: havola ijtimoiy tarmoqda “kitob muqovasi” bilan ko‘rinishi uchun kimdir kitobni bir marta ochib, muqovasini suratga olib qo‘yishi kerak. Har so‘rovda kitobni qayta ochish — sekin, va begona “kitob” ichida tuzoq bo‘lishi mumkin.

Ijtimoiy tarmoqlar havolani ochganda og:title, og:image teglarini qidiradi. Qisqa havola bo‘lsa, ular sizning serveringizdan so‘raydi.

Ikki variant: har so‘rovda maqsad sahifani o‘qish (sekin, ishonchsiz, SSRF xavfi) yoki metama’lumotni yaratish paytida bir marta olib, saqlab qo‘yish. Ikkinchisi to‘g‘ri.

▸Chuqurroq: Maxsus domenlar: TLS sertifikatlarini masshtabda boshqarish

Mijozlar o‘z domenlarini xohlaydi: go.brand.uz CNAME orqali sizning tizimingizga ishora qiladi. Mahsulot uchun kuchli xususiyat, lekin ortida jiddiy infratuzilma bor.

Har bir maxsus domen uchun TLS sertifikati kerak. 100 000 mijoz domeni bo‘lsa:

Sertifikat muddati: 90 kun
Yangilash 60-kunda boshlanadi
Kunlik yangilash: 100 000 / 60 = ~1670 sertifikat / kun

Jarayon to‘liq avtomat bo‘lishi shart va unda bir nechta tuzoq bor:

  • ACME tezlik cheklovlari — sertifikat markazlari haftalik limit qo‘yadi; yangilashlarni vaqt bo‘ylab tekis taqsimlash kerak, aks holda limitga urilib qolasiz
  • Domen tasdiqlash — mijoz DNS yozuvini noto‘g‘ri qo‘ysa, tasdiqlash muvaffaqiyatsiz bo‘ladi. Buni oldindan aniqlab xabar berish kerak, sertifikat tugagandan keyin emas
  • SNI va sertifikat saqlash — chekka nuqtalar minglab sertifikatni xotirada ushlashi va so‘rov kelganda to‘g‘risini tanlashi kerak
  • Nosozlik oqibati og‘ir — sertifikat yangilanmasa, mijozning barcha havolalari brauzerda “xavfli sayt” ogohlantirishi bilan ochiladi

Shuning uchun sertifikat quvuri alohida monitoring, alert va qayta urinish mantiqiga ega bo‘lishi kerak — bu mahsulotning eng jim, lekin eng xavfli qismlaridan biri.

Yutuq: Havola ijtimoiy tarmoqda chiroyli ko'rinadi

Narxi: Tashqi sahifani o'qish - sekin va xavfli

14

Kalit maydonini kengaytirish va migratsiya

Oddiy tilda: katalog raqamlari tugay boshladi. Raqamga yana bitta belgi qo‘shamiz — lekin eski raqamlar ham ishlashda davom etishi shart, chunki ular allaqachon kitoblarda chop etilgan.

Kalit uzunligi sobit bo‘lmasligi kerak. To‘g‘ri yondashuv: uzunlik ma’lumotdan o‘qiladi, kodga qotirilmaydi.

Yechish: kalit uzunligiga qarab emas, aynan kalit bo'yicha qidiriladi
  -> 5, 6, 7, 8 belgili kalitlar bir vaqtda yashaydi

Generatsiya: joriy uzunlik konfiguratsiyada
  -> maydon 20% to'lganda uzunlik bir belgiga oshiriladi

Shu tarzda eski havolalar abadiy ishlaydi (bu majburiy shart), yangi kalitlar esa kerakli maydonda generatsiya qilinadi.

▸Chuqurroq: Bitta bazadan shardlangan bazaga o'tish: xavfsiz migratsiya

Bu operatsiya ishlab turgan tizimda bajariladi va xatoga joy yo‘q — havola yo‘qolsa, u chop etilgan hamma joyda o‘ladi.

1-bosqich: IKKI TOMONLAMA YOZISH
   Yangi yozuvlar eski VA yangi bazaga yoziladi
   O'qish hali eskidan. Yangi bazaning to'g'riligi kuzatib boriladi

2-bosqich: TO'LDIRISH (backfill)
   6 milliard qator paketlab ko'chiriladi
   50 000 qator/s tezlikda: 6e9 / 5e4 = 120 000 s = ~33 soat
   Asosiy bazaga ta'sir qilmasligi uchun replikadan o'qiladi

3-bosqich: TEKSHIRISH
   Tasodifiy namuna solishtiriladi (masalan 1 million qator)
   Diapazonlar bo'yicha nazorat summalari
   Farq topilsa - sabab aniqlanmaguncha davom etilmaydi

4-bosqich: O'QISHNI BOSQICHMA-BOSQICH KO'CHIRISH
   1% -> 10% -> 50% -> 100%
   Har bosqichda 404 darajasi va kechikish kuzatiladi

5-bosqich: ESKI BAZANI O'CHIRISH
   Kamida bir necha hafta kutiladi - orqaga qaytish imkoni saqlanadi

Eng ko‘p qilinadigan xato — 3-bosqichni tashlab ketish. Ikki tomonlama yozishdagi mayda xatolar (masalan tranzaksiya rollback bo‘lganda faqat bitta bazaga yozilib qolishi) sezilmay to‘planadi va faqat o‘qish ko‘chirilgandan keyin 404 lar shaklida chiqadi — o‘shanda sababni topish ancha qiyin.

Yutuq: Tizim o'n yillar yashaydi

Narxi: Oldindan o'ylanmasa, keyin juda qimmat

Nazorat savoli · javobni ko‘rishKesh urish darajasi 95% dan 80% ga tushdi. Nima bo'lgan bo'lishi mumkin va bu bazaga qanday ta'sir qiladi?

Ta’sir: bazaga yuk 19 300 × 0.05 = 965 dan 19 300 × 0.20 = 3860 ga chiqadi — 4 barobar. Bu ko‘pincha bazani to‘yinish nuqtasiga olib boradi.

Sabablari (ehtimollik bo‘yicha):

  1. Kesh tugunlaridan biri tushgan yoki qayta ishga tushgan — sovuq kesh
  2. TTL noto‘g‘ri qisqartirilgan (masalan 24 soatdan 1 soatga)
  3. Kesh xotirasi to‘lib, evicton boshlangan — havolalar soni o‘sgan bo‘lishi mumkin
  4. Trafik naqshi o‘zgargan: ommaviy skanerlash yoki bot hujumi (salbiy keshlash yo‘q bo‘lsa)
  5. Deploy paytida kesh tozalangan

Diagnostika: kesh xotirasi va eviction soni, TTL taqsimoti, topilmagan kalitlarning ulushi (skanerlarni ko‘rsatadi), kesh tugunlari holati.

7. Bitta bosishning hayoti

Evolyutsiyadan keyin tizim ko‘p qatlamli bo‘lib qoldi. Endi bitta bosishni boshidan oxirigacha kuzatamiz. Shunda har qatlam nega kerakligi va vaqt qayerga ketishi ko‘rinadi.

7.1 Qadam-baqadam

Oddiy tilda: siz mahalladagi filialga kirasiz. Ko‘p hollarda kerakli ma’lumot shu yerdagi ma’lumotnomada bor — javob darhol. Kamdan-kam hollarda filial markaziy kutubxonaga qo‘ng‘iroq qiladi. Siz esa farqni faqat kutish vaqtidan sezasiz.

Brauzer: GET dars.uz/K7xQm2
DNS: anycast IP
Eng yaqin chekka: TCP + TLS
Chekka KV: K7xQm2 -> URL
302 + Location
Bosish hodisasi buferga
Brauzer asl sahifaga
Asosiy yo'l: so'rov origin'ga umuman bormaydi. Hodisa foydalanuvchi kutmagan holda, fonda yuboriladi
  1. DNS dars.uz uchun bitta IP qaytaradi, lekin bu IP yuzlab nuqtadan e’lon qilingan (anycast, 2.4). Tarmoq so‘rovni eng yaqin nuqtaga olib boradi.
  2. TCP va TLS chekkada tugaydi — foydalanuvchidan 10–20 ms masofada. Ilgari ulanish bo‘lgan bo‘lsa, bu qadam qayta ishlatiladi.
  3. Chekka KV da kalit bor bo‘lsa (odatda 90% va undan ko‘p), javob shu yerda yasaladi: 302 va Location.
  4. Bosish hodisasi chekkadagi buferga tushadi va paketlab markazga ketadi (8-qadam). Foydalanuvchi buni kutmaydi.
  5. Chekkada kalit yo‘q bo‘lsa — origin yo‘li: Bloom filtri → L1 → L2 → baza. Topilgan javob chekkada ham keshlanadi.

7.2 Vaqt qayerga ketadi

Hisob · Chekkada topilgan va topilmagan bosish
Toshkentdagi foydalanuvchi, yangi ulanish: A) Chekkada topildi (Toshkent yaqinidagi nuqta, RTT ~10 ms) DNS (keshda) ~5 ms TCP 10 ms TLS 1.3 (1 RTT) 10 ms So'rov + chekka KV 12 ms Javob 8 ms -------------------------------- Jami ~45 ms B) Chekkada yo'q -> origin Frankfurtda (RTT ~120 ms) A dagi qadamlar ~45 ms Chekka -> origin -> chekka ~120 ms (ulanish oldindan ochiq) L2 kesh yoki baza 1-5 ms -------------------------------- Jami ~170 ms O'rtacha (chekka 90%): 0.9 x 45 + 0.1 x 170 = ~58 ms O'rtacha (chekka 50%): 0.5 x 45 + 0.5 x 170 = ~108 ms
Natija: Chekkada topilgan bosish ~45 ms, origin'ga borgani ~170 ms. Chekka 90% ni yutsa, o'rtacha ~58 ms: kechikishning asosiy tutqichi — chekkada topilish ulushi

Bu hisobdan amaliy qoida chiqadi: chekkada topilish ulushini bitta asosiy metrika sifatida kuzating (14-bo‘lim). Serverdagi kod tezligini ikki barobar oshirish o‘rtachani 1–2 ms ga o‘zgartiradi. Chekkada topilish ulushini 50% dan 90% ga ko‘tarish esa o‘rtachani ~50 ms ga kamaytiradi.

7.3 Yangi havolaning birinchi daqiqasi

Eng nozik lahza — havola endigina yaratilgan payt. Ma’lumot hali hamma qatlamga yetib bormagan.

POST /api/v1/links
KGS blokidan kalit
SQL: INSERT (manba haqiqat)
L2 keshga darhol yozish
Bloom filtriga qo'shish
Chekkaga tarqatish (10-60 s)
Birinchi bosish
Birinchi to'rt qadam sinxron: javob qaytgunicha havola origin'da allaqachon ishlaydi. Chekka keyinroq yetib oladi

Agar birinchi bosish chekkaga havola yetib kelmasdan oldin kelsa, chekka uni topmaydi va origin’dan so‘raydi (miss-to-origin). Origin’da esa havola allaqachon bor: L2 keshda va Bloom filtrida. Ya’ni foydalanuvchi ozgina sekinroq javob oladi, lekin xato olmaydi.

Hisob · Birinchi daqiqa qanchalik muhim
Faraz: bosishlar eksponensial so'nadi, yarim yemirilish T = 3 soat (bit.ly 2011-yil tadqiqoti, soatda: Twitter 2.8, Facebook 3.2, to'g'ridan-to'g'ri ulashish 3.4, YouTube 7.4) Birinchi t vaqt ichidagi ulush = 1 - 2^(-t / T) t = 1 daqiqa (t/T = 1/180): 1 - 2^(-0.0056) = 0.38% t = 10 daqiqa: 1 - 2^(-0.056) = 3.8% t = 3 soat: 50% t = 24 soat: 1 - 2^(-8) = 99.6%
Natija: Yarim yemirilishi 3 soat bo'lgan havolaning bosishlaridan atigi ~0.4% i birinchi daqiqaga to'g'ri keladi. Shuning uchun chekkaga 10-60 soniyada tarqatish yetarli — muhimi, shu oraliqda 404 bermaslik
Nazorat savoli · javobni ko‘rishHavola yaratildi va 2 soniyadan keyin bosildi. Chekka uni hali bilmaydi. Qaysi bitta xato butun tajribani buzadi?

Chekkada 404 javobni uzoq keshlash. Ketma-ketlik:

  1. Bosish chekkaga tushdi, chekka KV da kalit yo‘q
  2. Chekka origin’dan so‘radi. Agar origin’da replikatsiya kechikkan bo‘lsa yoki so‘rov havola yaratilishidan millisoniyalar oldin kelgan bo‘lsa — 404
  3. Chekka bu 404 ni 5 daqiqaga keshladi
  4. Havola endi bazada bor, lekin shu chekka nuqtadagi hamma foydalanuvchi 5 daqiqa davomida 404 oladi — aynan eng ko‘p bosiladigan paytda

Choralar: chekkada salbiy javoblarni juda qisqa (bir necha soniya) yoki umuman keshlamaslik; origin’da havolani javob qaytishidan oldin L2 va Bloom filtriga yozish; replikatsiya kechikishi bor bo‘lsa, “yaqinda yaratilgan” kalitlar uchun asosiy bazadan o‘qish. Bu — 4.5 dagi “o‘zi yozganini o‘qish” muammosining chekkadagi ko‘rinishi.

8. Kesh matematikasi: nega oz sonli havola trafikning ko‘pini oladi

2-qadamda “eng faol 20 million havola trafikning 95% ini oladi” deb faraz qildik. Endi bu raqam qayerdan kelishini va qachon noto‘g‘ri bo‘lishini ko‘ramiz. Bu bo‘lim keshning hajmi, TTL va xarajatini hisoblash uchun asos bo‘ladi.

8.1 Oddiy tilda: vitrina

Oddiy tilda: kitob do‘konida yuz ming nom kitob bor, lekin kirish oldidagi vitrinada atigi ikki yuztasi turadi. Shunga qaramay, xaridorlarning katta qismi aynan vitrinadan oladi, chunki u yerda hozir hamma o‘qiyotgan kitoblar bor. Vitrina — kesh. Qanchalik kichik vitrina qanchalik ko‘p xaridorga xizmat qilishi ikki narsaga bog‘liq: kitoblar mashhurligi qanchalik notekis va mashhurlik qanchalik tez o‘zgaradi.

8.2 Notekislik: Zipf taqsimoti

Havolalar mashhurligi taxminan Zipf qonuniga bo‘ysunadi: eng mashhur havola ikkinchisidan taxminan ikki, uchinchisidan uch barobar ko‘p bosiladi. Umumiy holda i-o‘rindagi havolaning ulushi 1 / i^s ga proporsional. s qancha katta bo‘lsa, taqsimot shuncha notekis.

Hisob · Faqat mashhurlik bo'yicha urish darajasi
s = 1 da eng faol C ta havolaning ulushi: H(C) / H(N), H(n) = 1 + 1/2 + ... + 1/n ~ ln(n) + 0.577 N = 6 000 000 000 havola, C = 20 000 000 (kesh): H(C) ~ ln(2e7) + 0.577 = 16.81 + 0.58 = 17.39 H(N) ~ ln(6e9) + 0.577 = 22.52 + 0.58 = 23.10 Ulush ~ 17.39 / 23.10 = 75% C = 200 000 000 (kesh 10 barobar katta): H(C) ~ 19.11 + 0.58 = 19.69 -> 85% Xulosa: s = 1 da keshni 10 barobar oshirish atigi 75% -> 85% beradi. Dum juda uzun.
Natija: s = 1 bo'lsa, 6 mlrd havoladan eng faol 20 mln tasi trafikning ~75% ini oladi. 95% uchun mashhurlikning o'zi yetmaydi — vaqt omili kerak (8.3)

2-daraja amaliyotidagi simulyatsiya (60 000 havola, skaner, yangi va o‘chirilgan havolalar bilan) ham shuni ko‘rsatadi. Jadvalda — so‘rovlarning qancha qismi bazaga yetib borgani:

Kesh hajmi (havolalarning)s = 1.0s = 1.1s = 1.2
5%27.5%17.9%10.9%
10%22.0%13.9%8.3%
20%16.1%9.9%6.0%

Ikkita saboq. Birinchisi: egrilik (s) kesh hajmidan kuchliroq. s ning 1.0 dan 1.2 ga o‘zgarishi bazaga yukni keshni to‘rt barobar oshirishdan ko‘proq kamaytiradi. Ikkinchisi: keshni ikki barobar oshirish bazaga yukni ikki barobar emas, atigi ~20–30% kamaytiradi.

8.3 Vaqt: havolaning yarim yemirilishi

Mashhurlik vaqt o‘tishi bilan so‘nadi. bit.ly 2011-yilda 1000 ta havolani tahlil qildi. Ular “yarim yemirilish”ni shunday aniqladi: havola eng ko‘p bosilgan paytdan boshlab, umrbod bosishlarining yarmini qancha vaqtda yig‘ishi. Natija: Twitter’da 2.8 soat, Facebook’da 3.2 soat, email va messenjerlarda 3.4 soat, YouTube’da 7.4 soat.

Bu — keshning “sirli” samaradorligining asosiy sababi. Har lahzada haqiqatan bosilayotgan havolalar — asosan so‘nggi bir-ikki kunda yaratilgan yoki ulashilganlar. Ular esa jami havolalarning juda kichik qismi.

Hisob · Ishchi to'plam: hozir kimlar bosilyapti
Oyiga 100 mln yangi havola -> kuniga ~3.3 mln Yarim yemirilish 3 soat bo'lsa, havola o'z bosishlarining: 24 soatda: 1 - 2^(-8) = 99.6% ini oladi 48 soatda: 1 - 2^(-16) = 99.998% ini "Issiq" havolalar = so'nggi ~2 kunda yaratilganlar: 2 x 3.3 mln = ~6.7 mln Kesh hajmi 20 mln yozuv: 20 / 3.3 = ~6 kunlik yangi havola sig'adi + bir necha million "doim yashil" havola (bosh sahifalar, mashhur hujjatlar, QR kodlar) Natija: urish darajasi ~95% va undan yuqori — mashhurlik notekisligi + vaqt bo'yicha so'nish birgalikda
Natija: Bir kunda ~3.3 mln yangi havola, va ular bosishlarining 99.6% ini 24 soatda oladi. 20 mln yozuvli kesh ~6 kunlik yangi havolani sig'diradi — 95% ana shundan keladi

LRU aynan shu vaqt omiliga mos keladi: u yaqinda so‘ralganlarni ushlaydi va eskirganlarni o‘zi chiqarib tashlaydi. Shuning uchun real trafikda LRU sodda Zipf modelidan ancha yaxshi natija beradi. Lekin bitta xavfi bor: skaner ham “yaqinda so‘ralgan” bo‘lib ko‘rinadi (2-qadam Deep). Shu sabab salbiy yozuvlar alohida saqlanadi.

8.4 TTL: yangilik va yuk orasidagi tanlov

Hisob · TTL qancha yuk va qancha eskirish beradi
Keshdagi faol yozuvlar: 20 000 000 Har yozuv TTL tugaganda bir marta bazadan qayta o'qiladi (single-flight + SWR bilan aynan bir marta, 10.1) TTL = 24 soat: 20e6 / 86 400 = ~231 o'qish / s TTL = 1 soat: 20e6 / 3 600 = ~5 560 o'qish / s TTL = 1 daqiqa: 20e6 / 60 = ~333 000 / s -> trafikdan ham ko'p; amalda faqat so'ralayotgan kalitlar yangilanadi, lekin baza baribir bo'g'iladi Eskirish oynasi = TTL (manzil o'zgartirildi yoki havola o'chirildi, invalidatsiya yo'q)
Natija: TTL 24 soat: kesh yangilash bazaga ~230/s yuk beradi, lekin o'zgartirilgan havola sutka davomida eski bo'lishi mumkin. Shuning uchun TTL uzun, o'zgarishlar esa majburiy invalidatsiya bilan

Amaliy yechim ikki qismdan iborat: uzun TTL (soatlar yoki sutka) va o‘zgarish bo‘lganda majburiy invalidatsiya (10-qadam). TTL bu holda “xavfsizlik to‘ri” vazifasini bajaradi: invalidatsiya signali yo‘qolib qolsa, eskirish baribir TTL bilan cheklanadi.

Nazorat savoli · javobni ko‘rishKesh ikki barobar oshirildi va urish darajasi 86% dan 90% ga chiqdi. Bazaga yuk necha foiz kamaydi? Bu investitsiyaga arziydimi?

Urish darajasini emas, topilmaslik darajasini hisoblang. U 14% dan 10% ga tushdi. Bazaga yuk 10 / 14 = 0.71 ga ko‘paydi, ya’ni ~29% kamaydi. “Atigi 4 foiz punkt” bo‘lib ko‘rinadigan o‘zgarish aslida bazaga yukning qariyb uchdan birini olib tashlaydi.

Arziydimi — narxga bog‘liq. Kesh xotirasi (RAM) qimmat, baza o‘qishi esa nisbatan arzon. Agar baza 86% bilan bemalol ishlayotgan bo‘lsa, ikki barobar RAM — ortiqcha xarajat. Agar baza to‘yinish chegarasida bo‘lsa (10.4 dagi Little qonuni), 29% zaxira — kerakli sug‘urta. Yana bir variant — keshni emas, TTL va skanerdan himoyani yaxshilash: ular ko‘pincha arzonroq yutuq beradi.

9. Bugungi arxitektura

To'liq tizim
Mijoz
BrauzerMobil ilovaQR skaner
Chekka (anycast, 100+ nuqta)
TLS terminatsiyaChekka KV: kalit -> URL302 javob

Redirect'larning 90% i shu yerda tugaydi va origin'ga umuman bormaydi.

Origin — o'qish yo'li
L1 kesh (jarayon)L2 kesh (Redis)Bloom filtri

Chekkada topilmagan va yangi kalitlar shu yerga tushadi.

Origin — yozish yo'li
API: yaratish, tahrirlashKGS (kalit diapazonlari)URL skanerlash

Yuk kichik (200/s), lekin izchillik talabi yuqori.

Saqlash
Shardlangan SQL (manba haqiqat)O'qish replikalari

3.7 TB, 10-16 shard, har birida replika.

Analitika
Hodisalar navbatiOqim agregatsiyasiOLAP + xom arxiv

Redirect yo'lidan butunlay ajratilgan.

O‘qish yo‘li — so‘rov yuqoridan pastga tushadigan “elak”: har qatlam so‘rovlarning katta qismini o‘zi hal qiladi va pastga faqat qolganini yuboradi. Bazaga 19 300 so‘rovdan bir necha o‘ntasi yetib boradi.

Chekka KV: ~90% shu yerda tugaydi
Bloom filtri: 'aniq yo'q' -> 404
L1 jarayon keshi (TTL ~5 s, hot key)
L2 Redis: qolganining ~95%
Shard replikasi
Asosiy shard (faqat yangi va o'zgargan)
Har qatlam pastdagisini himoya qiladi. Qatlam tushsa, yuk bir pog'ona pastga ko'chadi — 10.2 dagi nosozliklar jadvali shu haqda
Hisob · Elak: har qatlamdan keyin qancha qoladi
Cho'qqi: 19 300 so'rov / s Chekka KV (90%): 19 300 x 0.10 = 1 930 origin'ga shundan skaner ~10%: Bloom rad etadi -> ~1 740 L1 (hot key'lar, ~40%): 1 740 x 0.60 = 1 044 L2 Redis (95%): 1 044 x 0.05 = 52 Replikalar va shard: ~50 / s Chekka tushsa: 19 300 -> L1/L2 -> ~500 / s bazaga Chekka + L2 tushsa: ~10 000 / s bazaga -> yiqilish -> degradatsiya tartibi (10.3) aynan shu uchun kerak
Natija: 19 300 so'rovdan bazaga ~0.1% — sekundiga ~20 ta. Chekka tushsa, bu son 10 barobar oshadi; L2 ham tushsa — yana 20 barobar

9.1 Ikki yo‘lning qiyosi

O'qish yo'li (19 300/s)
  • Chekkada tugaydi, origin'ga kamdan-kam boradi
  • Eventual consistency maqbul
  • Kesh urishi 95%+ bo'lishi shart
  • Mavjudlik 99.99% — eng muhim talab
Yozish yo'li (200/s)
  • Bitta mintaqada, oddiy va tranzaksion
  • Kuchli izchillik: kalit takrorlanmasligi kerak
  • Kechikish 100-300 ms maqbul (skanerlash bilan)
  • Mavjudlik 99.9% yetarli

Bu ajratish — darsning asosiy g‘oyasi. Ikki yo‘lning talablari butunlay boshqacha, shuning uchun ular boshqacha loyihalanadi. Ularni bitta “xizmat” deb qarash — birinchi arxitektura xatosi.

9.2 Mahsulot qatlami: havola faqat redirect emas

Ishlab chiqarishdagi qisqartiruvchi bir nechta qo‘shimcha talabni ko‘taradi va ularning har biri arxitekturaga tegadi:

UTM va marketing parametrlari. Havola yaratilganda maqsad URL ga utm_source, utm_campaign kabi parametrlar qo‘shiladi. Muhim tafsilot: bu parametrlarni saqlash paytida qo‘shish kerak, redirect paytida emas — aks holda har bir bosishda satr manipulyatsiyasi bajariladi va kesh kaliti murakkablashadi.

Mobil ilova havolalari. Foydalanuvchi telefonda havolani ochsa, brauzer emas, ilova ochilishi kerak. Bu Universal Links (iOS) va App Links (Android) orqali ishlaydi va domendan maxsus fayl talab qiladi (/.well-known/apple-app-site-association). Ya’ni sizning domeningiz endi faqat redirect emas, statik fayl ham xizmat qiladi — va u kalit qidiruvidan oldin tekshirilishi kerak.

QR kodlar. Qisqa havolaning QR kodi kichikroq va ishonchliroq skanerlanadi:

Hisob · Havola uzunligi QR kodga qanday ta'sir qiladi
Kichik harf bor -> QR "bayt" rejimi. O'rtacha (M) xato tuzatish darajasida sig'im: Versiya 1 (21x21 modul) 14 bayt Versiya 2 (25x25) 26 bayt Versiya 3 (29x29) 42 bayt Versiya 4 (33x33) 62 bayt "dars.uz/K7xQm2" 14 -> V1 "https://dars.uz/K7xQm2" 22 -> V2 "https://my-shortener.io/K7xQm2?utm_source=x" 43 -> V4 Bir xil jismoniy o'lchamda (masalan 2 sm): V1: modul = 2 / 21 = 0.95 mm V4: modul = 2 / 33 = 0.61 mm 0.95 / 0.61 = ~1.6 -> V1 shuncha uzoqdan va xira kamerada ham o'qiladi
Natija: Har qo'shimcha belgi QR kodni zichlashtiradi. Bir xil bosma o'lchamda 21x21 kod 33x33 koddan taxminan 1.6 barobar uzoqdan o'qiladi

Qiziq tafsilot: QR’ning yana bir, ixchamroq “alfanumerik” rejimi bor, lekin u faqat katta harflar, raqamlar va bir nechta belgini qabul qiladi. Shuning uchun ba’zi xizmatlar QR uchun alohida, faqat katta harfli kalitlar beradi: DARS.UZ/K7XQM2 ixchamroq kodga sig‘adi.

Havola guruhlari va boshqaruv paneli. Kampaniya bo‘yicha guruhlash, birgalikda statistika, ommaviy import (CSV orqali 100 000 havola) — bularning har biri yozish yo‘liga yuk qo‘shadi. Ommaviy import alohida navbat orqali, tezligi cheklangan holda bajarilishi kerak; aks holda bitta mijoz KGS diapazonlarini tugatib, boshqalarning yaratishini to‘xtatib qo‘yadi.

10. Ishonchlilik: nima buziladi

10.1 Cache stampede (thundering herd)

Hot kalitning TTL i tugadi. Shu lahzada 50 000 ta so‘rov keshda topmaydi va bir vaqtda bazaga yuguradi.

Hisob · Bitta TTL tugashining narxi
Hot kalit: 50 000 so'rov / soniya Bazadan o'qish vaqti: 5 ms TTL tugagan lahzada: 5 ms ichida keladigan so'rovlar: 50 000 x 0.005 = 250 ta ...lekin ular ham javob kutadi, shuning uchun navbat o'sib boradi va baza ulanishlari tugaydi Himoyasiz tizimda: baza ulanish hovuzi (100-500) bir soniyada tugaydi
Natija: Bitta kalitning muddati tugashi bazaga 50 000 bir vaqtli so'rov yuboradi — bu deyarli har doim yiqilish demak

Uchta himoya, birgalikda ishlatiladi:

  1. Single-flight — bitta kalit uchun faqat bitta so‘rov bazaga boradi, qolganlari uning natijasini kutadi
  2. Ehtimolli erta yangilash — TTL tugashiga yaqin har bir so‘rov kichik ehtimollik bilan keshni yangilaydi. Natijada yangilash bitta lahzada emas, vaqt bo‘ylab tarqaladi
  3. Stale-while-revalidate — eskirgan qiymat qaytariladi, yangilash fonda ketadi. Redirect uchun bu mukammal: bir necha soniya eski manzil hech kimga zarar qilmaydi
def resolve_with_swr(key):
    entry = cache.get(key)
    if entry and not entry.expired:
        return entry.url
    if entry and entry.stale_ok:
        refresh_in_background(key)     # foydalanuvchi kutmaydi
        return entry.url
    with single_flight(key):           # faqat bitta so'rov bazaga boradi
        return load_from_db(key)

10.2 Nosozliklar taksonomiyasi

NosozlikBelgisiSababChora
Kesh tuguni tushdiBazaga yuk 20× oshdiApparat, OOMKesh replikasi, bazaga rate limit, degradation
Cache stampedeBaza ulanishlari tugadiTTL bir vaqtda tugadiSingle-flight, SWR, TTL ga tasodifiy qo‘shimcha
Hot keyBitta Redis tuguni 100%Viral havolaL1 kesh, chekka kesh
Baza shardi tushdiKalitlarning 1/N qismi ishlamaydiApparat, failoverReplikaga o‘tish, kesh eski qiymatni beradi
Chekka eskirdiO‘chirilgan havola ishlayaptiPurge yetib bormadiMajburiy invalidatsiya, qisqa TTL kritik havolalarga
Domen qora ro‘yxatdaBarcha havolalarda ogohlantirishFishing suiiste’moliSkanerlash, tez o‘chirish, obro‘ni tiklash jarayoni
Analitika navbati to‘ldiStatistika kechikyaptiCho‘qqi yoki iste’molchi sekinHodisalarni tashlash (redirect ishlashda davom etadi)
Kalit maydoni tugadiYozish xatolari o‘syaptiUzunlik oshirilmaganUzunlikni oshirish (14-qadam)

10.3 Degradatsiya tartibi

1-bosqich
Analitikani tashlash
Hodisalar buferi to'lsa, ular yo'qoladi. Redirect ishlayveradi — bu to'g'ri ustuvorlik.
2-bosqich
Eskirgan keshdan xizmat qilish
Baza javob bermasa, TTL o'tgan qiymat baribir to'g'ri bo'lish ehtimoli 99.9%.
3-bosqich
Yaratishni to'xtatish
Yozish yo'li o'chadi, o'qish ishlaydi. Havolalar — asosiy funksiya.
4-bosqich
Faqat chekka keshdan ishlash
Origin butunlay tushsa ham, chekkadagi havolalar ishlab turadi.

Bu tartibning mantig‘i bitta: chop etilgan havola ishlashi kerak. U bannerda, vizitkada, kitobda bo‘lishi mumkin. Yangi havola yaratilmasligi — noqulaylik; eski havola ishlamasligi — halokat.

10.4 Ulanish hovuzi: Little qonuni amalda

“Baza sekin” degan shikoyatning yarmi aslida noto‘g‘ri sozlangan ulanish hovuzi. Kerakli hajm intuitsiya bilan emas, formula bilan topiladi:

Ulanishlar soni = throughput x kechikish
Hisob · Ulanish hovuzining to'g'ri hajmi
Kesh urishidan keyin bazaga: 965 so'rov/s Bitta so'rov: 5 ms = 0.005 s Kerakli ulanishlar = 965 x 0.005 = 4.8 -> 5 ta Zaxira bilan (cho'qqi va sekin so'rovlar uchun): 10-20 ta Agar 500 ta ulanish qo'ysak: Har biri bazada xotira va kontekst almashinuvi talab qiladi Baza yadrolari soni: 16 500 ta parallel so'rov 16 yadroda navbatga tizilib, har birining kechikishi 5 ms dan 150 ms ga chiqadi
Natija: Bazaga 965 rps yuborish uchun atigi ~5 ta ulanish yetarli. 500 ta ulanish qo'yish tizimni tezlashtirmaydi — u yiqiladigan holatni yashiradi va portlashini kuchaytiradi
▸Chuqurroq: Nega katta hovuz tizimni sekinlashtiradi

Ulanishlar soni bazadagi yadrolar sonidan ancha katta bo‘lsa, so‘rovlar parallel bajarilmaydi — ular navbatga tizilib, kontekst almashinuvi, qulf raqobati va xotira bosimini oshiradi. Natijada throughput o‘smaydi, kechikish esa o‘sadi.

Bundan ham muhimi: katta hovuz orqa bosimni yo‘q qiladi. Kichik hovuzda ilova darhol “ulanish yo‘q” xatosini oladi va uni to‘g‘ri boshqarishi mumkin (429 qaytarish, keshdan eski qiymat berish). Katta hovuzda esa u 30 soniya kutadi, mijoz timeout bo‘lib qayta yuboradi — va qayta urinishlar bo‘roni (retry storm) boshlanadi: har timeout bazaga yangi so‘rov olib keladi.

Amaliy qoida: hovuz hajmi baza yadrolari sonining 2–4 barobaridan oshmasin, va ulanishni kutish uchun qisqa timeout (100–500 ms) qo‘yilsin. Tez xato — yaxshi xato.

Nazorat savoli · javobni ko‘rishBaza sekinlashdi. Jamoadagi kimdir 'ulanish hovuzini 100 dan 500 ga oshiraylik' deyapti. Javobingiz?

Deyarli har doim bu noto‘g‘ri qaror. Little qonuni bo‘yicha kerakli hovuz hajmi = throughput × kechikish. Agar hovuz allaqachon to‘lib turgan bo‘lsa, demak yo throughput kutilganidan yuqori (sabab: kesh urishi tushgan), yo kechikish oshgan (sabab: sekin so‘rovlar, qulf, disk).

Hovuzni kattalashtirish sababni yashiradi va oqibatni yomonlashtiradi: bazadagi yadrolardan ancha ko‘p parallel so‘rov navbatga tizilib, har birining kechikishi oshadi, va orqa bosim yo‘qolgani uchun mijozlar timeout bo‘lib retry storm boshlaydi.

To‘g‘ri tartib: (1) kesh urish darajasini tekshirish, (2) sekin so‘rovlarni topish, (3) statement timeout qo‘yish, (4) kerak bo‘lsa o‘qish replikasi qo‘shish. Hovuz hajmi — oxirgi va eng kam ta’sirli tutqich.

10.5 Bu tizimni qanday sinash kerak

Testlar odatdagi CRUD ilovasidan farq qiladi, chunki eng qimmat xatolar poyga holatlari va yuk ostidagi xatti-harakatda.

Test turiNimani tekshiradiQanday
BirlikKalit generatsiyasining taqsimoti1M kalit yaratib, belgilar taqsimotini va takrorlanishini tekshirish
BirlikTo‘qnashuvda qayta urinishBazani majburan UNIQUE xatosi qaytarishga majburlash
IntegratsiyaMaxsus kalit poygasiIkki parallel so‘rov, bittasi muvaffaqiyatli bo‘lishi shart
IntegratsiyaKesh invalidatsiyasiO‘chirilgan havola keshdan ham yo‘qolganini tekshirish
YukCho‘qqidagi p99Kesh issiq va sovuq holatda alohida
YukCache stampedeBitta hot kalitga TTL tugash lahzasida ommaviy so‘rov
XaosKesh tuguni tushishiBazaga yuk oshadi, tizim yiqilmasligi kerak
XaosShard failoverKalitlarning 1/N qismi keshdan xizmat olishda davom etadimi
SintetikDoimiy nazoratBir necha mintaqadan har 30 soniyada test havolasini ochish

11. Xavfsizlik

11.1 Ochiq redirect (open redirect)

Sizning domeningiz istalgan manzilga yo‘naltiradi. Bu mahsulotning maqsadi, lekin ayni paytda klassik zaiflik:

Fishing xati:
  "Bankingizdan xabar: hisobingizni tasdiqlang -> dars.uz/K7xQm2"

Foydalanuvchi ishonchli domenni ko'radi, lekin soxta saytga tushadi.

Bundan tashqari, ba’zi saytlar ishonch qarorlarini domen bo‘yicha qabul qiladi (masalan Referer tekshiruvi yoki OAuth redirect_uri oq ro‘yxati). Sizning domeningiz ularning himoyasini chetlab o‘tish vositasiga aylanishi mumkin.

Choralar: yaratishda skanerlash, shubhali havolalarga oraliq ogohlantirish sahifasi, shikoyat mexanizmi va tez o‘chirish, hamda rel="noopener noreferrer" va Referrer-Policy sarlavhalari.

11.2 Kalitlarni sanab chiqish (enumeration)

Ketma-ket yoki qisqa kalitlar bo‘lsa, hujumchi /aaa, /aab, /aac deb sanab chiqib, odamlarning shaxsiy havolalarini (hujjatlar, hisob-kitoblar, buyurtma sahifalari) to‘playdi. Bu nazariy emas — real hodisalarda milliondan ortiq shaxsiy hujjat shu yo‘l bilan topilgan.

Choralar: yetarli uzun va tasodifiy kalitlar (3.4-bo‘lim), IP bo‘yicha tezlik cheklovi, 404 javoblarga sun’iy kechikish, va eng muhimi — foydalanuvchilarga “qisqa havola maxfiy emas” ekanini aniq aytish.

11.3 Maxfiylik

XavfTafsilotChora
URL da maxfiy ma’lumotToken, sessiya, ism URL da bo‘lishi mumkinURL ni loglarda maskalash, saqlash muddati
Referrer sizishiMaqsad sayt qaysi qisqa havoladan kelganini ko‘radiReferrer-Policy: no-referrer
IP va qurilma yozuvlariAnalitika shaxsiy ma’lumot to‘playdiAnonimlashtirish, saqlash muddati, huquqiy asos
Havola ommaviyligiQisqa havola — amalda ochiqFoydalanuvchini ogohlantirish; parol bilan himoya opsiyasi

11.4 SSRF va metama’lumot

13-qadamdagi ogohlantirish shu yerga ham tegishli: foydalanuvchi bergan URL ni server o‘qiganda ichki tarmoqqa kirish yo‘li ochiladi. Tekshiruv DNS yechimidan keyin, IP darajasida bo‘lishi kerak — domen nomi bo‘yicha tekshirish yetarli emas, chunki hujumchi o‘z domenini ichki IP ga yo‘naltirishi mumkin (DNS rebinding).

11.5 Havolaning o‘limi: goo.gl saboqi

Oddiy tilda: siz kitobingizda “batafsil: kutubxona katalogining K7xQm2 raqami” deb yozdingiz. Kitob o‘n yil sotiladi. Besh yildan keyin kutubxona yopilsa, kitobdagi har bir havola bir kunda o‘ladi — va siz uni hech qanday yo‘l bilan tuzata olmaysiz, chunki kitob allaqachon bosilgan.

Bu nazariy xavf emas. Google 2018-yil martida goo.gl ni yopishni e’lon qildi, 2019-yil 30-martdan yangi havola yaratish to‘xtadi. Eski havolalar yana besh yil ishladi. 2024-yil iyulda Google ularni ham o‘chirishini aytdi: havolalarning 99% dan ortig‘i o‘tgan oyda birorta ham bosish olmagan. 2024-yil avgustidan havolalarda ogohlantirish chiqa boshladi. 2025-yil 25-avgustdan esa nofaol havolalar 404 qaytara boshladi. Keyinroq Google ogohlantirish ko‘rsatilmagan, ya’ni 2024-yil oxirida faol bo‘lgan havolalar ishlashda davom etishini aniqlashtirdi.

Hisob · 99% nofaol — lekin 1% qancha
Faraz (illyustratsiya): xizmatda 10 mlrd havola qolgan Faol (oyiga kamida 1 bosish), 1%: 100 000 000 havola Nofaol, 99%: 9 900 000 000 havola Nofaol havolani saqlash narxi (4.2 dagi hisob bilan): ~600 bayt x 9.9e9 = ~6 TB -> 3 nusxa, ~$0.10/GB/oy = ~$1 800 / oy Redirect narxi: nofaol havola deyarli so'ralmaydi -> chekka va origin xarajati deyarli nol Xulosa: havolani "abadiy" saqlash texnik jihatdan arzon. Yopish sababi — narx emas, xizmatni YURITISH: xavfsizlik, suiiste'mol nazorati, jamoa e'tibori
Natija: Hatto 1% faol havola ham o'n millionlab bosish degani. 'Nofaol' havola esa ilmiy maqola, kitob va arxivlarda yashaydi — u bir oy bosilmagani o'lik ekanini anglatmaydi

Muhandis uchun uchta saboq:

  1. Havola — va’da. Qisqa havola chop etilgan materialda xizmatdan uzoq yashaydi. Shuning uchun “o‘chirish siyosati” birinchi kundan yozilishi kerak: qachon, qanday ogohlantirish bilan, qaysi havolalar saqlanadi.
  2. Chiqish yo‘li bo‘lsin. Foydalanuvchiga havolalar ro‘yxatini eksport qilish imkonini bering (17.5 dagi savol). Shunda xizmat yopilsa ham, ular o‘z domenida redirect’larni tiklay oladi.
  3. O‘z domeningiz — eng yaxshi sug‘urta. Maxsus domen (go.brand.uz, 13-qadam Deep) ishlatgan mijoz xizmatni almashtirganda havolalarini yo‘qotmaydi: DNS yozuvini yangi provayderga yo‘naltirish va ro‘yxatni ko‘chirish yetarli.
Nazorat savoli · javobni ko‘rishKompaniyangiz qisqartiruvchini yopmoqchi. 'Nofaol havolalarni o'chiraylik' degan taklifga qanday reja tuzasiz?

Bosqichma-bosqich, qaytarib bo‘lmaydigan qadamni oxiriga qoldirib:

  1. O‘lchash: “nofaol”ni aniqlang — 30 kun emas, kamida 6–12 oy, va botlarni hisobdan chiqarib (14.2). Bir martalik mavsumiy havolalar (yillik hisobot, ta’lim kursi) aks holda noto‘g‘ri “o‘lik” bo‘ladi.
  2. Yaratishni to‘xtatish: yangi havola yo‘q, eskilari ishlaydi.
  3. Ogohlantirish: redirect oldidan oraliq sahifa (“bu havola falon sanada ishlamay qoladi”) va egalariga xat — eksport havolasi bilan.
  4. Faollarni saqlash: ogohlantirish davrida bosilgan havolalar ro‘yxati saqlanadi va ular ishlashda davom etadi — goo.gl oxir-oqibat aynan shunga keldi.
  5. Arxivga topshirish: qolgan havolalar ro‘yxatini ochiq arxivga berish (masalan, veb-arxiv loyihalariga), shunda tadqiqotchilar manzillarni tiklay oladi.
  6. Faqat shundan keyin 404 yoki 410 Gone.

Asosiy fikr: o‘chirish arzon, lekin uning oqibati sizning tizimingizdan tashqarida — kitoblarda, maqolalarda, QR kodlarda. Reja ana shu tashqi xarajatni kamaytirishi kerak.

12. Iqtisod

Hisob · Oyiga 10 milliard redirect qancha turadi
Oylik hajm: 3860/s x 2.59e6 s = ~10 000 000 000 redirect Hisoblash (chekka + origin): Chekkada 90% (so'rov narxi ~$0.30 / 1M): 9e9 x 0.3/1e6 = $2700 Origin: 12 ta server x $150 = $1800 Saqlash: 3.7 TB x 3 replika x $0.10/GB = $1110 Kesh: 2 x 32 GB Redis = $400 Trafik (egress): 10e9 x ~1 KB = 10 TB x $0.08/GB = $800 Analitika: Qayta ishlash va saqlash (siqilgan) = ~$600 ===================================== Jami: ~$7400 / oy Bitta redirect: $0.00000074
Natija: Milliard redirect uchun ~$740. Bitta redirect ~0.00007 tsent — ChatGPT darsidagi bitta xabardan (0.21 tsent) taxminan 3000 barobar arzon

Ikkita xulosa:

  1. Eng katta xarajat — chekka so‘rovlari va trafik, saqlash emas. Ya’ni optimallashtirish javob hajmini kamaytirishdan (bo‘sh tana, minimal sarlavhalar) va brauzer keshidan (301 masalasi) boshlanadi
  2. Bitta havola juda arzon, lekin bepul emas. Bepul tarifda cheksiz havola berish — suiiste’molchilar uchun taklifnoma. Shuning uchun deyarli barcha qisqartiruvchilar yaratishni cheklaydi, o‘qishni esa cheklamaydi

12.1 Bitta havolaning umrbod narxi

Oddiy tilda: kutubxonaga kartochka qo‘shish deyarli bepul — qog‘oz arzon. Qimmat narsa boshqa joyda: har yangi kitobni “ichida zararli narsa yo‘qmi” deb tekshirish, va kim qachon o‘qiganini yozib borish.

Hisob · Bitta havola 10 yilda qancha turadi
(illyustratsiya, bulut narxlari tartibida) Saqlash: 600 bayt x 3 nusxa = 1.8 KB 1.8e-6 GB x $0.10 / GB / oy = $0.00000018 / oy 10 yil (120 oy): = $0.00002 Yaratishda URL skanerlash (tashqi xizmat yoki o'z modeli): ~$0.0001 - 0.001 / havola Analitika: havola o'rtacha 100 marta bosilsa 100 x 220 bayt = 22 KB xom, siqilgan ~5 KB 1 yil saqlash: 5e-6 GB x $0.10 x 12 = $0.000006 + oqim agregatsiyasi hisob-kitobi Jami: ~$0.0002 - 0.001 / havola shundan saqlash: 2-10%
Natija: Saqlash 10 yilda ~$0.00002 — deyarli nol. Asosiy xarajat — yaratishdagi tekshiruv va analitika. Shuning uchun bepul tarif yaratish sonini cheklaydi, mavjud havolani esa abadiy saqlash mumkin

Bu jadval 11.5 dagi saboqni raqam bilan tasdiqlaydi: havolani “abadiy” saqlash arzon. Qimmat narsa — suiiste’molga qarshi kurash va xizmatni yuritish. Biznes modeli ham shunga mos: bepul tarifda yaratish cheklangan, pullik tarifda esa mijoz analitika, maxsus domen va ko‘proq yaratish uchun to‘laydi.

13. Sig‘im rejalashtirish

Hisob · Necha server, necha shard
Redirect cho'qqisi: 19 300 / soniya Chekka 90% ni yutadi -> origin'ga 1930 / soniya Bitta origin serveri (kesh urishi bilan): ~10 000 redirect/s Kerak: 1930 / 10 000 = 0.2 server Lekin: - kesh sovuq bo'lgan holat uchun zaxira x3 - 3 mintaqa uchun x3 - yuklama 60% dan oshmasin /0.6 => ~12 server Shardlar: 3.7 TB / 300 GB (qulay shard hajmi) = 13 -> 16 shard (2 ning darajasi) Har birida 2 ta replika = 48 instansiya
Natija: Cho'qqida 4 ta origin serveri yetarli, lekin mintaqaviy zaxira va yuklamani 60% da ushlash uchun 12 ta olinadi
▸Chuqurroq: Nega shard soni 2 ning darajasi qilib olinadi

16, 32, 64 kabi sonlar tanlanadi, chunki shardni ikkiga bo‘lish eng oddiy o‘sish operatsiyasi: bitta shard ikkitaga bo‘linganda faqat o‘sha shardning ma’lumoti ko‘chadi va hash mod 2N formulasi eski taqsimotni buzmaydi (kalitlarning yarmi joyida qoladi).

Muqobil yondashuv — mantiqiy shardlar: boshidanoq 1024 ta mantiqiy shard yaratiladi va ular jismoniy tugunlarga xaritalanadi. O‘sish — xaritani o‘zgartirish, ma’lumot esa mantiqiy shard butunligicha ko‘chadi. Bu usul yiriklashuvda ancha qulay, chunki qayta shardlash formulani emas, jadvalni o‘zgartiradi.

13.1 Ko‘p ijarachilik: shovqinli qo‘shni muammosi

Bitta mijoz 100 000 havolani CSV orqali import qilyapti, ikkinchisining kampaniyasi viral bo‘ldi. Ikkalasi ham bir xil shardlarda, bir xil keshda, bir xil KGS diapazonlarida.

ResursShovqinli qo‘shni qanday zarar qiladiChora
KGS diapazonlariOmmaviy import kalitlarni tez yeydiMijoz bo‘yicha yaratish kvotasi
Kesh xotirasiBitta mijozning havolalari keshni to‘ldiradiMijoz bo‘yicha kesh ulushi yoki W-TinyLFU
Shard yukiViral havola bitta shardni bo‘g‘adiChekka kesh (yuk shardgacha yetmaydi)
Analitika navbatiBitta mijoz hodisalari navbatni to‘ldiradiMijoz bo‘yicha partition va kvota
Baza ulanishlariUzun so‘rov hovuzni band qiladiAlohida hovuz, statement timeout

Umumiy tamoyil: har bir umumiy resurs uchun kvota bo‘lishi kerak, va kvota buzilganda tizim butunlay to‘xtamasligi, faqat o‘sha mijozni sekinlashtirishi kerak. Bu — adolatli rejalashtirish (fair scheduling) masalasi va u ChatGPT darsidagi navbat prioritetlari bilan bir xil sinfdan.

14. Kuzatuv va sifat

Har bir redirect uchun yozilishi kerak:

kalit, javob_kodi (302 | 404 | 410 | 429)
manba (chekka | L1 | L2 | baza)
kechikish_ms, mintaqa, chekka_nuqtasi
bot_mi (User-Agent tahlili)

Panellarda:

MetrikaNega muhimOgohlantirish chegarasi
Redirect p50 / p95 / p99Asosiy foydalanuvchi tajribasip99 > 100 ms
Kesh urish darajasi (L1, L2, chekka)Bazaga yukni belgilaydi90% dan past
404 ulushiSkaner hujumi yoki buzuq havolalar5% dan yuqori
Yaratish kechikishiSkanerlash sekinlashganini ko‘rsatadip95 > 500 ms
Kalit maydoni bandligiUzunlikni oshirish vaqti15% dan yuqori
Analitika navbati kechikishiStatistika qanchalik eskirgan5 daqiqadan ko‘p
Tashlangan hodisalarDegradatsiya ishlayaptimiHar qanday o‘sish

14.1 SLO va xato byudjeti

“99.99% mavjudlik” degan gap byudjetga aylantirilmasa, ma’nosiz shior bo‘lib qoladi.

Hisob · Xato byudjeti
Oydagi daqiqalar: 30 x 24 x 60 = 43 200 99.9% -> 0.1% x 43 200 = 43.2 daqiqa / oy 99.95% -> 0.05% x 43 200 = 21.6 daqiqa 99.99% -> 0.01% x 43 200 = 4.32 daqiqa 99.999% -> 0.001% x 43 200 = 26 soniya Redirect uchun 99.99% tanlasak: Oyiga 4.32 daqiqa "byudjet" Bitta 5 daqiqalik uzilish - butun oylik byudjet tugadi
Natija: Oyiga 4.3 daqiqa — bu bitta deploy'ning noto'g'ri ketishiga ham yetmaydi. Shuning uchun 99.99% arxitektura talabi: bosqichma-bosqich deploy, avtomatik rollback, ko'p mintaqa

Xato byudjeti amaliy vosita: u sarflanadi. Byudjet qolgan bo‘lsa — yangi xususiyatlarni chiqarish mumkin; tugagan bo‘lsa — jamoa barqarorlikka o‘tadi. Bu muhandislik va mahsulot o‘rtasidagi bahsni raqamga aylantiradi.

Sarflash tezligi bo‘yicha ogohlantirish (burn rate) oddiy chegaradan yaxshiroq ishlaydi:

Agar oxirgi 1 soatda byudjetning 2% i sarflansa   -> tez ogohlantirish (sahifa)
Agar oxirgi 6 soatda byudjetning 5% i sarflansa   -> sekin ogohlantirish (tiket)

Birinchisi jiddiy uzilishni darhol ushlaydi, ikkinchisi sekin oqib turgan muammoni — va ikkalasi ham “xato darajasi 0.1% dan oshdi” degan shovqinli alertdan foydaliroq.

14.2 Bot trafigi: statistikaning eng katta yolg‘oni

Havola ijtimoiy tarmoqqa qo‘yilganda uni odamlardan oldin robotlar ochadi: xabar oldindan ko‘rish (unfurl) botlari, xavfsizlik skanerlari, arxivlovchilar, raqobatchilarning kuzatuv vositalari.

Hisob · Bot ulushi statistikani qanchalik buzadi
Havola messenjer va ijtimoiy tarmoqqa qo'yildi: Unfurl botlari (5 ta platforma x 2-3 marta) ~ 12 ta ochish Xavfsizlik skanerlari ~ 5 ta Arxiv va indekslash botlari ~ 3 ta --------------------------------------------------------- Odam bosmasidan oldin ~ 20 ta "bosish" Havola 20 ta odam tomonidan bosilsa: Xom hisoblagich: 40 Haqiqiy odam: 20 Xato: 100%
Natija: Filtrsiz hisoblagich haqiqiy odamlar sonidan ikki barobar katta ko'rsatishi mumkin — mijozga berilgan hisobot esa shu songa asoslanadi

Botlarni ajratishning uch usuli, ishonchliligi bo‘yicha:

  1. User-Agent ro‘yxati — oson, lekin eskiradi va soxtalashtirilishi mumkin
  2. Xulq-atvor — bot havolani qo‘yilgan lahzada, bir necha millisoniya ichida ochadi va keyin hech qachon qaytmaydi; odam esa tasodifiy vaqtda keladi
  3. IP obro‘si — ma’lum bulut provayderlari diapazonlari va bot tarmoqlari
Nazorat savoli · javobni ko‘rishSkaner sekundiga 5000 ta yangi kalit so'rayapti. Kesh urish darajasi nega tushadi va uch xil chorani qanday tartiblaysiz?

LRU keshda har bir yangi (foydasiz) kalit keshga kiradi va eng issiq havolalardan birini siqib chiqaradi. Bir soatda 18 million foydasiz yozuv 20 millionlik keshning katta qismini egallaydi — urish darajasi 95% dan 60% ga tushadi va bazaga yuk 4–8 barobar oshadi.

Choralar, samaradorligi bo‘yicha:

  1. Bloom filtri — yo‘q kalitlar keshgacha ham yetib bormaydi. Eng kuchli chora, lekin 7.2 GB xotira va davriy qayta qurish talab qiladi
  2. Salbiy keshni ajratish — 404 lar alohida, hajmi cheklangan keshda saqlanadi va asosiy keshni buzmaydi. Arzon va tez amalga oshiriladi
  3. W-TinyLFU — yangi element keshga kirish uchun chastota imtihonidan o‘tadi; bir martalik so‘rovlar keshni buza olmaydi
  4. Tezlik cheklovi — manbani sekinlashtiradi, lekin taqsimlangan skanerni to‘xtatmaydi

Amalda 2 + 4 darhol qilinadi, 1 va 3 esa keyingi bosqichda.

15. Antinaqshlar

QarorNima yutamizNimani yo'qotamiz
Analitikani redirect ichida sinxron yozishKod sodda, statistika aniqRedirect 20 barobar sekinlashadi; analitika tushsa havolalar ham ishlamaydi
Kalitni URL hash'idan olishDeduplikatsiya bepulIkki foydalanuvchi bitta havolani baham ko'radi; biri ikkinchisinikini o'chira oladi
Ketma-ket kalitlar (aralashtirilmagan)To'qnashuv yo'q, oddiyEnumeration: barcha shaxsiy havolalarni sanab chiqish mumkin
301 redirect (analitika kerak bo'lganda)Serverga yuk 5 barobar kamAnalitikaning 80% i yo'qoladi; manzilni hech qachon o'zgartirib bo'lmaydi
'Avval tekshir, keyin yoz' (maxsus kalitlar uchun)Ko'rinishidan mantiqiyPoyga holati: ikki foydalanuvchi bir kalitni oladi. UNIQUE cheklov shart
Yo'q kalitlarni keshlamaslikKesh 'toza' bo'ladiSkanerlar to'g'ri bazani uradi — cache penetration
O'chirilgan kalitni qayta ishlatishKalit maydoni tejaladiEski havola boshqa saytga olib boradi — chalkashlik va xavfsizlik muammosi
Bir xil TTL hamma kalitlargaSozlash osonOmmaviy TTL tugashi — stampede. Tasodifiy qo'shimcha (jitter) kerak
Foydalanuvchi URL'ini tekshirmasdan o'qish (unfurl)Chiroyli oldindan ko'rishSSRF: ichki tarmoq va bulut metama'lumotiga kirish

16. Trade-off‘lar

QarorNima yutamizNimani yo'qotamiz
7 belgili kalit100+ yilga yetadi, to'qnashuv arzon6 belgidan uzunroq — mahsulot jozibasi biroz kam
Tasodifiy kalitKoordinatsiyasiz, taxmin qilinmaydiYozishda qo'shimcha tekshiruv
KGS (oldindan generatsiya)Yozish yo'li eng tezYangi xizmat, restart'da kalitlar yo'qoladi
Chekka redirectKechikish 5 barobar kam, origin himoyalanganO'chirish va yangilash kechikadi
Salbiy keshlashSkanerlardan himoyaYangi havola bir muddat 404 berishi mumkin
Stale-while-revalidateStampede yo'q, kechikish barqarorBir necha soniya eskirgan manzil
HyperLogLog (noyob sanash)10 000 barobar kam xotira, birlashtiriladi~1% xato; aniq son kerak bo'lsa yaramaydi
Bloom filtriYo'q kalitlar bazaga bormaydiXotira; o'chirish yo'q; noto'g'ri ijobiy javoblar
Ko'p mintaqali yozishMintaqa tushsa ham yaratish ishlaydiKalit maydonini bo'lish kerak; operatsion murakkablik

Butun dars o‘nta gapda

  1. Qisqartiruvchi — juda katta va juda tez kalit-qiymat qidiruv: bitta GET va bitta PUT; qolgan hamma narsa ularni tez, arzon va ishonchli qilish uchun (2.5).
  2. O‘qish yozishdan 100–1000 barobar ko‘p: ikki yo‘l alohida loyihalanadi — o‘qish chekkada va keshda, yozish bitta mintaqada, tranzaksion (1.4, 9.1).
  3. 302, 301 emas: brauzer keshi analitikani va havolani o‘zgartirish imkonini o‘ldiradi (2.3).
  4. Kalit uzunligi raqamdan chiqadi: 6 milliard havola → 7 belgili base62; to‘qnashuvni yo‘q qilish emas, arzon qilish kerak (3-bo‘lim).
  5. Hisoblagich + Feistel + blok: takrorsiz, taxmin qilinmaydigan kalitlar markazga deyarli murojaatsiz (3.3, 5-qadam).
  6. Kechikishni tarmoq belgilaydi: server 5 ms, tarmoq 150 ms — chekka va anycast kesh optimallashtirishdan muhimroq (2.2, 7.2).
  7. Kesh vaqt bo‘yicha so‘nishga tayanadi: yarim yemirilish ~3 soat, shuning uchun 20 mln yozuv 6 mlrd havolaning ~95% trafigini oladi; urish darajasini emas, topilmaslikni hisoblang (8-bo‘lim).
  8. Keshning nosozliklari keshsizlikdan xavfliroq: stampede, hot key, skaner — single-flight, SWR, L1 va Bloom filtri bilan (6, 10-bo‘limlar).
  9. Analitika asinxron va yo‘qotishga ruxsat etilgan: statistika buzilsa ham havola ishlashi kerak (8-qadam, 10.3).
  10. Havola — va’da: u chop etiladi va xizmatdan uzoq yashaydi; kalitni qayta ishlatmang, eksport bering, yopishni bosqichma-bosqich rejalashtiring (10-qadam, 11.5).

17. Intervyu savollari

17.1 Asoslar

▸Kalit uzunligini qanday tanlaysiz? Hisobingizni ko'rsating.

Uch qadamdan iborat hisob:

  1. Umr davomidagi havolalar soni: oyiga 100M × 12 × 5 yil = 6 milliard
  2. Maydon hajmi: base62 da 62^n. 6 belgi = 5.68×10¹⁰, 7 belgi = 3.52×10¹²
  3. Bandlik foizi va to‘qnashuv: 7 belgida 6e9/3.52e12 = 0.17% band, ya’ni har 587 yozuvdan bittasi to‘qnashadi — qayta urinish arzon. 6 belgida 10.6% band, har 9.5 yozuvdan biri to‘qnashadi — bu allaqachon sezilarli

Javob: 7 belgi. Qo‘shimcha: uzunlik kodga qotirilmasin, konfiguratsiyadan o‘qilsin va maydon 15–20% to‘lganda oshirilsin.

▸301 va 302 orasidan qaysi birini tanlaysiz va nega?

Deyarli har doim 302 (yoki metod saqlansin desangiz 307).

301 ni brauzer oylab keshlaydi. Bu ikki narsani anglatadi: (a) takroriy bosishlar serverga umuman yetib kelmaydi — analitikaning ~80% i yo‘qoladi, (b) havola manzilini keyin hech qachon o‘zgartirib bo‘lmaydi, chunki foydalanuvchining brauzeri eski manzilga ketaveradi.

Tijorat qisqartiruvchilari uchun analitika va tahrirlash imkoni — mahsulotning o‘zi, shuning uchun 302 tanlanadi. 301 faqat manzil o‘zgarmasligi kafolatlangan va analitika kerak bo‘lmagan holatda (masalan domen migratsiyasi) mantiqiy.

▸Nega o'qish va yozish yo'llarini alohida loyihalash kerak?

Chunki ularning talablari qarama-qarshi. O‘qish: 19 300/s, eventual consistency maqbul, mavjudlik 99.99%, foydalanuvchiga yaqin bo‘lishi shart. Yozish: 200/s, kuchli izchillik shart (kalit takrorlanmasin), 100–300 ms kechikish maqbul, bitta mintaqada bo‘lishi mumkin.

Agar ularni bitta xizmat deb qarasak, o‘qish yo‘liga tranzaksiya va izchillik yuki tushadi (sekin va qimmat), yoki yozish yo‘li kesh mantiqini oladi (murakkab va xato manbai). Ajratganda har biri o‘z talablariga optimallashtiriladi va bir-birining nosozligidan himoyalanadi.

▸Ma'lumotlar bazasi sifatida nimani tanlaysiz?

Operatsiya — birlamchi kalit bo‘yicha aniq qidiruv, ya’ni deyarli har qanday saqlash mos keladi. Tanlov boshqa mezonlarga tayanadi:

PostgreSQL — boshlash uchun eng to‘g‘ri: tranzaksiya (maxsus kalitlar uchun UNIQUE cheklovi juda muhim), ikkilamchi indekslar (foydalanuvchining havolalari ro‘yxati), operatsion soddalik. 3.7 TB shardlanadi.

DynamoDB / Cassandra — chiziqli masshtablanish va boshqariluvchanlik kerak bo‘lsa. Lekin shartli yozish (kalit bandligini tekshirish) qimmatroq va murakkabroq.

Amaliy javob: manba haqiqat SQL da, o‘qish yo‘li esa kesh va chekka KV da. Ikkisi orasidagi izchillik eventual bo‘lishi mumkin.

17.2 Kesh va masshtab

▸Kesh hajmini qanday hisoblaysiz va qanday urish darajasini kutasiz?

Murojaat Zipf taqsimoti bo‘yicha: kichik qism havolalar trafikning katta qismini oladi. Eng faol ~20 million havola trafikning ~95% ini beradi.

Kesh yozuvi ~510 bayt (kalit + URL + qo‘shimcha), 20M × 510 = 10.2 GB — bitta 32 GB tugunga bemalol sig‘adi. Kutilayotgan urish darajasi ~95%, ya’ni bazaga qoladigan yuk 19 300 × 0.05 = 965/s.

Muhim tafsilot: bu hisobni o‘lchash bilan tekshirish kerak. Trafik naqshi kutilganidan tekisroq bo‘lsa (uzun dum), urish darajasi past bo‘ladi va kesh hajmini oshirish kerak.

▸Cache stampede nima va uni qanday oldini olasiz?

Hot kalitning TTL i tugagan lahzada barcha so‘rovlar bir vaqtda bazaga yuguradi. 50 000 rps li kalitda bu bazaning ulanish hovuzini bir soniyada tugatadi.

Uch himoya birga: (1) single-flight — bitta kalit uchun bitta so‘rov bazaga boradi, qolganlari natijani kutadi; (2) stale-while-revalidate — eskirgan qiymat qaytariladi, yangilash fonda; (3) TTL ga jitter — muddatlar bir lahzada tugamasin.

Redirect uchun SWR ayniqsa mos: bir necha soniya eskirgan manzil amalda hech qanday zarar qilmaydi, lekin kechikish barqaror qoladi.

▸Bitta havola viral bo'lib, sekundiga 500 000 marta bosilyapti. Nima qilasiz?

Sharding yordam bermaydi — bitta kalit bitta shardda (va bitta Redis tugunida). Kerak bo‘ladigan narsa — yuqoriroq qatlamlarda keshlash:

  1. Chekka kesh — so‘rov origin‘ga umuman yetib kelmaydi. Bu 99% holatni yopadi
  2. L1 kesh (ilova jarayonining xotirasida, TTL 5 soniya) — 50 ta server bo‘lsa, Redis‘ga yuk 500 000 dan 10 ga tushadi
  3. O‘qish replikalari — agar baza baribir kerak bo‘lsa

Narxi: havola o‘chirilsa, 5 soniyagacha ishlab turishi mumkin. Bu maqbul kelishuv; kritik holatlar uchun majburiy invalidatsiya signali qo‘shiladi.

▸Bloom filtri qanday muammoni yechadi? Uning cheklovlari nima?

Skanerlar mavjud bo‘lmagan kalitlarni so‘raydi. Ular keshda topilmaydi (har safar yangi kalit) va to‘g‘ri bazaga tushadi — cache penetration.

Bloom filtri “aniq yo‘q” yoki “bo‘lishi mumkin” javobini beradi. Birinchisi 100% ishonchli, demak yo‘q kalitlarni bazaga yubormasdan rad etish mumkin. 6 milliard kalit uchun 1% xato bilan 7.2 GB, 10% xato bilan 3.6 GB.

Cheklovlari: element o‘chirib bo‘lmaydi (davriy qayta qurish yoki Counting/Cuckoo filter kerak), noto‘g‘ri ijobiy javoblar bor (lekin ular xavfsiz — baza tekshiradi), va filtr shardlar bo‘yicha bo‘linishi kerak.

▸Sharding kalitini qanday tanlaysiz? Qayta shardlashni qanday qilasiz?

Shard kaliti — qisqa kalitning o‘zi (hash(kalit) mod N), chunki barcha o‘qishlar aynan shu bo‘yicha keladi. Foydalanuvchi ID si bo‘yicha shardlash xato bo‘lardi: redirect paytida biz kimning havolasi ekanini bilmaymiz.

Qayta shardlash uchun mod N yomon: N o‘zgarganda 91% ma’lumot ko‘chadi. Ikki yaxshi variant: izchil xeshlash (virtual tugunlar bilan, ko‘chish ~1/N) yoki mantiqiy shardlar (1024 ta bo‘lak jismoniy tugunlarga xaritalanadi, o‘sish — xaritani o‘zgartirish). Ikkinchisi bashoratliroq va yirik tizimlarda ko‘proq uchraydi.

▸Kesh urish darajasi 95% deyapsiz. Bu raqamni qanday asoslaysiz?

Ikki omil bilan, va ikkalasi kerak.

Notekislik (Zipf). s = 1 bo‘lsa, eng faol C havolaning ulushi taxminan ln C / ln N. 6 mlrd havoladan 20 mln tasi atigi ~75% beradi. Faqat mashhurlik bilan 95% chiqmaydi.

Vaqt bo‘yicha so‘nish. bit.ly o‘lchovlariga ko‘ra, havola bosishlarining yarmini ~3 soatda oladi, sutkada esa deyarli hammasini. Har lahzada bosilayotganlar asosan so‘nggi 1–2 kun havolalari: kuniga ~3.3 mln. 20 mln yozuvli LRU ~6 kunlik yangi havolani va “doim yashil”larni ushlaydi.

Intervyuda buni faraz deb ayting va o‘lchashni taklif qiling: kesh hajmi bo‘yicha urish egri chizig‘ini real trafik jurnalida simulyatsiya qilish (amaliyotdagi 4-qism aynan shunday).

▸Feistel shifri nima uchun kerak, oddiy tasodifiy son yetmaydimi?

Tasodifiy kalit takrorlanishi mumkin, shuning uchun har yozuvda bazani tekshirish va qayta urinish kerak. Hisoblagich esa takrorlanmaydi, lekin ketma-ket: aaa, aab, ... — begona havolalarni sanab chiqish oson.

Feistel ikkalasining yaxshi tomonini birlashtiradi. U [0, N) dagi sonlarni qayta tartiblaydigan bijeksiya: har kirishga bitta chiqish, takrorsiz. Kirish ketma-ket bo‘lsa ham, chiqish tasodifiyga o‘xshaydi. Sir kalitsiz keyingi kalitni taxmin qilib bo‘lmaydi.

Nozik joy — domen 2 ning darajasi emas (62^7). Shuning uchun “cycle walking” qilinadi: natija domendan katta bo‘lsa, yana shifrlanadi. % N bilan qisqartirish xato, chunki u takror kalit beradi.

▸Bitta foydalanuvchi bitta URL ni 10 marta qisqartirsa — 10 xil kalit berasizmi?

Ha, va bu ataylab. Har qisqartirish alohida havola: o‘z statistikasi, o‘z muddati, o‘z egasi. Marketolog bir sahifani turli kanallar uchun alohida qisqartirib, qaysi kanal ishlaganini ko‘radi.

Deduplikatsiya kerak bo‘lsa (masalan, anonim foydalanuvchilarning saqlash hajmini kamaytirish uchun), u egasi + URL bo‘yicha qilinadi: alohida indeks (owner_id, hash(url)) va “avval qidir, topilmasa yarat”. Butun xizmat bo‘yicha URL xeshidan kalit yasash (3.3) esa xato: begona foydalanuvchilar statistikani bo‘lishadi.

17.3 Ma’lumot va analitika

▸Sekundiga 19 000 bosishni qanday hisoblaysiz? Bazaga UPDATE yozib bo'lmaydi.

To‘g‘ri — bitta qatorga sekundiga o‘n minglab UPDATE qulf raqobatiga olib keladi va redirect kechikishini sekundlarga chiqaradi.

Yo‘l: redirect serveri hodisani mahalliy buferga qo‘yadi va darhol 302 qaytaradi. Bufer paketlab (1000 ta hodisa yoki 1 soniya) navbatga (Kafka) yuboriladi. Iste’molchi oqim agregatsiyasini qiladi (kalit bo‘yicha vaqt oynasida yig‘adi) va hisoblagichlarni paketlab yangilaydi. Xom hodisalar parallel ravishda arxivga yoziladi.

Muhim qaror: bufer to‘lsa, hodisalar tashlanadi. Statistikaning 0.1% i yo‘qolgani — redirect sekinlashuvidan ko‘ra yaxshiroq.

▸Noyob tashrif buyuruvchilarni qanday sanaysiz?

Aniq sanash uchun barcha identifikatorlarni saqlash kerak — 10M bosishli havola uchun 160 MB, va bu faqat bitta havola.

HyperLogLog 12 KB da milliardlab elementni ~1% xato bilan sanaydi. Qo‘shimcha yutuq: HLL strukturalarini birlashtirish mumkin, ya’ni kunlik ko‘rsatkichlardan haftalik va oylikni qayta sanamasdan olish mumkin (oddiy hisoblagichlar bilan bu ishlamaydi — kunlik summalar noyoblikni bermaydi).

1% atrofidagi xato marketing hisobotlari uchun maqbul. Agar aniq son shart bo‘lsa (masalan billing), alohida aniq hisob yuritiladi va u qimmatroq bo‘ladi.

▸Analitika bazasi tushdi. Redirect'lar ishlashi kerakmi?

Albatta ha, va bu arxitektura talabi sifatida yozilishi kerak. Analitika — ikkinchi darajali xususiyat; havolalarning ishlashi — asosiy funksiya.

Amalda bu shuni anglatadi: redirect yo‘li analitika navbatiga asinxron yozadi, navbat javob bermasa yoki bufer to‘lsa — hodisa tashlanadi, xato loglanadi, redirect esa odatdagidek davom etadi. Hech qanday await, hech qanday retry redirect yo‘lida bo‘lmasligi kerak.

17.4 Xavfsizlik

▸Ochiq redirect nima uchun muammo, agar bu mahsulotning maqsadi bo'lsa ham?

Chunki sizning domeningiz ishonch signali bo‘lib xizmat qiladi. Fishing xatida dars.uz/K7xQm2 ko‘rgan odam ishonchli domenni ko‘radi va soxta bank sahifasiga tushadi.

Bundan tashqari, ba’zi tizimlar ishonchni domen bo‘yicha beradi (OAuth redirect_uri oq ro‘yxati, Referer tekshiruvi) — sizning domeningiz ularning himoyasini chetlab o‘tish vositasiga aylanadi.

Oqibat sizga ham qaytadi: domen qora ro‘yxatga tushsa, barcha havolalaringiz brauzerda ogohlantirish bilan ochiladi. Shuning uchun skanerlash, shikoyat mexanizmi va tez o‘chirish — mahsulotning majburiy qismi.

▸Kalitlarni sanab chiqishdan qanday himoyalanasiz?

Birinchi navbatda kalitlar tasodifiy bo‘lishi kerak. Ketma-ket kalitlar (hisoblagichdan) ishlatilsa, ular bijektiv permutatsiya (masalan Feistel shifri) bilan aralashtiriladi — to‘qnashuvsizlik saqlanadi, lekin ketma-ketlik ko‘rinmaydi.

Qo‘shimcha qatlamlar: IP bo‘yicha tezlik cheklovi, 404 javoblarga sun’iy kechikish, anomaliya aniqlash (bitta manbadan ko‘p 404).

Va eng muhimi — kutilmani to‘g‘ri qo‘yish: qisqa havola maxfiylik vositasi emas. Maxfiy hujjatga havola qisqartirilsa, u himoyalangan deb hisoblanmasligi kerak. Bu foydalanuvchiga aniq aytilishi kerak.

▸Foydalanuvchi bergan URL ni oldindan ko'rish uchun o'qiyapsiz. Qanday xavf bor?

SSRF — foydalanuvchi ichki manzilni berishi mumkin: http://169.254.169.254/... (bulut metama’lumot xizmati, u yerdan vaqtinchalik hisob ma’lumotlari olinishi mumkin) yoki ichki tarmoqdagi xizmat.

Himoya: DNS yechimidan keyin IP ni tekshirish (xususiy va maxsus diapazonlarni rad etish) — domen nomi bo‘yicha tekshirish yetarli emas, chunki hujumchi o‘z domenini ichki IP ga yo‘naltirishi mumkin (DNS rebinding). Qo‘shimcha: redirect zanjirining har bir qadamini tekshirish, alohida tarmoq segmentidan so‘rov yuborish, javob hajmi va timeout cheklovi.

17.5 Amaliy stsenariylar

▸Redirect p99 500 ms ga chiqdi. Diagnostika tartibingiz?
  1. Qaysi qatlamdan kelyapti — chekka, L1, L2 yoki baza? Har bir manba uchun alohida kechikish metrikasi bo‘lishi kerak. Agar bazaga tushayotganlar ko‘paygan bo‘lsa — kesh muammosi
  2. Kesh urish darajasi — tushganmi? Sabablari: tugun qayta ishga tushgan, TTL o‘zgargan, eviction boshlangan, skaner hujumi
  3. Geografiya — muammo hamma mintaqadami yoki bittasidami? Bitta mintaqada bo‘lsa — chekka nuqtasi yoki tarmoq
  4. 404 ulushi — oshgan bo‘lsa, skanerlar bazani uryapti (Bloom filtri yoki salbiy keshlash ishlamayapti)
  5. Baza — shard failover, sekin so‘rovlar, ulanish hovuzi to‘lganmi

p50 ham yomonmi yoki faqat p99 mi — birinchisi tizimli muammo (sig‘im, konfiguratsiya), ikkinchisi dum (hot key, stampede, ayrim sekin so‘rovlar).

▸Mijoz 'havolalar ro'yxatini CSV ga eksport qilish' so'radi. 50 million havolasi bor.

To‘g‘ridan-to‘g‘ri SELECT bilan qilib bo‘lmaydi: so‘rov daqiqalar davom etadi, xotirani to‘ldiradi va bazaga ta’sir qiladi.

To‘g‘ri yechim: asinxron eksport vazifasi. Foydalanuvchi so‘raydi → vazifa navbatga tushadi → fon ishchisi ma’lumotni kursor bilan paketlab (masalan 10 000 tadan) o‘qiydi, obyekt xotiraga siqilgan holda yozadi → tayyor bo‘lgach foydalanuvchiga vaqtinchalik havola yuboriladi.

Muhim tafsilotlar: o‘qish replikadan (asosiy bazaga tegmaslik), progress ko‘rsatkichi, vazifaning takroriy ishga tushishiga qarshi idempotentlik, va fayl uchun amal qilish muddati.

▸Kalit maydonining 20% i band bo'ldi. Nima qilasiz?

Bu — uzunlikni oshirish signali (14-qadam). Rejalashtirilgan harakat:

  1. Konfiguratsiyada generatsiya uzunligini 7 dan 8 ga oshirish
  2. Eski kalitlar tegilmaydi — yechish uzunlikka qarab emas, aynan kalit bo‘yicha ishlaydi, shuning uchun 7 va 8 belgili kalitlar birga yashaydi
  3. Kesh va Bloom filtri o‘zgarishsiz ishlaydi
  4. Chekka konfiguratsiyasi yangilanadi (agar u uzunlikka tayangan bo‘lsa — bu allaqachon dizayn xatosi)

Agar tizim uzunlikni kodga qotirgan bo‘lsa (validatsiya len(key) == 7), bu migratsiya og‘riqli bo‘ladi — shuning uchun uzunlik boshidanoq konfiguratsiyadan o‘qilishi kerak.

▸Bitta shard yiqildi. Foydalanuvchi nima ko'radi?

Kalitlarning 1/N qismi (16 shardda ~6%) bazadan o‘qilmaydi. Lekin:

  • Keshda bo‘lgan havolalar ishlayveradi — bu trafikning ~95% i
  • Chekkadagi havolalar ham ishlayveradi — ko‘pchilik so‘rovlar origin‘ga bormaydi
  • Faqat keshda yo‘q va o‘sha shardga tegishli havolalar 500 xatosi beradi

Chora tartibi: replikaga avtomatik failover (soniyalar), kesh TTL ini vaqtincha uzaytirish (eskirgan qiymat yo‘qdan yaxshi), yaratishni shu shard uchun to‘xtatish.

Bu — kesh nafaqat tezlik, balki mavjudlik vositasi ekanining yaxshi misoli.

▸Havola endigina yaratildi, lekin boshqa mintaqadagi foydalanuvchi 404 olyapti. Qanday tekshirasiz?

Bu — “yangi havolaning birinchi daqiqasi” muammosi (7.3). Tekshirish tartibi:

  1. Qaysi qatlam 404 berdi? Javobdagi sarlavha yoki jurnal: chekka, origin keshi yoki baza
  2. Chekka 404 ni keshladimi? Agar ha — salbiy TTL qancha? Uzun bo‘lsa, havola o‘sha nuqtada shuncha vaqt “o‘lik” turadi
  3. Origin’da havola bormi? L2 va Bloom filtriga yaratish paytida sinxron yozilganmi, yoki fonda (keyinroq)?
  4. Replikatsiya kechikishi: o‘qish replikadan bo‘lsa, yozuv u yerga yetib kelganmi?

Tuzatish: chekkada salbiy javobni bir necha soniyagina keshlash, yaratishda L2 va Bloom’ga javobdan oldin yozish, va bir necha daqiqalik yangi kalitlarni asosiy bazadan o‘qish.

▸Xizmatingiz o'n yildan keyin yopilishi mumkin. Bugun dizaynda nimani o'zgartirasiz?

Uchta narsani — ularning hammasi bugun arzon, keyin esa imkonsiz.

  1. Maxsus domen — mijoz havolalari uning o‘z domenida bo‘lsin. Xizmat yopilsa, u DNS’ni boshqa joyga yo‘naltiradi
  2. Eksport — har mijoz istalgan payt barcha havolalarini kalit → URL ro‘yxati sifatida yuklab ola olsin
  3. Yopish siyosati — qachon, qanday ogohlantirish bilan, faol havolalar qanday saqlanishi oldindan yozilgan bo‘lsin

goo.gl misoli ko‘rsatdi: e’londan oxirgi redirect’gacha yetti yil o‘tdi va oxir-oqibat baribir faol havolalar saqlab qolindi (11.5). Havola chop etilgan materialda yashaydi, shuning uchun uning umri xizmat umridan uzun.

▸Bloom filtri xotiraga sig'maydi. Nima qilasiz?

Uch yo‘l bor, ularni birlashtirish ham mumkin:

  1. Shard bo‘yicha bo‘lish — har shard o‘z kalitlari uchun filtr saqlaydi: 7.2 GB / 16 = ~450 MB. So‘rov kalit bo‘yicha kerakli shardga boradi, filtr ham shu yerda tekshiriladi
  2. Xato ulushini oshirish — p = 10% da hajm ikki barobar kichik (3.6 GB). Skaner so‘rovlarining 90% i baribir to‘xtaydi
  3. Faqat chekkada emas, origin’da — chekkaga butun filtrni tarqatish o‘rniga, origin oldida bitta filtr. Chekka esa salbiy javobni qisqa keshlaydi

Qaysi biri — o‘lchovga qarab: skaner ulushi kichik bo‘lsa, filtrsiz, faqat alohida salbiy kesh ham yetarli bo‘lishi mumkin (amaliyotdagi skaner testi).

▸Nima uchun bu masala intervyularda shunchalik ko'p so'raladi?

Chunki u kichik ko‘rinadi, lekin ichida katta tizimning barcha naqshlari bor: kalit maydoni va ehtimollik hisobi, o‘qish/yozish yo‘llarining ajratilishi, ko‘p qatlamli keshlash va uning nosozliklari, sharding va qayta shardlash, hot key, asinxron quvurlar, CAP kelishuvlari, xavfsizlik (enumeration, ochiq redirect, SSRF) va aniq iqtisodiy hisob.

Yaxshi javob “hash qilamiz va bazaga yozamiz” emas. Yaxshi javob raqamdan boshlanadi: qancha havola, qancha o‘qish, qancha yozish — va har bir qaror shu raqamlardan kelib chiqadi.

18. Amaliyot

To‘rt daraja. Ikkinchi daraja uchun kod va avtomatik tekshiruvlar docs/amaliyot/url-shortener/ da: keys.py, bloom.py, cache.py — TODO; model.py — tayyor alifbo, barqaror xesh, markaziy hisoblagich, “baza” va Zipf trafigi; check.py — 17 ta tekshiruv.

Amaliyot

1-daraja: kalit maydoni kalkulyatori

Skript yozing, u quyidagilarni kirish sifatida oladi: alifbo hajmi, kalit uzunligi, oyiga yangi havolalar soni, xizmat umri (yil).

Chiqishda: maydon hajmi, umr oxiridagi bandlik foizi, bitta yozuv uchun to‘qnashuv ehtimoli, kutilayotgan qayta urinishlar soni, va maydonning 20% i qachon to‘lishi.

Tekshiruv mezoni: darsdagi raqamlarni takrorlang (7 belgi → 0.17% bandlik, 1/587 to‘qnashuv). Keyin grafik chizing: kalit uzunligi 5 dan 10 gacha bo‘lganda umr necha yil? Qaysi nuqtada uzunlikni oshirish foyda bermay qoladi?

Amaliyot

2-daraja: kalitlar, Bloom filtri va kesh (tayyor tekshiruvlar bilan)

Kod docs/amaliyot/url-shortener/ da. Uchta faylni to‘ldirasiz, check.py esa ularni 17 ta tekshiruvda sinaydi (~4 soniya, faqat Python standart kutubxonasi):

  1. keys.py — encode/decode (base62), Feistel (aralashtiruvchi bijeksiya, cycle walking bilan) va KeyAllocator (markazdan blok bilan son olib, kalit beradi)
  2. bloom.py — m va k formulasi, “ikki xesh” pozitsiyalari, add va in
  3. cache.py — LinkCache.get: LRU, TTL, alohida salbiy kesh, single-flight va stale-while-revalidate; invalidate

Tekshiruv mezoni: python check.py oxirida Jami: 17/17 OK. Keyin check.py dagi 4-qism parametrlarini o‘zgartiring (kesh hajmi, Zipf s) va 8.2 dagi jadvalni o‘zingiz takrorlang.

▸Chuqurroq: check.py qanday tekshiradi: sodda model va 'bir daqiqalik' trafik

Keshni tekshirishning qiyin joyi — vaqt. So‘rovlar bir-birini kutadi, yuklanishlar fonda tugaydi, TTL o‘tadi. check.py buni uch usulda tekshiradi.

Sodda model bilan solishtirish. NaiveCache xuddi shu qoidalarni ro‘yxatlar va chiziqli qidiruv bilan bajaradi — uni o‘qib tekshirish oson. 60 ta tasodifiy ketma-ketlikda (kichik sig‘im, tez-tez o‘chirish va qayta yaratish, bir xil vaqtdagi so‘rovlar) sizning keshingiz har so‘rovda aynan bir xil javob, bir xil kutish vaqti va bazaga bir xil sondagi o‘qishni berishi kerak.

Ataylab yaratilgan vaziyatlar. Bitta kalitga 5 soniya davomida sekundiga 5000 so‘rov, TTL esa 1 soniya. Single-flight bo‘lmasa, bazaga minglab so‘rov ketadi; to‘g‘ri yechimda — 5 ta. SWR bilan esa birinchi yuklanishdan keyin birorta ham so‘rov kutmaydi. Skaner testida 15 000 yo‘q kalit issiq havolalarni keshdan siqib chiqarmasligi tekshiriladi.

Tizim. Bir daqiqalik trafik: 60 000 havola, Zipf bosishlar, 15% skaner, viral havola, yangi havolalar va eng mashhur 200 havolaning o‘chirilishi. Har javob bazadagi haqiqat bilan solishtiriladi. Referens yechimda issiq holatda so‘rovlarning ~13.9% i bazaga yetadi, skanerning esa ~0.1% i.

Amaliyot

3-daraja: ishlaydigan xizmat va yuk testi

2-darajadagi modullaringiz asosida HTTP xizmat yozing:

  1. POST /api/v1/links — URL validatsiyasi, KeyAllocator dan kalit, Idempotency-Key, maxsus kalit (UNIQUE cheklovi va band so‘zlar ro‘yxati), muddat
  2. GET /:key — Bloom filtri, keyin LinkCache (yoki Redis), 302; topilmasa 404, o‘chirilgan bo‘lsa 410
  3. Bosishlarni asinxron sanash: bufer + fon vazifasi; bufer to‘lsa — hodisa tashlanadi
  4. DELETE — tombstone, invalidatsiya

Tekshiruv mezoni: yuk testi (k6, wrk yoki ab) bilan jadval tuzing: keshsiz, kesh bilan, kesh + Bloom bilan (20% skaner trafigi qo‘shib). Har qatorda: RPS, p50, p99, bazaga so‘rovlar soni. Ikki jarayondan bir vaqtda bir xil maxsus kalitni so‘rang — faqat bittasi muvaffaqiyatli bo‘lishini isbotlang.

Amaliyot

4-daraja: to'liq tizim modeli

Elektron jadval yoki skript yozing, u tizimning sig‘imi va xarajatini modellashtiradi. Kirish: yangi havolalar soni, o‘qish/yozish nisbati, cho‘qqi koeffitsienti, kesh urish darajasi, chekkada tugaydigan so‘rovlar ulushi, URL o‘rtacha uzunligi, saqlash va trafik narxlari.

Chiqish: kerakli server soni, shardlar soni, kesh hajmi, oylik xarajat va bitta redirect narxi.

Tekshiruv mezoni: darsdagi hisoblarni takrorlang (~$7400/oy, redirect $0.00000074). Keyin sezgirlik tahlili: kesh urish darajasi 95% dan 80% ga tushsa xarajat necha foizga oshadi? Chekkada tugaydigan ulush 90% dan 50% ga tushsa-chi? Qaysi parametr eng ko‘p ta’sir qiladi — va bu sizning optimallashtirish ustuvorligingizni qanday o‘zgartiradi?

19. Lug‘at

AtamaMa’nosi
Base62a-z, A-Z, 0-9 — URL uchun xavfsiz 62 belgili alifbo
Kalit maydoniMumkin bo‘lgan barcha kalitlar to‘plami: 62^n
Tug‘ilgan kun paradoksiTo‘qnashuv ehtimoli intuitsiyadan ancha tez o‘sishi
KGSKey Generation Service — kalitlarni oldindan yaratuvchi xizmat
Feistel shifriKetma-ket sonlarni to‘qnashuvsiz aralashtiruvchi bijektiv o‘girish
301 / 302 / 307 / 308Redirect kodlari; keshlanishi va metod saqlanishi bilan farq qiladi
Cache-asideIlova keshni o‘zi boshqaradigan naqsh
Salbiy keshlashTopilmagan kalitlarni ham keshlash (skanerlardan himoya)
Cache stampedeTTL tugagan lahzada barcha so‘rovlarning bazaga yugurishi
Single-flightBir xil kalit uchun faqat bitta bazaga so‘rov yuborish
Stale-while-revalidateEskirgan qiymatni qaytarib, yangilashni fonda qilish
Hot keyNomutanosib ko‘p so‘raladigan bitta kalit
Cache penetrationMavjud bo‘lmagan kalitlar orqali keshni chetlab o‘tish
Bloom filtri“Aniq yo‘q / bo‘lishi mumkin” javobini beruvchi ehtimollik strukturasi
HyperLogLogNoyob elementlarni kam xotirada taxminiy sanash
Izchil xeshlashShard qo‘shilganda ma’lumotning faqat 1/N qismi ko‘chishi
Mantiqiy shardJismoniy tugunlarga xaritalanadigan sobit sonli bo‘lak
TombstoneO‘chirilgan yozuvning kalitni band qilib turuvchi belgisi
AnycastBir xil IP ni ko‘p joyda e’lon qilib, eng yaqiniga yo‘naltirish
Chekka KVFoydalanuvchiga yaqin nuqtalardagi kalit-qiymat saqlash
EnumerationKalitlarni ketma-ket sanab, begona havolalarni topish hujumi
Ochiq redirectDomenning istalgan manzilga yo‘naltirishi va undan suiiste’mol
SSRFServerni ichki tarmoqqa so‘rov yuborishga majburlash zaifligi
DNS rebindingDomenni tekshiruvdan keyin ichki IP ga yo‘naltirish hiylasi
Degradatsiya tartibiSig‘im yetmaganda nimadan voz kechish ketma-ketligi
RedirectServer sahifa o‘rniga “boshqa manzilga bor” deb javob berishi
Cycle walkingNatija domendan tashqarida bo‘lsa, qayta shifrlash — bijeksiyani saqlaydi
Zipf taqsimotii-o‘rindagi element ulushi 1 / i^s ga proporsional notekis taqsimot
Yarim yemirilishHavola umrbod bosishlarining yarmini oladigan vaqt (~3 soat)
Ishchi to‘plamMa’lum vaqt oralig‘ida haqiqatan so‘ralayotgan kalitlar
Urish / topilmaslik darajasiKeshdan javob berilgan / bazaga ketgan so‘rovlar ulushi
Miss-to-originChekkada topilmagan so‘rovni origin’dan so‘rash siyosati
Link rotVaqt o‘tishi bilan havolalarning ishlamay qolishi
UTMMarketing kanalini belgilovchi URL parametrlari (utm_source va sh.k.)

20. Raqamlar manbasi

RaqamQiymatManba
TinyURL2002-yil yanvar, Kevin Gilbertson; Usenet forumlari uchunTinyURL va Kevin Gilbertson haqidagi ommaviy manbalar (Wikipedia)
bit.ly2008, Nyu-YorkBitly haqidagi ommaviy manbalar
bit.ly hajmiOyiga yuzlab million havola, ~10 mlrd bosishKompaniyaning o‘z da’volari; yillar bo‘yicha farq qiladi
t.co2011-yil iyun; 10-oktabrdan barcha havolalar o‘raladiTwitter dasturchilar blogi, 2011; texnik matbuot
goo.gl2009 ochilgan; 2018-yil 30-mart e’lon; 2019-yil 30-martdan yangi havola yo‘q; 2024-yil iyul — o‘chirish e’loni (99% dan ortig‘i bir oyda bosilmagan); 2025-yil 25-avgust — nofaol havolalar 404Google Developers blogi; Archive Team; texnik matbuot
Havola yarim yemirilishiTwitter 2.8, Facebook 3.2, to‘g‘ridan-to‘g‘ri 3.4, YouTube 7.4 soat; 1000 ta havolabit.ly tadqiqoti, 2011-yil sentabr
HTTP redirect semantikasi301/302/307/308RFC 9110
Bloom filtri formulasim = -n ln p / (ln 2)^2, k = (m/n) ln 2Bloom (1970); Kirsch va Mitzenmacher (2006)
HyperLogLog xatosi1.04 / sqrt(m); 16 384 registr (12 KB) — ~0.81%Flajolet va boshq. (2007)
QR sig‘imiBayt rejimi, M daraja: V1 — 14, V2 — 26, V3 — 42, V4 — 62 baytISO/IEC 18004
2-daraja natijalari17/17; 26 mutatsiya; issiq holatda bazaga ~13.9%docs/amaliyot/url-shortener/, referens implementatsiya

Oyiga 100 mln havola, o‘qish/yozish nisbati, cho‘qqi koeffitsienti, URL o‘rtacha uzunligi, kesh urish darajasi, chekkada topilish ulushi, server va saqlash narxlari, kechikishlar va 11.5, 12.1 dagi xarajatlar — illyustratsiya uchun taxminiy raqamlar. Ular bozor yetakchilarining ochiq raqamlari tartibida tanlangan. Asosiy xulosalar — o‘qish yo‘lini chekka va keshga berish, kalit uzunligini hisob bilan tanlash, 302 ni tanlash, analitikani asinxron qilish va havolani va’da sifatida ko‘rish — bu raqamlarning bir necha barobarlik xatosiga ham chidamli.

21. Manbalar

  • RFC 9110, “HTTP Semantics” (2022) — 301/302/307/308 va keshlanish
  • David Karger va boshq. (1997), “Consistent Hashing and Random Trees”, STOC
  • Burton H. Bloom (1970), “Space/Time Trade-offs in Hash Coding with Allowable Errors”, Communications of the ACM
  • Adam Kirsch, Michael Mitzenmacher (2006), “Less Hashing, Same Performance: Building a Better Bloom Filter”, ESA
  • Philippe Flajolet va boshq. (2007), “HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm”, AofA
  • Andrea Vattani va boshq. (2015), “Optimal Probabilistic Cache Stampede Prevention”, VLDB
  • Gil Einziger, Roy Friedman, Ben Manes (2017), “TinyLFU: A Highly Efficient Cache Admission Policy”, ACM Transactions on Storage
  • Lee Breslau va boshq. (1999), “Web Caching and Zipf-like Distributions: Evidence and Implications”, INFOCOM
  • Michael Luby, Charles Rackoff (1988), “How to Construct Pseudorandom Permutations from Pseudorandom Functions”, SIAM Journal on Computing (Feistel tarmog‘i)
  • John Black, Phillip Rogaway (2002), “Ciphers with Arbitrary Finite Domains”, CT-RSA (cycle walking)
  • bit.ly (2011), “You just shared a link. How long will people pay attention?” — havola yarim yemirilishi tadqiqoti
  • Google Developers Blog (2018, 2024) — goo.gl ni yopish e’lonlari
  • Instagram Engineering, “Sharding & IDs at Instagram” — mantiqiy shardlar
  • Twitter Engineering, “Announcing Snowflake” (2010) — taqsimlangan ID
  • OWASP: Unvalidated Redirects and Forwards; Server-Side Request Forgery Prevention Cheat Sheet

Ushbu sahifa dizayni bit.ly interfeysidan ilhomlangan o‘quv materiali. Loyiha bit.ly bilan bog‘liq emas, rasmiy logotip va shriftlardan foydalanilmagan.