क्लाइंट-सर्वर सिंक्रनाइज़ेशन पैटर्न / एल्गोरिदम?


224

मुझे लगता है कि वहाँ क्लाइंट-सर्वर सिंक्रनाइज़ेशन पैटर्न होना चाहिए। लेकिन मैं पूरी तरह से एक को गूगल करने में विफल रहा।

स्थिति काफी सरल है - सर्वर केंद्रीय नोड है, जो कई क्लाइंट एक ही डेटा से कनेक्ट और हेरफेर करते हैं। डेटा को परमाणुओं में विभाजित किया जा सकता है, संघर्ष के मामले में, जो कुछ भी सर्वर पर है, प्राथमिकता है (उपयोगकर्ता को संघर्ष समाधान में शामिल होने से बचने के लिए)। संभावित बड़ी मात्रा में डेटा के कारण आंशिक सिंक्रनाइज़ेशन को प्राथमिकता दी जाती है।

क्या ऐसी स्थिति के लिए कोई पैटर्न / अच्छी प्रथाएं हैं, या यदि आपको किसी के बारे में पता नहीं है - तो आपका दृष्टिकोण क्या होगा?

नीचे बताया गया है कि अब मैं इसे कैसे हल कर सकता हूं: डेटा के समानांतर, एक संशोधन पत्रिका आयोजित की जाएगी, जिसमें सभी लेनदेन टाइमस्टैम्प किए जाएंगे। जब क्लाइंट कनेक्ट होता है, तो यह पिछले चेक के बाद से सभी परिवर्तनों को प्राप्त करता है, समेकित रूप में (सर्वर सूचियों के माध्यम से जाता है और हटाए जाने के बाद आने वाले परिवर्धन को हटाता है, प्रत्येक परमाणु के लिए अपडेट को मर्ज करता है, आदि)। वेटिला, हम अप टू डेट हैं।

वैकल्पिक प्रत्येक रिकॉर्ड के लिए संशोधन तिथि रखेगा, और डेटा डिलीट करने के बजाय, उन्हें हटाए गए के रूप में चिह्नित करेगा।

कोई विचार?


27
सहमत इस तरह की चीज़ों के लिए बहुत कम पैटर्न की बात की गई है ... भले ही यह परिदृश्य बहुत सामान्य है
जैक उलेजा

जवाबों:


88

आपको यह देखना चाहिए कि वितरण प्रबंधन कैसे वितरित करता है। एसवीएन, सीवीएस और अन्य रिपोजिटरी को देखें जो डेल्टास के काम का प्रबंधन करते हैं।

आपके पास कई उपयोग के मामले हैं।

  • परिवर्तन सिंक्रनाइज़ करें। आपका परिवर्तन-लॉग (या डेल्टा इतिहास) दृष्टिकोण इसके लिए अच्छा लगता है। ग्राहक अपने डेल्टास को सर्वर पर भेजते हैं; सर्वर ग्राहकों को डेल्टास को समेकित और वितरित करता है। यह विशिष्ट मामला है। डेटाबेस इसे "लेनदेन प्रतिकृति" कहते हैं।

  • क्लाइंट ने सिंक्रनाइज़ेशन खो दिया है। या तो बैकअप / रिस्टोर के माध्यम से या बग के कारण। इस मामले में, क्लाइंट को डेल्टास के माध्यम से जाने के बिना सर्वर से वर्तमान स्थिति प्राप्त करने की आवश्यकता है। यह मास्टर से डिटेल, डेल्टास और परफॉर्मेंस को डैमेज करने की कॉपी है। यह एक बार की बात है; ग्राहक टूट गया है; इसे अनुकूलित करने का प्रयास न करें, बस एक विश्वसनीय प्रतिलिपि लागू करें।

  • ग्राहक संदिग्ध है। इस मामले में, आपको यह निर्धारित करने के लिए क्लाइंट के साथ सर्वर की तुलना करने की आवश्यकता है कि क्या क्लाइंट अप-टू-डेट है और किसी भी डेल्टा की आवश्यकता है।

आपको क्रमिक रूप से प्रत्येक परिवर्तन के क्रमांकन के डेटाबेस (और SVN) डिज़ाइन पैटर्न का पालन करना चाहिए। इस तरह से एक ग्राहक एक तुच्छ अनुरोध कर सकता है ("मुझे क्या संशोधन करना चाहिए?") सिंक्रनाइज़ करने का प्रयास करने से पहले। और फिर भी, क्वेरी ("2149 के बाद से सभी डेल्टा") ग्राहक और सर्वर के लिए प्रक्रिया के लिए खुशी से सरल है।


क्या आप बता सकते हैं कि एक डेल्टा वास्तव में क्या है? मेरा अनुमान है कि यह एक हैश / टाइमस्टैम्प संयोजन होगा ... मैं यू सर से सुनना चाहूंगा।
अनीस

एक डेल्टा दो संशोधनों के बीच परिवर्तन को संदर्भित करता है। उदाहरण के लिए, यदि किसी उपयोगकर्ता का नाम बदल गया है, तो डेल्टा कुछ हो सकता है जैसे {पुनरीक्षण: 123, नाम: "जॉन डो"}
dipole_moment

31

टीम के हिस्से के रूप में, मैंने काफी परियोजनाएँ कीं जिनमें डेटा सिंकिंग शामिल थी, इसलिए मुझे इस प्रश्न का उत्तर देने के लिए सक्षम होना चाहिए।

डेटा सिंकिंग काफी व्यापक अवधारणा है और चर्चा करने के लिए बहुत अधिक तरीके हैं। यह उनके अपसाइड और डाउनसाइड के साथ विभिन्न तरीकों की एक श्रृंखला को कवर करता है। यहाँ दो दृष्टिकोणों के आधार पर संभावित वर्गीकरणों में से एक है: सिंक्रोनस / एसिंक्रोनस, क्लाइंट / सर्वर / पीयर-टू-पीयर। सिंकिंग कार्यान्वयन गंभीर रूप से इन कारकों, डेटा मॉडल जटिलता, हस्तांतरित और संग्रहीत डेटा की मात्रा और अन्य आवश्यकताओं पर निर्भर करता है। इसलिए प्रत्येक विशेष मामले में चुनाव एप्लिकेशन की आवश्यकताओं को पूरा करते हुए सबसे सरल कार्यान्वयन के पक्ष में होना चाहिए।

मौजूदा ऑफ-द-शेल्फ समाधानों की समीक्षा के आधार पर, हम सिंक्रनाइज़ेशन के कई प्रमुख वर्गों को अलग कर सकते हैं, जो सिंक्रनाइज़ेशन के अधीन वस्तुओं की विभिन्नता में भिन्न होते हैं:

  • एक संपूर्ण दस्तावेज़ या डेटाबेस का सिंक्रनाइज़ेशन क्लाउड-आधारित अनुप्रयोगों में उपयोग किया जाता है, जैसे ड्रॉपबॉक्स, Google ड्राइव या Yandex.Disk। जब उपयोगकर्ता एक फ़ाइल को संपादित और सहेजता है, तो नया फ़ाइल संस्करण पूरी तरह से क्लाउड पर अपलोड किया जाता है, जो पहले की प्रतिलिपि को अधिलेखित करता है। संघर्ष के मामले में, दोनों फ़ाइल संस्करण सहेजे जाते हैं ताकि उपयोगकर्ता यह चुन सके कि कौन सा संस्करण अधिक प्रासंगिक है।
  • की-वैल्यू पेयर का सिंकिंग एक साधारण डेटा संरचना वाले ऐप्स में इस्तेमाल किया जा सकता है, जहाँ चर को परमाणु माना जाता है, अर्थात तार्किक घटकों में विभाजित नहीं किया जाता है। यह विकल्प पूरे दस्तावेजों के समन्वय के समान है, क्योंकि मूल्य और दस्तावेज़ दोनों को पूरी तरह से अधिलेखित किया जा सकता है। हालाँकि, उपयोगकर्ता के दृष्टिकोण से एक दस्तावेज़ कई भागों से बना एक जटिल वस्तु है, लेकिन एक कुंजी-मूल्य जोड़ी है, लेकिन एक छोटी स्ट्रिंग या एक संख्या है। इसलिए, इस मामले में हम संघर्ष के समाधान की अधिक सरल रणनीति का उपयोग कर सकते हैं, मूल्य को और अधिक प्रासंगिक मानते हुए, अगर यह बदलने के लिए अंतिम हो गया है।
  • पेड़ या ग्राफ़ के रूप में संरचित डेटा का सिंक्रनाइज़ेशन अधिक परिष्कृत अनुप्रयोगों में उपयोग किया जाता है जहां डेटा की मात्रा हर अपडेट में डेटाबेस को उसकी संपूर्णता में भेजने के लिए पर्याप्त होती है। इस मामले में, संघर्षों को व्यक्तिगत वस्तुओं, क्षेत्रों या रिश्तों के स्तर पर हल करना होगा। हम मुख्य रूप से इस विकल्प पर केंद्रित हैं।

इसलिए, हमने अपने ज्ञान को इस लेख में पकड़ा है, जो मुझे लगता है कि इस विषय में रुचि रखने वाले सभी के लिए बहुत उपयोगी हो सकता है => कोर डेटा आधारित iOS ऐप्स में डेटा सिंकिंग ( http://blog.denivip.ru/index.php/2014/04 / data-syncing-in-core-data-based-ios-apps /? lang = en )


3
^ ^ ^ ^ ^ ^ ^ ^ ^ यह अब तक का सबसे अच्छा जवाब है, दोस्तों!
14 फरवरी को hgoebl

मैं सहमत हूं, डेनिस विषय में बहुत कुछ लाया + लेख लिंक भयानक है। इसके अलावा डेनियलपॉल द्वारा उल्लिखित ओटी के बारे में बात करता है। एस.लॉट द्वारा उत्तर अच्छा है लेकिन यह गहराई में अधिक है।
क्रिस्टियन

28

आपको वास्तव में क्या चाहिए ऑपरेशनल ट्रांसफ़ॉर्म (OT)। यह भी कई मामलों में संघर्ष के लिए पूरा कर सकते हैं।

यह अभी भी अनुसंधान का एक सक्रिय क्षेत्र है, लेकिन आस-पास विभिन्न ओटी एल्गोरिदम के कार्यान्वयन हैं। मैं इस तरह के शोध में कई वर्षों से शामिल हूं, इसलिए मुझे बताएं कि क्या यह मार्ग आपको रुचिकर लगता है और मुझे आपको प्रासंगिक संसाधनों पर रखना अच्छा लगेगा।


7
डैनियल, प्रासंगिक संसाधनों के लिए एक संकेतक की सराहना की जाएगी।
परांद

4
मैं अभी विकिपीडिया लेख को फिर से पढ़ता हूं। यह एक लंबा रास्ता तय कर चुका है और उस पृष्ठ के निचले भाग में कई प्रासंगिक संदर्भ हैं। मैंने आपको चेंग्झेंग सन के काम की ओर इशारा किया होगा - उनका काम विकिपीडिया से संदर्भित है। en.wikipedia.org/wiki/Operational_transformation । उम्मीद है की वो मदद करदे!
डैनियल पॉल

13

सवाल क्रिस्टल क्लियर नहीं है, लेकिन मैं आशावादी ताला लगाऊंगा कि अगर मैं तुम होता। यह एक अनुक्रम संख्या के साथ लागू किया जा सकता है जो सर्वर प्रत्येक रिकॉर्ड के लिए वापस आ जाता है। जब कोई ग्राहक रिकॉर्ड वापस लेने की कोशिश करता है, तो इसमें सर्वर से प्राप्त अनुक्रम संख्या शामिल होगी। यदि अनुक्रम संख्या उस समय से मेल खाती है जो अद्यतन प्राप्त होने के समय डेटाबेस में है, तो अद्यतन की अनुमति है और अनुक्रम संख्या में वृद्धि हुई है। यदि क्रम संख्याएं मेल नहीं खातीं, तो अपडेट अस्वीकृत है।


2
अनुक्रम संख्या यहाँ आपके मित्र हैं। लगातार संदेश कतारों के बारे में सोचें।
डैनियल पौल

7

मैंने लगभग 8 साल पहले एक ऐप के लिए इस तरह की एक प्रणाली बनाई थी, और मैं कुछ तरीके साझा कर सकता हूं जो कि विकसित हो गए हैं जैसे कि ऐप का उपयोग बढ़ा है।

मैंने किसी भी डिवाइस से "इतिहास" तालिका में हर परिवर्तन (सम्मिलित करें, अपडेट या हटाएं) को लॉग इन करके शुरू किया। इसलिए, यदि, उदाहरण के लिए, कोई व्यक्ति "संपर्क" तालिका में अपना फोन नंबर बदलता है, तो सिस्टम contact.phone फ़ील्ड को संपादित करेगा, और एक्शन = अपडेट, फ़ील्ड = फोन, रिकॉर्ड = [संपर्क आईडी] के साथ एक इतिहास रिकॉर्ड भी जोड़ देगा, मूल्य = [नया फोन नंबर]। फिर जब भी कोई डिवाइस सिंक करता है, तो वह आखिरी सिंक के बाद से हिस्ट्री आइटम को डाउनलोड करता है और उन्हें अपने स्थानीय डेटाबेस पर लागू करता है। यह ऊपर वर्णित "लेनदेन प्रतिकृति" पैटर्न की तरह लगता है।

एक मुद्दा आईडी को विशिष्ट बनाए रखना है, जब विभिन्न उपकरणों पर आइटम बनाए जा सकते हैं। जब मैंने इसे शुरू किया था तो मुझे यूयूआईडी के बारे में पता नहीं था, इसलिए मैंने ऑटो-इन्क्रिमेंटिंग आईडी का उपयोग किया और कुछ जटिल कोड लिखे, जो उपकरणों से अपलोड की गई नई आईडी की जांच करने के लिए केंद्रीय सर्वर पर चलता है, यदि कोई विरोधाभास है, तो उन्हें एक अद्वितीय आईडी में बदल दें। अपने स्थानीय डेटाबेस में आईडी को बदलने के लिए स्रोत डिवाइस बताएं। बस नए रिकॉर्ड की आईडी बदलना इतना बुरा नहीं था, लेकिन अगर मैं बनाता हूं, उदाहरण के लिए, संपर्क तालिका में एक नया आइटम, तो घटना तालिका में एक नया संबंधित आइटम बनाएं, अब मेरे पास विदेशी चाबियाँ हैं जो मुझे भी चाहिए जाँच करें और अद्यतन करें।

आखिरकार मुझे पता चला कि यूयूआईडी इससे बच सकते हैं, लेकिन तब तक मेरा डेटाबेस बहुत बड़ा हो रहा था और मुझे डर था कि एक पूर्ण यूयूआईडी कार्यान्वयन एक प्रदर्शन समस्या पैदा करेगा। इसलिए पूर्ण यूयूआईडी का उपयोग करने के बजाय, मैंने आईडी के रूप में बेतरतीब ढंग से उत्पन्न, 8 वर्ण अल्फ़ान्यूमेरिक कुंजियों का उपयोग करना शुरू कर दिया और संघर्षों को संभालने के लिए मैंने अपना मौजूदा कोड छोड़ दिया। मेरी वर्तमान 8-वर्ण कुंजियों और UUID के 36 वर्णों के बीच कहीं एक ऐसा मधुर स्थान होना चाहिए जो अनावश्यक रूप से प्रस्फुटित हुए बिना संघर्षों को समाप्त कर दे, लेकिन चूँकि मेरे पास पहले से ही संघर्ष समाधान कोड है, इसलिए इसका प्रयोग करना प्राथमिकता नहीं है। ।

अगली समस्या यह थी कि हिस्ट्री टेबल पूरे बाकी डेटाबेस से लगभग 10 गुना बड़ी थी। यह भंडारण को महंगा बनाता है, और इतिहास की मेज पर कोई रखरखाव दर्दनाक हो सकता है। उस पूरी तालिका को रखने से उपयोगकर्ता किसी भी पिछले परिवर्तन को वापस ले सकते हैं, लेकिन यह ओवरकिल की तरह लगने लगा। इसलिए मैंने एक समन्वयन प्रक्रिया में एक रूटीन जोड़ा जहां अगर इतिहास आइटम जिसे अंतिम रूप से डाउनलोड किया गया डिवाइस अब इतिहास तालिका में मौजूद नहीं है, तो सर्वर इसे हाल के इतिहास आइटम नहीं देता है, बल्कि इसके लिए एक फ़ाइल देता है जिसमें सभी डेटा होते हैं वह खाता। फिर मैंने 90 दिनों से अधिक पुराने इतिहास के आइटम को हटाने के लिए एक क्रोनजॉब जोड़ा। इसका मतलब है कि उपयोगकर्ता अभी भी 90 दिनों से कम पुराने परिवर्तनों को वापस ले सकते हैं, और यदि वे हर 90 दिनों में कम से कम एक बार सिंक करते हैं, तो अपडेट पहले की तरह ही वृद्धिशील होंगे। लेकिन अगर वे 90 दिनों से अधिक समय तक प्रतीक्षा करें,

उस परिवर्तन ने इतिहास तालिका का आकार लगभग 90% कम कर दिया है, इसलिए अब इतिहास तालिका बनाए रखने से डेटाबेस केवल दस गुना बड़ा होने के बजाय दोगुना हो जाता है। इस प्रणाली का एक अन्य लाभ यह है कि यदि आवश्यक हो तो सिंक्रनाइज़ेशन अभी भी इतिहास तालिका के बिना काम कर सकता है - जैसे कि अगर मुझे कुछ रखरखाव करने की आवश्यकता थी जो इसे अस्थायी रूप से ले गया। या मैं अलग-अलग मूल्य बिंदुओं पर खातों के लिए अलग-अलग रोलबैक समय अवधि की पेशकश कर सकता हूं। और अगर डाउनलोड करने के लिए 90 दिनों से अधिक के परिवर्तन हैं, तो पूर्ण फ़ाइल आमतौर पर वृद्धिशील प्रारूप की तुलना में अधिक कुशल है।

अगर मैं आज से शुरू कर रहा था, तो मैं आईडी संघर्ष जाँच को छोड़ दूंगा और सिर्फ एक प्रमुख लंबाई के लिए लक्ष्य रखूँगा जो कि संघर्ष को खत्म करने के लिए पर्याप्त है, किसी प्रकार की त्रुटि की जाँच के लिए। लेकिन इतिहास तालिका और हाल के अपडेट के लिए वृद्धिशील डाउनलोडों का संयोजन या जरूरत पड़ने पर एक पूर्ण डाउनलोड अच्छी तरह से काम कर रहा है।


1

डेल्टा (परिवर्तन) सिंक के लिए, आप सभी सब्सक्राइब किए गए क्लाइंट में परिवर्तन प्रकाशित करने के लिए पबसब पैटर्न का उपयोग कर सकते हैं, पुशर जैसी सेवाएं ऐसा कर सकती हैं।

डेटाबेस मिरर के लिए, कुछ वेब फ्रेमवर्क स्थानीय डेटाबेस को ब्राउजर डेटाबेस में सर्वर साइड डेटाबेस को स्थानीय से सिंक करने के लिए उपयोग करते हैं, आंशिक सिंक्रनाइज़ेशन समर्थित है। मीटर की जाँच करें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.