সিঙ্ক্রোনাইজেশনে দ্বন্দ্ব সমাধান হল একটি প্রক্রিয়া যা নেটওয়ার্ক সংযোগ ছাড়া বিভিন্ন ডিভাইসে একযোগে পরিবর্তনের সময় ডেটার সামঞ্জস্যপূর্ণ অবস্থা নির্ধারণ করে। বিতরিত মোবাইল সিস্টেমে, দ্বন্দ্ব দেখা দেয় যখন দুটি ক্লায়েন্ট একই বস্তু অফলাইনে পরিবর্তন করে এবং সংযোগ পুনরুদ্ধারের পর সার্ভার দুটি ভিন্ন সংস্করণ পায়। IEEE ICDCS, 2024 অনুযায়ী, মোবাইল অ্যাপ্লিকেশনে 12% পর্যন্ত প্রতিলিপি সেশনে অন্তত একটি দ্বন্দ্ব থাকে। সমাধানের কৌশল নির্ধারণ করে ডেটার কোন সংস্করণ গ্রহণ করা হবে এবং এটি তথ্যের অখণ্ডতাকে কীভাবে প্রভাবিত করে।
মূল বিষয়
দ্বন্দ্ব সমাধান হল বিরোধপূর্ণ পরিবর্তন শনাক্ত করার পর বিতরিত ডেটাকে একক সামঞ্জস্যপূর্ণ অবস্থায় আনার প্রক্রিয়া। কেন্দ্রীভূত সিস্টেমে, দ্বন্দ্ব দেখা দেয় না: সার্ভার অনুরোধগুলি ক্রমানুসারে প্রক্রিয়া করে। অফলাইন মোডযুক্ত মোবাইল অ্যাপ্লিকেশনে, ক্লায়েন্ট ডেটা স্থানীয়ভাবে পরিবর্তন করে এবং পরে সার্ভারের সাথে সিঙ্ক্রোনাইজ করে। যদি দুটি ক্লায়েন্ট একই বস্তু পরিবর্তন করে, সার্ভার একই শনাক্তকারী কিন্তু ভিন্ন বিষয়বস্তু সহ দুটি সংস্করণ পায়।
শিথিল-যুগ্ম প্রতিলিপিতে (অंतिम সামঞ্জস্য) দ্বন্দ্ব অনিবার্য, যখন সিস্টেম প্রাপ্যতা এবং কর্মক্ষমতার জন্য তাত্ক্ষণিক সামঞ্জস্য বিসর্জন দেয়। প্রিন্সটন বিশ্ববিদ্যালয়ের গবেষকদের (Aggarwal et al., GEO paper, KDD 2024) মতে, বিলম্বিত প্রতিলিপি সহ সিস্টেমগুলি শীর্ষ লোডের অধীনে 28% বেশি কর্মক্ষমতা দেখায় তবে সঠিক ক্রিয়াকলাপের জন্য দ্বন্দ্ব সমাধান প্রক্রিয়া প্রয়োজন।
সমাধানের কৌশল হল একটি অ্যালগরিদম যা সিস্টেম স্বয়ংক্রিয়ভাবে প্রয়োগ করে যখন একটি দ্বন্দ্ব শনাক্ত হয়। বিভিন্ন ডাটাবেস এবং ফ্রেমওয়ার্ক বিভিন্ন কৌশল প্রয়োগ করে: Firebase Realtime Database LWW ব্যবহার করে, CouchDB Merge সমর্থন যোগ করে, এবং Figma এবং Notion তাদের স্থাপত্য CRDT-এর উপর নির্মাণ করে।
দ্বন্দ্বের প্রধান কারণ হল ডেটার স্থানীয় কপি নিয়ে কাজ করা দুই বা ততোধিক ক্লায়েন্ট দ্বারা একই সম্পদের একযোগে পরিবর্তন। একটি সাধারণ পরিস্থিতি: ব্যবহারকারী A Trello-তে অফলাইনে একটি কাজ সম্পাদনা করে, যখন ব্যবহারকারী B অন্য ডিভাইসে একই কাজের বিবরণ পরিবর্তন করে। উভয়ই তাদের সংস্করণ স্থানীয়ভাবে সংরক্ষণ করে। যখন ডিভাইসগুলি নেটওয়ার্কে সংযুক্ত হয়, সার্ভার একই ক্ষেত্রের জন্য দুটি ভিন্ন মান পায়।
অতিরিক্ত কারণগুলির মধ্যে নেটওয়ার্ক বিলম্ব এবং নেটওয়ার্ক বিভাজন অন্তর্ভুক্ত। Raft বা Paxos প্রোটোকল ব্যবহারকারী বিতরিত ডাটাবেসে, দ্বন্দ্ব দেখা দিতে পারে যদি ক্লাস্টার লিডার অস্থায়ীভাবে অনুপলব্ধ থাকে এবং অনুরোধগুলি বিভিন্ন নোড দ্বারা প্রক্রিয়া করা হয়। Amazon DynamoDB শ্বেতপত্র (2025) অনুযায়ী, স্কেলযোগ্য NoSQL সিস্টেমে প্রায় 0.3% লেখা অপারেশন শনাক্তযোগ্য দ্বন্দ্বের কারণ হয়।
ভুল ডেটা কাঠামোর কারণেও দ্বন্দ্ব দেখা দেয়। যদি কোনো অ্যাপ্লিকেশন অপারেশন কাউন্টার বা অংশগ্রহণকারী তালিকা সংরক্ষণ করে, দুটি অফলাইন ক্লায়েন্ট এমন অপারেশন করতে পারে যা ক্রমিকভাবে অসামঞ্জস্যপূর্ণ। উদাহরণস্বরূপ, ক্লায়েন্ট A একটি তালিকার শেষে একটি আইটেম যোগ করে, যখন ক্লায়েন্ট B মাঝ থেকে একটি আইটেম সরিয়ে ফেলে — সিঙ্ক্রোনাইজেশনের সময়, সার্ভার জানে না কোন কাজটি প্রথমে প্রয়োগ করতে হবে।
Last Write Wins (LWW) হল একটি কৌশল যেখানে প্রতিযোগী সংস্করণগুলির মধ্যে সর্বশেষ টাইমস্ট্যাম্পযুক্ত এন্ট্রি নির্বাচন করা হয়। সিস্টেম প্রতিটি সংস্করণের টাইমস্ট্যাম্প তুলনা করে এবং নতুনটি গ্রহণ করে, পুরানোটিকে বাতিল করে। এটি একটি নিয়তিবাদী প্রক্রিয়া: টাইমস্ট্যাম্পের একই সেটের সাথে, ফলাফল সর্বদা একই হয়, অনিশ্চয়তা দূর করে। LWW Firebase Realtime Database, Apache Cassandra এবং Riak KV-তে বাস্তবায়িত হয়েছে।
মোবাইল অ্যাপ্লিকেশনে, LWW তার সরল বাস্তবায়নের কারণে বিশেষভাবে আকর্ষণীয়। ক্লায়েন্টের সংস্করণগুলির মধ্যে পার্থক্য বিশ্লেষণ করার, পরিবর্তন ইতিহাস সংরক্ষণ করার বা ব্যবহারকারীকে নির্বাচন ডায়ালগ দেখানোর প্রয়োজন নেই। সার্ভার মিলিসেকেন্ডে সিদ্ধান্ত নেয়। তবে, LWW-এর একটি মৌলিক ত্রুটি রয়েছে — ডেটা ক্ষতি। যদি দুটি ব্যবহারকারী একসঙ্গে একটি ফর্মের বিভিন্ন ক্ষেত্র পূরণ করে, একটি সংস্করণ সম্পূর্ণরূপে বাতিল হয়ে যাবে।
REST API-র মাধ্যমে সিঙ্ক্রোনাইজেশন সহ মোবাইল নোট-লেখার অ্যাপে LWW কার্যক্রমের উদাহরণ:
data class Note(
val id: String,
val title: String,
val content: String,
val updatedAt: Long
)
fun resolveWithLWW(
local: Note,
remote: Note
): Note {
return if (local.updatedAt >= remote.updatedAt) local
else remote
}
resolveWithLWW ফাংশন টাইমস্ট্যাম্প তুলনা করে এবং বর্তমান সংস্করণ ফেরত দেয়। যখন টাইমস্ট্যাম্প সমান হয় (যা উচ্চ লেখার ফ্রিকোয়েন্সিতে ঘটে), সাধারণত স্থানীয় সংস্করণ জয়ী হয়।
Merge Strategy হল একটি পদ্ধতি যেখানে সিস্টেম কোনো একটি সংস্করণ সম্পূর্ণরূপে বাতিল করে না বরং উভয়ের পরিবর্তনগুলিকে একটি সামঞ্জস্যপূর্ণ অবস্থায় একত্রিত করার চেষ্টা করে। এটি Git-এ শাখা একীভূত করার অনুরূপ: প্রতিটি দ্বন্দ্ব পৃথক ক্ষেত্র বা অপারেশনের স্তরে সমাধান করা হয়। একীকরণ কৌশলগুলি স্বয়ংক্রিয় (CRDT, OT) এবং ম্যানুয়াল (ব্যবহারকারী বিকল্প নির্বাচন করে) এ বিভক্ত।
সবচেয়ে পরিচিত বাস্তবায়ন হল তিন-মুখী একীকরণ (three-way merge)। সিস্টেম তিনটি সংস্করণ সংরক্ষণ করে: স্থানীয়, দূরবর্তী এবং তাদের সাধারণ পূর্বপুরুষ (বিচ্যুতির আগের ভিত্তি সংস্করণ)। যদি শুধুমাত্র একজন ক্লায়েন্ট কোনো ক্ষেত্র পরিবর্তন করে, সেই পরিবর্তন স্বয়ংক্রিয়ভাবে গৃহীত হয়। যদি উভয় ক্লায়েন্ট একই ক্ষেত্র পরিবর্তন করে — একটি দ্বন্দ্ব রেকর্ড করা হয় যার সমাধান প্রয়োজন। CouchDB এবং PouchDB নথি সিঙ্ক্রোনাইজেশনের জন্য এই মডেল সক্রিয়ভাবে ব্যবহার করে।
ব্যবহারকারী প্রোফাইলের জন্য তিন-মুখী একীকরণ বাস্তবায়নের উদাহরণ:
data class Profile(
val name: String,
val email: String,
val avatarUrl: String
)
fun threeWayMerge(
base: Profile,
local: Profile,
remote: Profile
): Profile {
return Profile(
name = if (local.name != base.name) local.name
else remote.name,
email = if (local.email != base.email) local.email
else remote.email,
avatarUrl = if (remote.avatarUrl != base.avatarUrl) remote.avatarUrl
else local.avatarUrl
)
}
তিন-মুখী একীকরণ কার্যকর যখন ডেটা কাঠামো যথেষ্ট স্থিতিশীল। ক্ষেত্রের নাম পরিবর্তন, প্রকার পরিবর্তন এবং অ্যারে অপারেশন করার সময় সমস্যা দেখা দেয় — এই ক্ষেত্রে, আরও জটিল যুক্তির প্রয়োজন হয়।
CRDT (Conflict-Free Replicated Data Type) হল একটি গাণিতিক মডেল যা কেন্দ্রীয় সমন্বয়ক ছাড়া ডেটা অভিসারের গ্যারান্টি দেয়। CRDT এমনভাবে ডিজাইন করা হয়েছে যে সমস্ত অপারেশন বিনিময়যোগ্য: প্রয়োগের ক্রম চূড়ান্ত ফলাফলকে প্রভাবিত করে না। এটি বীজগাণিতিক বৈশিষ্ট্যের মাধ্যমে অর্জিত হয়: CRDT-এর একীকরণ পরিবর্তন গ্রহণের ক্রম নির্বিশেষে সর্বদা একই ফলাফল দেয়।
CRDT-এর প্রধান প্রকারগুলির মধ্যে রয়েছে G-Counter (শুধুমাত্র বৃদ্ধি সমর্থনকারী কাউন্টার), PN-Counter (বৃদ্ধি এবং হ্রাসসহ কাউন্টার), LWW-Register (সংস্করণসহ রেজিস্টার) এবং OR-Set (যোগ এবং অপসারণ ট্র্যাকিংসহ সেট)। প্রতিটি প্রকার গ্যারান্টি দেয় যে দুটি প্রতিলিপির একীকরণ দ্বন্দ্ব তৈরি করবে না। INRIA গবেষণা (Marc Shapiro et al., 2024) অনুযায়ী, CRDT 95% সাধারণ ডেটা প্রকারের জন্য নিয়তিবাদী অভিসার প্রদান করে।
G-Counter-এর উদাহরণ — একটি কাউন্টার যা শুধুমাত্র বাড়ানো যেতে পারে:
class GCounter {
private val counts = mutableMapOf<String, Int>()
fun increment(nodeId: String) {
counts[nodeId] = (counts[nodeId] ?: 0) + 1
}
fun value(): Int = counts.values.sum()
fun merge(other: GCounter) {
other.counts.forEach { (node, count) ->
counts[node] = maxOf(counts[node] ?: 0, count)
}
}
}
GCounter সঠিক একীকরণের গ্যারান্টি দেয় কারণ প্রতিটি নোড শুধুমাত্র নিজস্ব কাউন্টার সংরক্ষণ করে, এবং একীকরণ প্রতি নোড সর্বোচ্চ নেয়। এটি বিকেন্দ্রীভূত সিস্টেমে ব্যবহৃত দ্বন্দ্ব-মুক্ত কাঠামোর একটি চমৎকার উদাহরণ।
কৌশল নির্বাচন ডেটার প্রকৃতি এবং ব্যবহারের পরিস্থিতির উপর নির্ভর করে। LWW সেই অ্যাপ্লিকেশনের জন্য সর্বোত্তম যেখানে সর্বশেষ সংস্করণ সর্বদা অগ্রাধিকার পায় — সংবাদ ফিড, বিজ্ঞপ্তি, অবস্থা। Merge Strategy কাঠামোবদ্ধ নথির জন্য উপযুক্ত যেখানে প্রতিটি ক্ষেত্র স্বাধীন — ব্যবহারকারী প্রোফাইল, ফর্ম, কনফিগারেশন। CRDT বিতরিত সিস্টেমে সহযোগিতামূলক সম্পাদনা, তালিকা এবং কাউন্টারের জন্য আদর্শ।
কৌশল নির্বাচন করার সময়, তিনটি বিষয় মূল্যায়ন করা হয়: ডেটা সামঞ্জস্য, কর্মক্ষমতা এবং বাস্তবায়নের জটিলতা। LWW সর্বোচ্চ কর্মক্ষমতা এবং ন্যূনতম জটিলতা প্রদান করে তবে ডেটা হারাতে পারে। Merge উচ্চ নির্ভুলতা প্রদান করে তবে ক্ষেত্র স্তরে পরিবর্তন শনাক্ত করার প্রক্রিয়া প্রয়োজন। CRDT গাণিতিক শুদ্ধতা নিশ্চিত করে তবে ডেটা প্রকার এবং মেটাডেটা আকারের উপর সীমাবদ্ধতা আরোপ করে।
| কৌশল | ডেটা ক্ষতি | জটিলতা | কর্মক্ষমতা | ব্যবহারের ক্ষেত্র |
|---|---|---|---|---|
| LWW | সম্ভব | কম | উচ্চ | সংবাদ ফিড, অবস্থা |
| Merge | সর্বনিম্ন | মধ্যম | মধ্যম | প্রোফাইল, নথি |
| CRDT | না | উচ্চ | মধ্যম-উচ্চ | সহযোগিতামূলক সম্পাদনা |
ব্যবহারিক ক্ষেত্রে, প্রায়শই একটি সম্মিলিত পদ্ধতি ব্যবহৃত হয়: সিস্টেমগুলি মেটাডেটার জন্য LWW, নথির বিষয়বস্তুর জন্য Merge এবং তালিকা কাঠামোর জন্য CRDT ব্যবহার করে। Firebase Firestore, উদাহরণস্বরূপ, উচ্চ-স্তরের ক্ষেত্রের জন্য LWW প্রয়োগ করে এবং পারমাণবিক আপডেটের জন্য লেনদেন সমর্থন করে। CouchDB পরিবর্তন ইতিহাস সংরক্ষণের সাথে Merge ব্যবহার করে। Figma এবং Notion রিয়েল-টাইমে বহু-ব্যবহারকারী সম্পাদনার জন্য CRDT-এর উপর তাদের স্থাপত্য নির্মাণ করে।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
দ্বন্দ্ব সমাধান হল একটি প্রক্রিয়া যা নির্ধারণ করে একই বস্তু বিভিন্ন ডিভাইসে একযোগে পরিবর্তন করা হলে ডেটার কোন সংস্করণ সঠিক বলে বিবেচিত হয়। সিস্টেম সংস্করণ নির্বাচন বা একীভূত করার জন্য একটি কৌশল (LWW, Merge, CRDT) প্রয়োগ করে।
LWW টাইমস্ট্যাম্প দ্বারা একটি সম্পূর্ণ সংস্করণ নির্বাচন করে, অন্যটি বাতিল হয়। Merge উভয় সংস্করণের পরিবর্তনগুলিকে পৃথক ক্ষেত্র স্তরে একত্রিত করে, ডেটা ক্ষতি কমিয়ে আনে কিন্তু আরও জটিল বাস্তবায়ন এবং ভিত্তি সংস্করণ সংরক্ষণের প্রয়োজন হয়।
CRDT সেই পরিস্থিতির জন্য নির্বাচিত হয় যেখানে ডেটা ক্ষতি অগ্রহণযোগ্য: সহযোগিতামূলক সম্পাদনা, আর্থিক লেনদেন, কাজের তালিকা। LWW অ-গুরুত্বপূর্ণ ডেটার জন্য যথেষ্ট — অবস্থা, সংবাদ ফিড, ক্যাশে, যেখানে সর্বশেষ সংস্করণ বস্তুনিষ্ঠভাবে সঠিক।
ভুল দ্বন্দ্ব সমাধান ব্যবহারকারীর ডেটা হারানোর কারণ হয়, যা নেতিবাচক পর্যালোচনা এবং ব্যবহারকারী ক্ষতির দিকে নিয়ে যায়। ওয়াশিংটন বিশ্ববিদ্যালয়ের একটি গবেষণা (2025) অনুযায়ী, 67% ব্যবহারকারী সিঙ্ক্রোনাইজেশন দ্বন্দ্বের কারণে তথ্য হারানোর দুটি ঘটনার পর অ্যাপ্লিকেশন ব্যবহার বন্ধ করে দেয়।
CouchDB এবং PouchDB-তে নথির তিন-মুখী একীকরণের জন্য অন্তর্নির্মিত সমর্থন রয়েছে। Firebase Firestore পারমাণবিক আপডেটের জন্য লেনদেন সমর্থন করে। RethinkDB এবং MongoDB-তে সংস্করণসহ আশাবাদী লকিং প্যাটার্নের মাধ্যমে অ্যাপ্লিকেশন স্তরে বাস্তবায়ন প্রয়োজন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন