مسئله: bit.ly بساز — لینک بلند میگیرد، کد کوتاه میدهد، و ریدایرکت میکند. کلاسیکترین سؤال مصاحبه، چون همه اجزای پایه را لمس میکند.
۱-۲) نیازمندی و تخمین
- FR: ساخت لینک کوتاه (+ دلخواه: آدرس سفارشی، انقضا)، ریدایرکت، آمار کلیک.
- NFR: ریدایرکت زیر 50ms و ۹۹.۹۹٪ در دسترس — مسیر خواندن مقدس است.
- فرض: 100M لینک جدید در ماه (~40/s)، خواندن 100:1 → ~4K QPS ریدایرکت، پیک 10x.
- ذخیره: هر رکورد ~500B × 100M × 12 ماه × ۵ سال ≈ 3TB — کوچک! مسئله storage نیست، تأخیر است.
۳) طراحی — تولید کد کوتاه
دو راه اصلی: (الف) hash لینک (MD5 و برداشتن ۷ کاراکتر) — خطر برخورد و نیاز به بررسی؛ (ب) شمارنده سراسری + تبدیل Base62 — بدون برخورد، ولی شمارنده باید توزیعشده باشد. راه پخته: هر سرور یک «بازه شماره» (مثلاً ۱۰هزارتایی) از یک سرویس ticket میگیرد و آفلاین خرج میکند — نه برخورد، نه گلوگاه. ۷ کاراکتر Base62 = 62⁷ ≈ 3.5 تریلیون کد؛ تا ابد کافی.
DIAGRAMمسیر خواندن — ۹۹٪ ترافیک
Client
→
LB
→
Redirect svc
→
Cache — Redis
→
DB — KV در Miss
۴) عمق و گلوگاه
- دیتابیس: Key-Value (کد → URL) کافی است؛ Shard با hash کد.
- کش: لینکهای داغ (قانون پارتو) در Redis؛ hit rate ۹۰٪+ طبیعی است.
- ریدایرکت: 302 (موقت) اگر آمار میخواهی — 301 را مرورگر کش میکند و دیگر کلیکها را نمیبینی.
- آمار کلیک: در مسیر ریدایرکت فقط یک رویداد به Kafka بینداز؛ تجمیع async — مسیر داغ را سنگین نکن.
به زبان ساده
لینک کوتاه یعنی یک کلید کوتاه به یک آدرس بلند؛ مسیر خواندن (ریدایرکت) ۹۹٪ ترافیک است و باید کوتاه، کششده و بیوابستگی بماند.
مثال واقعی
۷ حرف Base62 فضای ۳.۵ تریلیون کد میدهد؛ هر سرور یک «بازه شماره» از سرویس شمارنده میگیرد تا نه برخوردی باشد نه گلوگاه مرکزی.