مسئله: اتصال مسافر به نزدیکترین راننده در چند ثانیه. سه زیرسیستم: ردیابی لوکیشن (نوشتن سنگین)، تطبیق (جستجوی مکانی داغ) و سفر/پرداخت (تراکنشی).
۱-۲) نیازمندی و تخمین
- FR: درخواست سفر، یافتن رانندههای نزدیک، پیشنهاد و پذیرش، ردیابی زنده، قیمت و پرداخت.
- NFR: تطبیق <5s؛ لوکیشن زنده با تأخیر <2s؛ داده سفر/پول گم نشود.
- تخمین (فصل ۲): 200K راننده فعال ÷ 4s ≈ 50K location-write/s — گلوگاه اصلی همین است.
۳) طراحی — ایندکس مکانی
«نزدیکترین رانندهها» با کوئری روی lat/lng خام نمیشود. زمین را سلولبندی میکنیم: Geohash (رشتهای که مکان را به سلولهای تو در تو کد میکند) یا Quadtree. آخرین لوکیشن رانندهها فقط در RAM: Redis GEO یا نگاشت cell → لیست رانندهها. جستجو = سلول مسافر + سلولهای همسایه، بعد مرتبسازی با فاصله واقعی/ETA.
۴) عمق
- لوکیشن: از اپ راننده → Gateway → Kafka؛ یک مصرفکننده Redis GEO را بهروز میکند (مسیر داغ)، یکی تاریخچه را به Cold Storage میریزد (مسیر سرد).
- تطبیق بدون دوبار-اعزام: پیشنهاد سفر با قفل/lease کوتاه روی راننده (SETNX + TTL)؛ رد یا timeout → راننده بعدی.
- سفر = state machine (requested → matched → arrived → started → finished → paid) در DB تراکنشی؛ هر گذار رویدادی منتشر میکند.
- قیمت: مسافت/زمان + ضریب تقاضای منطقه (surge) که خودش خروجی استریمِ تراکم لحظهای است.
- ردیابی زنده مسافر: همان لوکیشن راننده از مسیر داغ، push روی WebSocket مسافر.
به زبان ساده
اسنپ یعنی جریان مداوم موقعیت رانندهها (هر چند ثانیه)، تطبیق سریع مسافر با نزدیکترین راننده آزاد، و بهروزرسانی زنده نقشه — داده فرّار و داده ماندگار کاملاً جدا رفتار میشوند.
مثال واقعی
موقعیت راننده در Redis با TTL مینشیند چون ۳۰ ثانیه دیگر کهنه است؛ اما خودِ سفر (کرایه، مسیر) تراکنش ماندگار در دیتابیس است.