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.
| Savol | Javob shu darsda | Bo‘lim |
|---|---|---|
| Kalit uzunligini qanday tanlaysiz? | Base62 va tug‘ilgan kun paradoksi | 3 |
| Tasodifiy kalit qachon to‘qnashadi? | To‘qnashuv ehtimoli hisobi | 3.2 |
| 301 va 302 orasida qaysi biri? | Redirect semantikasi va analitika | 2.3 |
| Nega bitta havola butun tizimni yiqitadi? | Hot key va cache stampede | 5.2, 10.1 |
| Kesh qancha so‘rovni yutadi? | Zipf, yarim yemirilish va urish darajasi | 8 |
| 100 million havolaga qancha joy kerak? | Saqlash hisobi | 4.2 |
| Kuniga 73 GB analitika bilan nima qilamiz? | Oqim quvuri va HyperLogLog | 6-bo‘lim, 8-qadam |
| Ochiq redirect nima uchun xavfli? | Xavfsizlik | 11.1 |
| Qisqartiruvchi yopilsa, havolalar nima bo‘ladi? | goo.gl saboqi | 11.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:
- Raqamni qanday berish kerak, toki ikki kitob bir xil raqam olmasin va begona odam raqamlarni sanab chiqib, hamma kitobni topa olmasin? (3-bo‘lim)
- Kartochkani qanday tez topish kerak, agar sekundiga o‘n minglab odam so‘rasa? (6–8-bo‘limlar)
- 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.
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.
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
- Uzun URL berilganda qisqa havola qaytarish
- Qisqa havola ochilganda foydalanuvchini asl manzilga yo‘naltirish
- Foydalanuvchi o‘z kalitini tanlashi (
dars.uz/kafka) - Havolaning amal qilish muddati va o‘chirilishi
- Bosishlar statistikasi: soni, geografiya, qurilma, manba
1.4 Nofunksional talablar
| Talab | Aniq ko‘rsatkich | Nega aynan shunday |
|---|---|---|
| Redirect kechikishi | p99 ≤ 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 takrorlanmasligi | 100% | Bitta kalit ikkita manzilga ketsa — halokat |
| Havola muddati | Cheksiz (agar belgilanmagan bo‘lsa) | Havolalar qog‘ozda, kitobda, bannerda qoladi |
| Masshtab | Oyiga 100M yangi havola | Bozor yetakchilariga yaqin tartib |
1.5 Konvert orqasidagi birinchi hisob
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.
- 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.
- O‘lchash. Qaysi havola bosildi va qayerdan — bu reklama va tavsiya tizimi uchun xom ashyo. Uni boshqa kompaniyaga berish — o‘z biznesingizni berish.
- 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
Bu jadvaldan ikkita muhandislik xulosasi chiqadi:
- Serverni 5 ms dan 2 ms ga tushirish deyarli hech narsa bermaydi. Tarmoq hukmron.
- 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
| Kod | Ma’nosi | Brauzer keshlaydimi | Oqibati |
|---|---|---|---|
| 301 Moved Permanently | Doimiy ko‘chirildi | Ha, agressiv | Takroriy bosishlar serverga umuman yetib kelmaydi |
| 302 Found | Vaqtincha | Yo‘q (odatda) | Har bosish serverga keladi |
| 307 Temporary Redirect | Vaqtincha, metodni saqlaydi | Yo‘q | POST so‘rovlar uchun to‘g‘ri |
| 308 Permanent Redirect | Doimiy, metodni saqlaydi | Ha | 301 ning aniqroq versiyasi |
▸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:
- 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
- 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:
| Alifbo | Belgilar | 7 belgi bilan | Muammosi |
|---|---|---|---|
| Base10 | 10 | 10⁷ = 10 million | Juda kichik |
| Base16 | 16 | 2.7×10⁸ | Kichik, lekin o‘qilishi oson |
| Base62 | 62 | 3.5×10¹² | Standart tanlov |
| Base64 | 64 | 4.4×10¹² | + va / URL da muammo qiladi |
| Base58 | 58 | 2.2×10¹² | 0, O, l, I olib tashlangan — qo‘lda yozishga qulay |
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.
▸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
- 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
- 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.
3.4 Qaysi birini tanlash kerak
| Mezon | Tasodifiy | Hisoblagich | KGS |
|---|---|---|---|
| Yozishda qo‘shimcha o‘qish | Bor | Yo‘q | Yo‘q |
| Koordinatsiya | Yo‘q | Har yozuvda | Blok bo‘lib |
| Kalitlarni taxmin qilish | Imkonsiz | Oson | Imkonsiz (aralashtirilgan bo‘lsa) |
| Amalga oshirish murakkabligi | Eng oddiy | O‘rtacha | Yuqori |
| 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.
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
▸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:
| Kod | Qachon | Mijoz nima qilishi kerak |
|---|---|---|
400 | URL noto‘g‘ri formatda | Tuzatib qayta yuborish |
409 | Maxsus kalit band | Boshqa kalit taklif qilish |
422 | URL zararli deb topildi | Foydalanuvchiga sababni ko‘rsatish |
429 | Tezlik cheklovi | Retry-After bo‘yicha kutish |
503 | Kalit 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) | |
|---|---|---|
| Yozish | Sahifani joyida yangilaydi + WAL | Xotiraga yozadi, keyin ketma-ket disk |
| Yozish amplifikatsiyasi | 2–5× (sahifa + WAL) | 10–30× (compaction) |
| Yozish tezligi | O‘rtacha (tasodifiy IO) | Yuqori (ketma-ket IO) |
| O‘qish | 1–2 IO (bashoratli) | 1–5 IO (darajalar bo‘yicha qidiruv) |
| O‘qish yordami | Sahifa keshi | Bloom filtrlari har bir SSTable uchun |
| Bo‘sh joy | Fragmentatsiya | Compaction paytida vaqtincha 2× |
▸Chuqurroq: Bizning yukimiz uchun qaysi biri to'g'ri
Ikkita muhim xususiyatimiz bor:
- O‘qish ustunlik qiladi (100:1) va o‘qishlar — birlamchi kalit bo‘yicha nuqta qidiruvi, diapazon skani emas
- 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
UNIQUEcheklovi 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:
| Yechim | Qanday ishlaydi | Kamchiligi |
|---|---|---|
| Yaratishda keshga yozish | Yozuv bazaga tushishi bilan keshga ham qo‘yiladi | Kesh tushsa muammo qaytadi |
| Yozgandan keyin asosiy bazadan o‘qish | N soniya davomida shu foydalanuvchi asosiy bazaga yo‘naltiriladi | Asosiy bazaga qo‘shimcha yuk; sessiya holati kerak |
| Versiya belgisi (LSN) | Mijozga yozuv pozitsiyasi beriladi, o‘qishda replika shu pozitsiyaga yetganini tekshiradi | Murakkab; 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.
| Muammo | Belgisi | Qaysi qadamda hal qilinadi |
|---|---|---|
| O‘qish yuki | Baza CPU 100%, timeout | 2-qadam: kesh |
| Hot key | Bitta shard yonadi | 3-qadam: chekka kesh, 6-qadam |
| Statistika yozuvi | Redirect sekinlashdi | 8-qadam: asinxron quvur |
| Yozish koordinatsiyasi | Yozish kechikishi o‘syapti | 5-qadam: KGS |
| Geografiya | p99 uzoq mintaqalarda yomon | 4-qadam: anycast va edge |
| Yo‘q kalitlar | Keshsiz so‘rovlar oqimi | 7-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.
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:
| Saqlash | Kalit bo‘yicha o‘qish | Nima uchun tanlanadi | Nima uchun tanlanmaydi |
|---|---|---|---|
| PostgreSQL | ~0.2 ms (issiq) | Tranzaksiya, ikkilamchi indekslar, oddiy operatsiya | Bitta tugun o‘qishda cheklangan |
| DynamoDB / Cassandra | ~2–5 ms | Chiziqli masshtablanadi, boshqariladi | Murakkab so‘rov yo‘q, narx |
| Redis (asosiy saqlash) | ~0.1 ms | Eng tez | RAM narxi: 3.7 TB uchun juda qimmat |
| Edge KV (Workers KV va sh.k.) | ~5 ms, lekin foydalanuvchiga yaqin | Geografiya bepul keladi | Yozish 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
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.
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:
- 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
- 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.
| Siyosat | Qanday ishlaydi | Bu yukda |
|---|---|---|
| LRU | Eng uzoq vaqt ishlatilmaganini chiqaradi | Skanerlashga chidamsiz |
| LFU | Eng kam ishlatilganini chiqaradi | Eski mashhur havolalar qotib qoladi |
| W-TinyLFU | Chastotani ixcham sanab, LRU bilan birlashtiradi | Eng 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
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
Yutuq: Bitta havola sekundiga million marta bosilsa ham tizim sezmaydi
Narxi: Bir necha soniyalik nomuvofiqlik: turli serverlar turli javob berishi mumkin
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.
- Toshkentdan RTT ~120 ms
- TLS qo'l siqish bilan ~250 ms
- Oddiy va arzon
- Mintaqa tushsa — hamma joyda ishlamaydi
- 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 keshi | Chekka KV | |
|---|---|---|
| Birinchi so‘rov | Origin‘ga boradi (sekin) | Chekkada hal bo‘ladi |
| Invalidatsiya | Purge API, tez | Replikatsiya kechikishi |
| Analitika | Chekkadan yig‘iladi | Chekkadan yig‘iladi |
| Origin tushsa | stale-if-error bilan ishlaydi | Butunlay ishlaydi |
| Murakkablik | Past | Yuqori |
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
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
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
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.
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
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.
Foydalanuvchi kutmaydi. Bufer to'lsa — hodisa TASHLANADI (bu to'g'ri qaror).
Paketlab yuboriladi: 1000 ta hodisa yoki 1 soniya — qaysi biri oldin bo'lsa.
Ikki yo'l: tezkor hisoblagichlar va batafsil tahlil uchun xom ma'lumot.
Har biri boshqa savolga javob beradi.
▸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
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:
- 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 - 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 - 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
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
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.
| Chora | Qachon ishlaydi | Narxi |
|---|---|---|
| Yaratishda URL ni skanerlash | Ma’lum zararli manzillar | Yaratishga 100–300 ms |
| Davriy qayta skanerlash | Manzil keyin zararli bo‘lsa | Fon yuki |
| Domenlar qora ro‘yxati | Ma’lum yomon domenlar | Yangilab turish kerak |
| Oraliq ogohlantirish sahifasi | Shubhali havolalar | Redirect tezligi yo‘qoladi |
| Yaratish uchun ro‘yxatdan o‘tish | Anonim suiiste’molni kamaytiradi | Konversiya tushadi |
| Tezlik cheklovi (IP, akkaunt) | Ommaviy yaratish | Halol 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
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
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
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):
- Kesh tugunlaridan biri tushgan yoki qayta ishga tushgan — sovuq kesh
- TTL noto‘g‘ri qisqartirilgan (masalan 24 soatdan 1 soatga)
- Kesh xotirasi to‘lib, evicton boshlangan — havolalar soni o‘sgan bo‘lishi mumkin
- Trafik naqshi o‘zgargan: ommaviy skanerlash yoki bot hujumi (salbiy keshlash yo‘q bo‘lsa)
- 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.
- DNS
dars.uzuchun bitta IP qaytaradi, lekin bu IP yuzlab nuqtadan e’lon qilingan (anycast, 2.4). Tarmoq so‘rovni eng yaqin nuqtaga olib boradi. - TCP va TLS chekkada tugaydi — foydalanuvchidan 10–20 ms masofada. Ilgari ulanish bo‘lgan bo‘lsa, bu qadam qayta ishlatiladi.
- Chekka KV da kalit bor bo‘lsa (odatda 90% va undan ko‘p), javob shu
yerda yasaladi:
302vaLocation. - Bosish hodisasi chekkadagi buferga tushadi va paketlab markazga ketadi (8-qadam). Foydalanuvchi buni kutmaydi.
- Chekkada kalit yo‘q bo‘lsa — origin yo‘li: Bloom filtri → L1 → L2 → baza. Topilgan javob chekkada ham keshlanadi.
7.2 Vaqt qayerga ketadi
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.
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.
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:
- Bosish chekkaga tushdi, chekka KV da kalit yo‘q
- Chekka origin’dan so‘radi. Agar origin’da replikatsiya kechikkan bo‘lsa
yoki so‘rov havola yaratilishidan millisoniyalar oldin kelgan bo‘lsa —
404 - Chekka bu
404ni 5 daqiqaga keshladi - Havola endi bazada bor, lekin shu chekka nuqtadagi hamma foydalanuvchi
5 daqiqa davomida
404oladi — 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.
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.0 | s = 1.1 | s = 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.
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
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
Redirect'larning 90% i shu yerda tugaydi va origin'ga umuman bormaydi.
Chekkada topilmagan va yangi kalitlar shu yerga tushadi.
Yuk kichik (200/s), lekin izchillik talabi yuqori.
3.7 TB, 10-16 shard, har birida replika.
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.
9.1 Ikki yo‘lning qiyosi
- Chekkada tugaydi, origin'ga kamdan-kam boradi
- Eventual consistency maqbul
- Kesh urishi 95%+ bo'lishi shart
- Mavjudlik 99.99% — eng muhim talab
- 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:
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.
Uchta himoya, birgalikda ishlatiladi:
- Single-flight — bitta kalit uchun faqat bitta so‘rov bazaga boradi, qolganlari uning natijasini kutadi
- Ehtimolli erta yangilash — TTL tugashiga yaqin har bir so‘rov kichik ehtimollik bilan keshni yangilaydi. Natijada yangilash bitta lahzada emas, vaqt bo‘ylab tarqaladi
- 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
| Nosozlik | Belgisi | Sabab | Chora |
|---|---|---|---|
| Kesh tuguni tushdi | Bazaga yuk 20× oshdi | Apparat, OOM | Kesh replikasi, bazaga rate limit, degradation |
| Cache stampede | Baza ulanishlari tugadi | TTL bir vaqtda tugadi | Single-flight, SWR, TTL ga tasodifiy qo‘shimcha |
| Hot key | Bitta Redis tuguni 100% | Viral havola | L1 kesh, chekka kesh |
| Baza shardi tushdi | Kalitlarning 1/N qismi ishlamaydi | Apparat, failover | Replikaga o‘tish, kesh eski qiymatni beradi |
| Chekka eskirdi | O‘chirilgan havola ishlayapti | Purge yetib bormadi | Majburiy invalidatsiya, qisqa TTL kritik havolalarga |
| Domen qora ro‘yxatda | Barcha havolalarda ogohlantirish | Fishing suiiste’moli | Skanerlash, tez o‘chirish, obro‘ni tiklash jarayoni |
| Analitika navbati to‘ldi | Statistika kechikyapti | Cho‘qqi yoki iste’molchi sekin | Hodisalarni tashlash (redirect ishlashda davom etadi) |
| Kalit maydoni tugadi | Yozish xatolari o‘syapti | Uzunlik oshirilmagan | Uzunlikni oshirish (14-qadam) |
10.3 Degradatsiya tartibi
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
▸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 turi | Nimani tekshiradi | Qanday |
|---|---|---|
| Birlik | Kalit generatsiyasining taqsimoti | 1M kalit yaratib, belgilar taqsimotini va takrorlanishini tekshirish |
| Birlik | To‘qnashuvda qayta urinish | Bazani majburan UNIQUE xatosi qaytarishga majburlash |
| Integratsiya | Maxsus kalit poygasi | Ikki parallel so‘rov, bittasi muvaffaqiyatli bo‘lishi shart |
| Integratsiya | Kesh invalidatsiyasi | O‘chirilgan havola keshdan ham yo‘qolganini tekshirish |
| Yuk | Cho‘qqidagi p99 | Kesh issiq va sovuq holatda alohida |
| Yuk | Cache stampede | Bitta hot kalitga TTL tugash lahzasida ommaviy so‘rov |
| Xaos | Kesh tuguni tushishi | Bazaga yuk oshadi, tizim yiqilmasligi kerak |
| Xaos | Shard failover | Kalitlarning 1/N qismi keshdan xizmat olishda davom etadimi |
| Sintetik | Doimiy nazorat | Bir 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
| Xavf | Tafsilot | Chora |
|---|---|---|
| URL da maxfiy ma’lumot | Token, sessiya, ism URL da bo‘lishi mumkin | URL ni loglarda maskalash, saqlash muddati |
| Referrer sizishi | Maqsad sayt qaysi qisqa havoladan kelganini ko‘radi | Referrer-Policy: no-referrer |
| IP va qurilma yozuvlari | Analitika shaxsiy ma’lumot to‘playdi | Anonimlashtirish, saqlash muddati, huquqiy asos |
| Havola ommaviyligi | Qisqa havola — amalda ochiq | Foydalanuvchini 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.
Muhandis uchun uchta saboq:
- 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.
- 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.
- 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:
- 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.
- Yaratishni to‘xtatish: yangi havola yo‘q, eskilari ishlaydi.
- Ogohlantirish: redirect oldidan oraliq sahifa (“bu havola falon sanada ishlamay qoladi”) va egalariga xat — eksport havolasi bilan.
- Faollarni saqlash: ogohlantirish davrida bosilgan havolalar ro‘yxati saqlanadi va ular ishlashda davom etadi — goo.gl oxir-oqibat aynan shunga keldi.
- Arxivga topshirish: qolgan havolalar ro‘yxatini ochiq arxivga berish (masalan, veb-arxiv loyihalariga), shunda tadqiqotchilar manzillarni tiklay oladi.
- Faqat shundan keyin
404yoki410 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
Ikkita xulosa:
- 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
- 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.
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
▸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.
| Resurs | Shovqinli qo‘shni qanday zarar qiladi | Chora |
|---|---|---|
| KGS diapazonlari | Ommaviy import kalitlarni tez yeydi | Mijoz bo‘yicha yaratish kvotasi |
| Kesh xotirasi | Bitta mijozning havolalari keshni to‘ldiradi | Mijoz bo‘yicha kesh ulushi yoki W-TinyLFU |
| Shard yuki | Viral havola bitta shardni bo‘g‘adi | Chekka kesh (yuk shardgacha yetmaydi) |
| Analitika navbati | Bitta mijoz hodisalari navbatni to‘ldiradi | Mijoz bo‘yicha partition va kvota |
| Baza ulanishlari | Uzun so‘rov hovuzni band qiladi | Alohida 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:
| Metrika | Nega muhim | Ogohlantirish chegarasi |
|---|---|---|
| Redirect p50 / p95 / p99 | Asosiy foydalanuvchi tajribasi | p99 > 100 ms |
| Kesh urish darajasi (L1, L2, chekka) | Bazaga yukni belgilaydi | 90% dan past |
| 404 ulushi | Skaner hujumi yoki buzuq havolalar | 5% dan yuqori |
| Yaratish kechikishi | Skanerlash sekinlashganini ko‘rsatadi | p95 > 500 ms |
| Kalit maydoni bandligi | Uzunlikni oshirish vaqti | 15% dan yuqori |
| Analitika navbati kechikishi | Statistika qanchalik eskirgan | 5 daqiqadan ko‘p |
| Tashlangan hodisalar | Degradatsiya ishlayaptimi | Har qanday o‘sish |
14.1 SLO va xato byudjeti
“99.99% mavjudlik” degan gap byudjetga aylantirilmasa, ma’nosiz shior bo‘lib qoladi.
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.
Botlarni ajratishning uch usuli, ishonchliligi bo‘yicha:
- User-Agent ro‘yxati — oson, lekin eskiradi va soxtalashtirilishi mumkin
- Xulq-atvor — bot havolani qo‘yilgan lahzada, bir necha millisoniya ichida ochadi va keyin hech qachon qaytmaydi; odam esa tasodifiy vaqtda keladi
- 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:
- Bloom filtri — yo‘q kalitlar keshgacha ham yetib bormaydi. Eng kuchli chora, lekin 7.2 GB xotira va davriy qayta qurish talab qiladi
- Salbiy keshni ajratish — 404 lar alohida, hajmi cheklangan keshda saqlanadi va asosiy keshni buzmaydi. Arzon va tez amalga oshiriladi
- W-TinyLFU — yangi element keshga kirish uchun chastota imtihonidan o‘tadi; bir martalik so‘rovlar keshni buza olmaydi
- Tezlik cheklovi — manbani sekinlashtiradi, lekin taqsimlangan skanerni to‘xtatmaydi
Amalda 2 + 4 darhol qilinadi, 1 va 3 esa keyingi bosqichda.
15. Antinaqshlar
| Qaror | Nima yutamiz | Nimani yo'qotamiz |
|---|---|---|
| Analitikani redirect ichida sinxron yozish | Kod sodda, statistika aniq | Redirect 20 barobar sekinlashadi; analitika tushsa havolalar ham ishlamaydi |
| Kalitni URL hash'idan olish | Deduplikatsiya bepul | Ikki foydalanuvchi bitta havolani baham ko'radi; biri ikkinchisinikini o'chira oladi |
| Ketma-ket kalitlar (aralashtirilmagan) | To'qnashuv yo'q, oddiy | Enumeration: barcha shaxsiy havolalarni sanab chiqish mumkin |
| 301 redirect (analitika kerak bo'lganda) | Serverga yuk 5 barobar kam | Analitikaning 80% i yo'qoladi; manzilni hech qachon o'zgartirib bo'lmaydi |
| 'Avval tekshir, keyin yoz' (maxsus kalitlar uchun) | Ko'rinishidan mantiqiy | Poyga holati: ikki foydalanuvchi bir kalitni oladi. UNIQUE cheklov shart |
| Yo'q kalitlarni keshlamaslik | Kesh 'toza' bo'ladi | Skanerlar to'g'ri bazani uradi — cache penetration |
| O'chirilgan kalitni qayta ishlatish | Kalit maydoni tejaladi | Eski havola boshqa saytga olib boradi — chalkashlik va xavfsizlik muammosi |
| Bir xil TTL hamma kalitlarga | Sozlash oson | Ommaviy TTL tugashi — stampede. Tasodifiy qo'shimcha (jitter) kerak |
| Foydalanuvchi URL'ini tekshirmasdan o'qish (unfurl) | Chiroyli oldindan ko'rish | SSRF: ichki tarmoq va bulut metama'lumotiga kirish |
16. Trade-off‘lar
| Qaror | Nima yutamiz | Nimani yo'qotamiz |
|---|---|---|
| 7 belgili kalit | 100+ yilga yetadi, to'qnashuv arzon | 6 belgidan uzunroq — mahsulot jozibasi biroz kam |
| Tasodifiy kalit | Koordinatsiyasiz, taxmin qilinmaydi | Yozishda qo'shimcha tekshiruv |
| KGS (oldindan generatsiya) | Yozish yo'li eng tez | Yangi xizmat, restart'da kalitlar yo'qoladi |
| Chekka redirect | Kechikish 5 barobar kam, origin himoyalangan | O'chirish va yangilash kechikadi |
| Salbiy keshlash | Skanerlardan himoya | Yangi havola bir muddat 404 berishi mumkin |
| Stale-while-revalidate | Stampede yo'q, kechikish barqaror | Bir necha soniya eskirgan manzil |
| HyperLogLog (noyob sanash) | 10 000 barobar kam xotira, birlashtiriladi | ~1% xato; aniq son kerak bo'lsa yaramaydi |
| Bloom filtri | Yo'q kalitlar bazaga bormaydi | Xotira; o'chirish yo'q; noto'g'ri ijobiy javoblar |
| Ko'p mintaqali yozish | Mintaqa tushsa ham yaratish ishlaydi | Kalit maydonini bo'lish kerak; operatsion murakkablik |
Butun dars o‘nta gapda
- Qisqartiruvchi — juda katta va juda tez kalit-qiymat qidiruv: bitta
GETva bittaPUT; qolgan hamma narsa ularni tez, arzon va ishonchli qilish uchun (2.5). - 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).
- 302, 301 emas: brauzer keshi analitikani va havolani o‘zgartirish imkonini o‘ldiradi (2.3).
- Kalit uzunligi raqamdan chiqadi: 6 milliard havola → 7 belgili base62; to‘qnashuvni yo‘q qilish emas, arzon qilish kerak (3-bo‘lim).
- Hisoblagich + Feistel + blok: takrorsiz, taxmin qilinmaydigan kalitlar markazga deyarli murojaatsiz (3.3, 5-qadam).
- Kechikishni tarmoq belgilaydi: server 5 ms, tarmoq 150 ms — chekka va anycast kesh optimallashtirishdan muhimroq (2.2, 7.2).
- 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).
- Keshning nosozliklari keshsizlikdan xavfliroq: stampede, hot key, skaner — single-flight, SWR, L1 va Bloom filtri bilan (6, 10-bo‘limlar).
- Analitika asinxron va yo‘qotishga ruxsat etilgan: statistika buzilsa ham havola ishlashi kerak (8-qadam, 10.3).
- 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:
- Umr davomidagi havolalar soni: oyiga 100M × 12 × 5 yil = 6 milliard
- Maydon hajmi: base62 da
62^n. 6 belgi = 5.68×10¹⁰, 7 belgi = 3.52×10¹² - 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:
- Chekka kesh — so‘rov origin‘ga umuman yetib kelmaydi. Bu 99% holatni yopadi
- L1 kesh (ilova jarayonining xotirasida, TTL 5 soniya) — 50 ta server bo‘lsa, Redis‘ga yuk 500 000 dan 10 ga tushadi
- 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?
- 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
- Kesh urish darajasi — tushganmi? Sabablari: tugun qayta ishga tushgan, TTL o‘zgargan, eviction boshlangan, skaner hujumi
- Geografiya — muammo hamma mintaqadami yoki bittasidami? Bitta mintaqada bo‘lsa — chekka nuqtasi yoki tarmoq
- 404 ulushi — oshgan bo‘lsa, skanerlar bazani uryapti (Bloom filtri yoki salbiy keshlash ishlamayapti)
- 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:
- Konfiguratsiyada generatsiya uzunligini 7 dan 8 ga oshirish
- Eski kalitlar tegilmaydi — yechish uzunlikka qarab emas, aynan kalit bo‘yicha ishlaydi, shuning uchun 7 va 8 belgili kalitlar birga yashaydi
- Kesh va Bloom filtri o‘zgarishsiz ishlaydi
- 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:
- Qaysi qatlam 404 berdi? Javobdagi sarlavha yoki jurnal: chekka, origin keshi yoki baza
- Chekka 404 ni keshladimi? Agar ha — salbiy TTL qancha? Uzun bo‘lsa, havola o‘sha nuqtada shuncha vaqt “o‘lik” turadi
- Origin’da havola bormi? L2 va Bloom filtriga yaratish paytida sinxron yozilganmi, yoki fonda (keyinroq)?
- 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.
- Maxsus domen — mijoz havolalari uning o‘z domenida bo‘lsin. Xizmat yopilsa, u DNS’ni boshqa joyga yo‘naltiradi
- Eksport — har mijoz istalgan payt barcha havolalarini
kalit → URLro‘yxati sifatida yuklab ola olsin - 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:
- 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
- Xato ulushini oshirish — p = 10% da hajm ikki barobar kichik (3.6 GB). Skaner so‘rovlarining 90% i baribir to‘xtaydi
- 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.
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?
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):
keys.py—encode/decode(base62),Feistel(aralashtiruvchi bijeksiya, cycle walking bilan) vaKeyAllocator(markazdan blok bilan son olib, kalit beradi)bloom.py—mvakformulasi, “ikki xesh” pozitsiyalari,addvaincache.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.
3-daraja: ishlaydigan xizmat va yuk testi
2-darajadagi modullaringiz asosida HTTP xizmat yozing:
POST /api/v1/links— URL validatsiyasi,KeyAllocatordan kalit,Idempotency-Key, maxsus kalit (UNIQUEcheklovi va band so‘zlar ro‘yxati), muddatGET /:key— Bloom filtri, keyinLinkCache(yoki Redis),302; topilmasa404, o‘chirilgan bo‘lsa410- Bosishlarni asinxron sanash: bufer + fon vazifasi; bufer to‘lsa — hodisa tashlanadi
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.
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
| Atama | Ma’nosi |
|---|---|
| Base62 | a-z, A-Z, 0-9 — URL uchun xavfsiz 62 belgili alifbo |
| Kalit maydoni | Mumkin bo‘lgan barcha kalitlar to‘plami: 62^n |
| Tug‘ilgan kun paradoksi | To‘qnashuv ehtimoli intuitsiyadan ancha tez o‘sishi |
| KGS | Key Generation Service — kalitlarni oldindan yaratuvchi xizmat |
| Feistel shifri | Ketma-ket sonlarni to‘qnashuvsiz aralashtiruvchi bijektiv o‘girish |
| 301 / 302 / 307 / 308 | Redirect kodlari; keshlanishi va metod saqlanishi bilan farq qiladi |
| Cache-aside | Ilova keshni o‘zi boshqaradigan naqsh |
| Salbiy keshlash | Topilmagan kalitlarni ham keshlash (skanerlardan himoya) |
| Cache stampede | TTL tugagan lahzada barcha so‘rovlarning bazaga yugurishi |
| Single-flight | Bir xil kalit uchun faqat bitta bazaga so‘rov yuborish |
| Stale-while-revalidate | Eskirgan qiymatni qaytarib, yangilashni fonda qilish |
| Hot key | Nomutanosib ko‘p so‘raladigan bitta kalit |
| Cache penetration | Mavjud bo‘lmagan kalitlar orqali keshni chetlab o‘tish |
| Bloom filtri | “Aniq yo‘q / bo‘lishi mumkin” javobini beruvchi ehtimollik strukturasi |
| HyperLogLog | Noyob elementlarni kam xotirada taxminiy sanash |
| Izchil xeshlash | Shard qo‘shilganda ma’lumotning faqat 1/N qismi ko‘chishi |
| Mantiqiy shard | Jismoniy tugunlarga xaritalanadigan sobit sonli bo‘lak |
| Tombstone | O‘chirilgan yozuvning kalitni band qilib turuvchi belgisi |
| Anycast | Bir xil IP ni ko‘p joyda e’lon qilib, eng yaqiniga yo‘naltirish |
| Chekka KV | Foydalanuvchiga yaqin nuqtalardagi kalit-qiymat saqlash |
| Enumeration | Kalitlarni ketma-ket sanab, begona havolalarni topish hujumi |
| Ochiq redirect | Domenning istalgan manzilga yo‘naltirishi va undan suiiste’mol |
| SSRF | Serverni ichki tarmoqqa so‘rov yuborishga majburlash zaifligi |
| DNS rebinding | Domenni tekshiruvdan keyin ichki IP ga yo‘naltirish hiylasi |
| Degradatsiya tartibi | Sig‘im yetmaganda nimadan voz kechish ketma-ketligi |
| Redirect | Server sahifa o‘rniga “boshqa manzilga bor” deb javob berishi |
| Cycle walking | Natija domendan tashqarida bo‘lsa, qayta shifrlash — bijeksiyani saqlaydi |
| Zipf taqsimoti | i-o‘rindagi element ulushi 1 / i^s ga proporsional notekis taqsimot |
| Yarim yemirilish | Havola umrbod bosishlarining yarmini oladigan vaqt (~3 soat) |
| Ishchi to‘plam | Ma’lum vaqt oralig‘ida haqiqatan so‘ralayotgan kalitlar |
| Urish / topilmaslik darajasi | Keshdan javob berilgan / bazaga ketgan so‘rovlar ulushi |
| Miss-to-origin | Chekkada topilmagan so‘rovni origin’dan so‘rash siyosati |
| Link rot | Vaqt o‘tishi bilan havolalarning ishlamay qolishi |
| UTM | Marketing kanalini belgilovchi URL parametrlari (utm_source va sh.k.) |
20. Raqamlar manbasi
| Raqam | Qiymat | Manba |
|---|---|---|
| TinyURL | 2002-yil yanvar, Kevin Gilbertson; Usenet forumlari uchun | TinyURL va Kevin Gilbertson haqidagi ommaviy manbalar (Wikipedia) |
| bit.ly | 2008, Nyu-York | Bitly haqidagi ommaviy manbalar |
| bit.ly hajmi | Oyiga yuzlab million havola, ~10 mlrd bosish | Kompaniyaning o‘z da’volari; yillar bo‘yicha farq qiladi |
| t.co | 2011-yil iyun; 10-oktabrdan barcha havolalar o‘raladi | Twitter dasturchilar blogi, 2011; texnik matbuot |
| goo.gl | 2009 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 404 | Google Developers blogi; Archive Team; texnik matbuot |
| Havola yarim yemirilishi | Twitter 2.8, Facebook 3.2, to‘g‘ridan-to‘g‘ri 3.4, YouTube 7.4 soat; 1000 ta havola | bit.ly tadqiqoti, 2011-yil sentabr |
| HTTP redirect semantikasi | 301/302/307/308 | RFC 9110 |
| Bloom filtri formulasi | m = -n ln p / (ln 2)^2, k = (m/n) ln 2 | Bloom (1970); Kirsch va Mitzenmacher (2006) |
| HyperLogLog xatosi | 1.04 / sqrt(m); 16 384 registr (12 KB) — ~0.81% | Flajolet va boshq. (2007) |
| QR sig‘imi | Bayt rejimi, M daraja: V1 — 14, V2 — 26, V3 — 42, V4 — 62 bayt | ISO/IEC 18004 |
| 2-daraja natijalari | 17/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