ডিস্ট্রিবিউটেড কম্পিউটিংয়ের গভীরে নিহিত রয়েছে এক গভীর ও আপাতদৃষ্টিতে অবিশ্বাস্য সত্য: পরস্পর সংযুক্ত স্বাধীন কম্পিউটারগুলোর মাঝে সার্বজনীন বা নৈর্ব্যক্তিক কোনো অভিন্ন ভৌত সময় বলে কিছু নেই। একটি একক প্রসেসরে বা সেন্ট্রালাইজড কম্পিউটারে একটি কেন্দ্রীয় ক্লক প্রতিটি নির্দেশকে ধারাবাহিকভাবে সাজিয়ে দেয়। কিন্তু যখনই গণনা একাধিক স্বাধীন সার্ভারে ছড়িয়ে দেওয়া হয় এবং তারা নেটওয়ার্কের মাধ্যমে যোগাযোগ করে, তখন ভৌত সময় আপেক্ষিক হয়ে পড়ে।
১. ক্লক ড্রিফট ও ভৌত সময়ের সীমাবদ্ধতা
প্রতিটি সার্ভারের মাদারবোর্ডে একটি কোয়ার্টজ ক্রিস্টাল অসিলেটর থাকে। তাপমাত্রা, ভোল্টেজের ওঠানামা এবং উপাদানের বয়সের কারণে প্রতিটি ঘড়ির নিজস্ব ক্লক ড্রিফট ($rho$) থাকে, যার মান সাধারণত:
$$rho approx 10^{-5} text{ থেকে } 10^{-6} implies text{প্রতি সেকেন্ডে ১ থেকে ১০ মাইক্রোসেকেন্ড বিচ্যুতি}$$
যদি কোনো সার্ভারকে একদিনের জন্য সিঙ্ক না করা হয়, তবে দুটি সার্ভারের ঘড়ির মাঝে প্রায় এক সেকেন্ডের পার্থক্য তৈরি হতে পারে। নেটওয়ার্ক টাইম প্রোটোকল (NTP) নেটওয়ার্কের মাধ্যমে ঘড়ি মেলানোর চেষ্টা করলেও ইন্টারনেটের রুট পরিবর্তন, প্যাকেট ড্রপ ও ল্যাটেন্সির কারণে শতভাগ নিখুঁত সময় পাওয়া অসম্ভব। যদি সার্ভার A সার্ভার B থেকে এমন একটি বার্তা পায় যার টাইমস্ট্যাম্প সার্ভার A-এর ঘড়ির তুলনায় “ভবিষ্যতের”, তবে ডেটাবেসে মারাত্মক ত্রুটি ও ডেটা বিকৃতি ঘটতে পারে।
২. লেসলি ল্যাম্পোর্টের বিপ্লব: হ্যাপেনস-বিফোর সম্পর্ক ($rightarrow$)
১৯৭৮ সালে প্রকাশিত তাঁর যুগান্তকারী গবেষণাপত্র “Time, Clocks, and the Ordering of Events in a Distributed System”-এ কম্পিউটার বিজ্ঞানী লেসলি ল্যাম্পোর্ট বুঝতে পেরেছিলেন যে ডিস্ট্রিবিউটেড সমন্বয়ের জন্য ভৌত সেকেন্ড মাপার প্রয়োজন নেই; প্রয়োজন হলো ঘটনার কার্যকারণ বা কজাল ক্রম (Causal Precedence) নির্ধারণ করা। ল্যাম্পোর্ট তিনটি স্বতঃসিদ্ধের ভিত্তিতে হ্যাপেনস-বিফোর (Happens-Before, $rightarrow$) সম্পর্ক সংজ্ঞায়িত করেন:
- স্থানীয় ক্রম: একই প্রসেসের ভেতর যদি ঘটনা $a$, ঘটনা $b$-এর আগে ঘটে, তবে $a rightarrow b$।
- বার্তা আদান-প্রদান: যদি $a$ হয় কোনো নোড কর্তৃক বার্তা পাঠানোর ঘটনা এবং $b$ হয় অন্য নোডে সেই বার্তা গ্রহণের ঘটনা, তবে $a rightarrow b$।
- সংক্রমণশীলতা (Transitivity): যদি $a rightarrow b$ এবং $b rightarrow c$ হয়, তবে অবশ্যই $a rightarrow c$।
সবচেয়ে গুরুত্বপূর্ণ হলো, যদি $a rightarrow b$ বা $b rightarrow a$ কোনোটিই প্রমাণিত না হয়, তবে সেই ঘটনা দুটিকে গণিতের ভাষায় বলা হয় সমকালীন বা কনকারেন্ট (Concurrent, $a parallel b$)।
৩. ল্যাম্পোর্ট লজিক্যাল ক্লক
ল্যাম্পোর্ট এই কার্যকারণ সম্পর্ককে পূর্ণসংখ্যার স্কেলে রূপান্তর করেন। যদি কোনো ঘটনা $a$-এর লজিক্যাল ক্লক মান $C(a)$ হয়, তবে ক্লক কন্ডিশন হলো:
$$a rightarrow b implies C(a) < C(b)$$
এই শর্ত বজায় রাখতে প্রতিটি প্রসেস দুটি মৌলিক অ্যালগরিদমিক নিয়ম মেনে চলে:
- নিয়ম ১ (অভ্যন্তরীণ ঘটনা): যেকোনো নতুন ঘটনা ঘটার আগে প্রসেস $P_i$ তার স্থানীয় ঘড়ির মান ১ বাড়ায়:
$$C_i leftarrow C_i + 1$$ - নিয়ম ২ (বার্তা আদান-প্রদান): বার্তা পাঠানোর সময় প্রসেস তার বর্তমান ক্লক মান যুক্ত করে দেয়। বার্তা গ্রহণকারী নোড $P_j$ নিজের ঘড়ির মান এবং বার্তার মানের মধ্যে যেটি বড়, তার সাথে ১ যোগ করে আপডেট করে:
$$C_j leftarrow max(C_j, C_m) + 1$$
৪. ভেক্টর ঘড়ির উদ্ভাবন ও নির্ভুল কজাল অর্ডার
ল্যাম্পোর্ট ঘড়ি নিশ্চিত করে যে $a rightarrow b$ হলে $C(a) < C(b)$ হবে। কিন্তু এর বিপরীতটি সত্য নয়! অর্থাৎ $C(a) < C(b)$ দেখেই বলা যায় না যে $a rightarrow b$, কারণ তারা সমকালীন ($a parallel b$) হলেও আকস্মিকভাবে একটির মান কম হতে পারে।
এই সীমাবদ্ধতা দূর করতে ১৯৮৮ সালে কলিন ফিডজ এবং ফ্রিডম্যান ম্যাটার্ন স্বাধীনভাবে উদ্ভাবন করেন ভেক্টর ক্লক (Vector Clocks)। $N$ সংখ্যক প্রসেসের সিস্টেমে প্রতিটি নোড একটি $N$-দৈর্ঘ্যের পূর্ণসংখ্যার ভেক্টর $V = [v_1, v_2, dots, v_N]$ সংরক্ষণ করে।
ভেক্টর ঘড়ির মাধ্যমে অর্জিত হয় ডিস্ট্রিবিউটেড সিস্টেমের অন্যতম মৌলিক নিশ্চয়তা:
$$V(a) < V(b) iff a rightarrow b$$
যদি $V(a) le V(b)$ বা $V(b) le V(a)$ কোনোটিই সত্য না হয়, তবে গাণিতিকভাবে নিশ্চিত হওয়া যায় যে ঘটনা দুটি সমকালীন ($a parallel b$)। অ্যামাজন ডায়নামো এবং আধুনিক ক্লাউড ডেটাবেস এই গাণিতিক ভিত্তির ওপর নির্ভর করেই সমকালীন ডেটা বিরোধ (Conflict Detection) সমাধান করে।