فی الحال ٹیسٹنگ جاری ہے: مکمل ہونے پر GitHub کوڈ کھول دیا جائے گا۔

یہ کیسے کام کرتا ہے

یہ صفحہ کلائنٹ اور سرور (کلسٹر) کے درمیان اصل پیغام کے بہاؤ کی پیروی کرتے ہوئے وضاحت کرتا ہے کہ Ticketing کیسے کام کرتا ہے۔ وائر پر آنے جانے والے بائٹس کی عین وضاحت پروٹوکول (API) اور پروٹوکول (کلسٹر) میں موجود ہے۔


مجموعی ڈھانچہ

صارف کی درخواستیں وصول کرنے والی سروسز (مثلاً ٹکٹ سیل کھلنے کو سنبھالنے والے ایونٹ سرورز) ایک ہی کلید کے لیے Ticketing کلسٹر کے سامنے قطار میں لگتی ہیں، اور صرف وہ سرور جس کی باری آتی ہے انوینٹری کم کرنے یا نشست تفویض کرنے جیسے کام آگے بڑھاتا ہے۔

groups
صارفین
آپ کی سروس (مثلاً ایونٹ سرورز)
dns ایونٹ سرور 1
dns ایونٹ سرور 2
dns ایونٹ سرور 3
Ticketing کلسٹر
confirmation_number ticketing-server 1
confirmation_number ticketing-server 2
confirmation_number ticketing-server 3

لاک کا حصول اور اجراء

بنیادی بہاؤ۔ ایک خالی کلید فوراً دے دی جاتی ہے؛ مصروف کلید FIFO قطار میں اپنی باری کا انتظار کرتی ہے۔ جب حاصل کنندہ اسے جاری کرتا ہے، تو لاک بغیر کسی دوبارہ مقابلے کے براہ راست قطار کے سب سے آگے والے کو منتقل ہو جاتا ہے — اگلا منتظر فوراً ایک نئے ٹوکن کے ساتھ آگے بڑھتا ہے، اس لیے کبھی ایسا لمحہ نہیں آتا جب لاک خالی پڑا ہو، اور کوئی بھی درمیان میں گھس نہیں سکتا۔

کلائنٹ X
کلائنٹ Y
سرور
A · حصول (order-1234)
A · جاری (token 41)
A · حصول (order-1234)
مصروف → قطار میں شامل، جواب روکا گیا
R · اجراء
R · جاری کر دیا گیا
A · براہ راست حوالگی (token 42)
درخواستجواب
  • lease ایک حفاظتی جال ہے۔ اگر کوئی کلائنٹ ختم ہو جائے یا اجراء کرنا بھول جائے، تو lease مدت گزرنے کے بعد سرور کلید واپس لے کر اگلے منتظر کو دے دیتا ہے۔ اسے فیاضی سے مقرر کریں — اپنے تنقیدی حصے (critical section) کے بدترین ممکنہ وقت سے زیادہ۔ v1 صرف 1–250 سیکنڈ قبول کرتا ہے؛ اس سے طویل کام واضح طور پر غیر معاون ہے اور مسترد کر دیا جاتا ہے۔
  • wait انتظار کی بالائی حد ہے۔ اگر اس وقت کے اندر باری نہ آئے، تو سرور لاک دیے بغیر T (ٹائم آؤٹ) سے جواب دیتا ہے، اس لیے کوئی لاک ضائع نہیں ہوتا۔ 0 قطار میں داخل ہوئے بغیر ایک فوری کوشش ہے۔ لامحدود انتظار نہیں ہے۔
  • اگر وہی کلائنٹ کسی ایسی کلید کو دوبارہ حاصل کرنے کی کوشش کرے جو وہ پہلے ہی رکھے ہوئے ہے، تو وہ کسی بھی دوسرے منتظر کی طرح قطار میں لگتا ہے — یہ reentrant لاک نہیں ہے۔

کلید کی حالت کے مطابق سرور کے رویے کے مکمل اصولوں کے لیے درخواست × کلید-حالت میٹرکس، اور فیلڈ کی قدروں کی حد کے لیے فیلڈ کی پابندیاں دیکھیں۔

فینسنگ ٹوکنز

ایک بے عیب لاک سرور بھی کلائنٹ کی گھڑی کو قابو نہیں کر سکتا۔ Ticketing اکیلے پرانے حاصل کنندہ کے معاملے کو نہیں روک سکتا: ایک کلائنٹ جو لاک رکھے ہوئے GC توقف یا اوورلوڈ کے باعث کچھ دیر رکا رہا، پھر بیدار ہوتا ہے — یہ جانے بغیر کہ اس کا lease پہلے ہی ختم ہو چکا ہے — اور اپنا کام جاری رکھتا ہے۔ اسی لیے ہر حصول کے جواب میں موجود token ایک u64 عدد ہے جو ہر بار جاری ہونے پر ضرور بڑھتا ہے۔ مالی یا persistent DB میں فی-key fencing high-water کا موازنہ اور update حقیقی business write کے ساتھ اسی DB transaction یا ایک conditional write میں atomic ہونا چاہیے۔ صرف fencing row پہلے update کر کے حقیقی write بعد میں کرنا محفوظ نہیں۔

کلائنٹ X
کلائنٹ Y
سرور
محفوظ وسیلہ
A · حصول
A · جاری (token 7)
A · حصول → انتظار
GC / اوورلوڈ سے رک گیا
lease ختم → واپس لیا گیا
A · براہ راست حوالگی (token 8)
تحریر (token 8)
token 8 درج → قبول
دیر سے بیدار ہوا
تحریر (token 7)
7 < 8 → مسترد
درخواستجواب

یکسر بڑھاؤ کلسٹر میں بھی برقرار رہتا ہے — ٹوکن کاؤنٹر خود اتفاقِ رائے کے ذریعے نقل کیا جاتا ہے، اس لیے قائد کی تبدیلی کے بعد بھی نیا قائد ہمیشہ پہلے سے بڑے نمبر سے آگے بڑھتا ہے۔ عین فیلڈ فارمیٹ کے لیے فینسنگ ٹوکن (اسپیک) دیکھیں۔

کلسٹر — Raft اتفاقِ رائے کے ذریعے بلا تعطل

کلسٹر موڈ میں، نوڈز Raft اتفاقِ رائے کے ذریعے ایک ہی لاک حالت میں شریک ہوتے ہیں۔ صرف قائد کلائنٹ کی درخواستیں سنبھالتا ہے، اور ہر لاک-حالت کی تبدیلی (حصول، اجراء، میعاد ختم) صرف اس وقت حتمی ہوتی ہے جب اکثریت نوڈز اسے ریکارڈ کر چکے ہوں۔ غیر-قائد نوڈ سے رابطہ کرنے پر آپ کو M (منتقل شدہ) جواب ملتا ہے جو قائد کی طرف اشارہ کرتا ہے۔

کلائنٹ
فالوور B
قائد A
فالوور C
A · حصول
M · قائد کی طرف رہنمائی
A · حصول
نقل کی تجویز
نقل کی تجویز
تصدیق
تصدیق
اکثریت کی تصدیق → کمٹ
A · جاری (token)
درخواستجواباتفاق رائے RPC (Raft)
  • اگر قائد ختم ہو جائے، تو موجودہ defaults تقریباً 2.3 سے 2.5 سیکنڈ میں نیا قائد منتخب کرتے ہیں۔ وہی logical acquire باقی wait budget میں صرف تب جاری رہ سکتا ہے جب request کا کوئی byte نہ بھیجا گیا ہو۔ بھیجے گئے acquire کا جواب confirm نہ ہو تو وہ Indeterminate ہے اور خودکار طور پر دوبارہ نہیں بھیجا جاتا۔
  • حتیٰ کہ lease کا ختم ہونا بھی اتفاقِ رائے سے گزرتا ہے۔ لاک تب ہی غائب ہوتا ہے جب قائد میعاد ختم ہونے کی کمانڈ کمٹ کرے، اس لیے نوڈز کی تھوڑی مختلف گھڑیاں لاک کی حالت کو کبھی الگ نہیں کرتیں۔
  • اگر کلسٹر اکثریت کھو دے (مثلاً 3 میں سے 2 نوڈز بند ہو جائیں)، تو یہ غلط لاک جاری کرنے کا خطرہ مول لینے کے بجائے تحریر قبول کرنا بند کر دیتا ہے (حفاظت پہلے)۔ اگر 3 میں سے 2 (یا 5 میں سے 3) نوڈز کی volatile process state کھو جائے تو اس cluster/fencing domain کو نہ recover کیا جائے، نہ اسی identity کے ساتھ خودکار bootstrap کیا جائے۔

چونکہ اکثریت ہی اہم ہے، صرف 3 یا 5 نوڈز کی اجازت ہے۔ جفت تعداد صرف لاگت بڑھاتی ہے بغیر خرابی برداشت کرنے کی صلاحیت بہتر کیے، اس لیے سرور ایسی تعداد کے ساتھ شروع ہونے سے انکار کرتا ہے۔

نوڈز کی تعدادبلا تعطلبیک وقت برداشت کی جانے والی ناکامیاںنوٹس
1token monotonicity صرف process lifetime تک؛ restart ہونے والی persistent DB کی حفاظت غیر معاون
31بلا تعطل کی معیاری ترتیب۔ زیادہ تر حالات کے لیے کافی
52ایک نوڈ کی دیکھ بھال کے دوران بھی افزونیت برقرار

پیئر RPC کے فریم اور پورٹ کے اصولوں کے لیے پروٹوکول (کلسٹر)، اور نوڈز کو ایک ایک کر کے بدلنے کے لیے بلا تعطل نئے NodeId learner کی تبدیلی دیکھیں۔

کلائنٹ کا رویہ

سرکاری کلائنٹس مشترکہ طور پر درج ذیل رویہ رکھتے ہیں (زبان کے مخصوص APIs کے لیے لائبریریز دیکھیں)۔

  • بیک گراؤنڈ میں ہر پتے کے لیے ایک مستقل کنکشن برقرار رکھتا ہے۔ ایک ہی پتہ دینے پر، یہ اسی نوڈ سے دو کنکشنز برقرار رکھتا ہے، تاکہ ایک ساکٹ کا مختصر منقطع ہونا سروس میں خلل نہ ڈالے۔
  • درخواست بھیجنے کے لیے کنکشن پہلے قائد، پھر راؤنڈ-روبن سے چنا جاتا ہے۔ یہ آخری بار M کے ذریعے بتائے گئے قائد کو یاد رکھتا ہے اور بعد کی درخواستیں براہ راست اسے بھیجتا ہے۔
  • درخواستیں pipelined ہوتی ہیں۔ اگلی درخواست جواب کا انتظار کیے بغیر بھیجی جا سکتی ہے — جوابات کو درخواستوں سے کیسے ملایا جاتا ہے اس کے لیے جواب ملانے کے اصول دیکھیں۔
  • منقطع کنکشن exponential backoff (0.1 سیکنڈ سے 3.2 سیکنڈ کی حد تک) کے ساتھ دوبارہ رابطہ کرتا رہتا ہے۔ ایک مردہ کنکشن broker آبجیکٹ کو خراب نہیں کرتا — یہ خود بخود بحال ہو جاتا ہے۔
  • اسی logical acquire کو اندرونی طور پر صرف اس وقت retry کیا جاتا ہے جب request کا کوئی byte نہ بھیجا گیا ہو۔ متعلقہ B قطعی Busy/عدم حصول ہے اور internal retry کے بغیر فوراً caller کو لوٹتا ہے۔ M صرف اگلے connection کے لیے leader hint ہے؛ owner/key نہ ہونے کی وجہ سے یہ پہلے سے بھیجی pending request کو دوبارہ بھیجنے کی بنیاد نہیں۔ confirm شدہ response کے بغیر بھیجا acquire Indeterminate بتایا جاتا ہے اور critical section میں داخل نہیں ہونا چاہیے۔
  • Explicit release اور known-token compensation عین owner/token/key match اور bounded dedicated queue استعمال کرتے ہیں۔ retry request/enqueue سے absolute 5-second deadline پر رکتی ہے، باقی lease تک نہیں۔ success response کے بغیر explicit release کو کامیاب نہ بتایا جاتا ہے نہ سمجھا جاتا ہے؛ server-side lease آخری حفاظتی جال ہے۔

کنکشنز اور سیکیورٹی

ہر کنکشن (کلائنٹ ہو یا پیئر) TCP → (TLS) → challenge-response تصدیق کی ترتیب میں قائم ہوتا ہے۔ کلائنٹ سرور کے nonce کو ٹوکن کے ساتھ ملا کر ہیش کرتا ہے تاکہ جواب دے سکے، اس لیے ٹوکن کبھی بھی سادہ متن میں وائر پر نہیں بھیجا جاتا، اور ہر کنکشن پر ایک نیا nonce replay کو ناممکن بنا دیتا ہے۔ عین اسپیک کے لیے تصدیقی ہینڈ شیک دیکھیں۔

مطابقت پر ایک نوٹ

  • باہمی اخراج اتفاقِ رائے سے یقینی بنایا جاتا ہے۔ چونکہ ہر اجراء اکثریت کی کمٹ سے گزرتا ہے، اس لیے ایک ہی کلید کبھی بھی بیک وقت دو حاصل کنندگان کو نہیں دی جاتی، چاہے نیٹ ورک کی تقسیم ہو یا قائد کی تبدیلی۔
  • Persistent DB میں fencing لازمی ہے۔ صرف فی-key high-water condition جو protected write کے ساتھ اسی transaction/conditional write میں atomic ہو، lease ختم ہونے کے بعد بیدار client کو روک سکتی ہے۔ Lock کام کی ترتیب بناتا ہے؛ DB fencing آخری stale write روکتا ہے۔