समस्या और लागू होने वाले परिदृश्य
एक रियल-टाइम कोलैबोरेटिव एडिटर डिज़ाइन करें जो पैराग्राफ, हेडिंग, लिस्ट, बोल्ड टेक्स्ट और कमेंट एंकर का समर्थन करता हो। सिस्टम में 2 करोड़ (20 million) दैनिक सक्रिय उपयोगकर्ता हैं और पीक पर 20 लाख (2 million) कनेक्शन्स बनाए रखता है, जिसमें 200,000 उपयोगकर्ता सक्रिय रूप से टाइप कर रहे हैं। एक सक्रिय संपादक औसतन प्रति सेकंड दो अपडेट उत्पन्न करता है, और एक हॉट डॉक्यूमेंट में 100 समवर्ती संपादक हो सकते हैं। ऑनलाइन सहयोगियों को p95 पर 200 मिलीसेकंड के भीतर एक रिमोट एडिट दिखना चाहिए। एक उपयोगकर्ता 24 घंटे तक ऑफ़लाइन संपादन कर सकता है और पुनः कनेक्ट होने के बाद मर्ज कर सकता है। सर्वर द्वारा एक्नॉलेज किया गया एडिट खोना नहीं चाहिए। कर्सर, चयन (selections) और ऑनलाइन स्थिति थोड़ी देर के लिए खो सकते हैं।
सिस्टम viewer, commenter और editor अनुमतियों, अनुमति परिवर्तनों, वर्ज़न हिस्ट्री, प्रति-उपयोगकर्ता undo और मल्टी-रीजन एक्सेस का भी समर्थन करता है। इंटरव्यू में शुरुआत से CRDT या OT एल्गोरिदम साबित करने या किसी कंपनी के निजी आर्किटेक्चर को पुनरुत्पादित करने की आवश्यकता नहीं है। उम्मीदवार को एक कॉन्फ़्लिक्ट-रिज़ॉल्यूशन मॉडल चुनना चाहिए, इसे एडिटर डेटा स्ट्रक्चर, ट्रांसपोर्ट, पर्सिस्टेंस और ऑथराइजेशन सीमाओं से जोड़ना चाहिए, और यह बताना चाहिए कि डिज़ाइन क्या गारंटी नहीं दे सकता है।
2026 की वर्तमान अंग्रेज़ी और चीनी इंटरव्यू सामग्री कोलैबोरेटिव एडिटिंग को OT बनाम CRDT, WebSocket कनेक्शन्स, डॉक्यूमेंट रूम्स, कर्सर प्रेजेंस, ऑफ़लाइन एडिटिंग, ड्यूरेबल अपडेट्स और स्नैपशॉट रिकवरी तक फैली एक सिस्टम डिज़ाइन समस्या के रूप में प्रस्तुत करती है। Yjs दस्तावेज़ीकरण कम्यूटेटिव, एसोसिएटिव और आइडेम्पोटेंट अपडेट्स, स्टेट-वेक्टर डेल्टा सिंक और गैर-स्थायी (non-persistent) अवेयरनेस के लिए प्राथमिक प्रमाण प्रदान करता है। यह संयोजन प्रॉम्प्ट को प्रतिनिधि और तकनीकी रूप से सत्यापन योग्य बनाता है।
इंटरव्यूअर क्या मूल्यांकन कर रहा है
पहला, क्या उम्मीदवार "WebSockets का उपयोग करें" पर रुकने के बजाय समवर्ती कन्वर्जेंस (concurrent convergence) को हल करता है? WebSocket एक द्विदिशात्मक (bidirectional) चैनल प्रदान करता है। जब दो उपयोगकर्ता एक ही स्थिति में इन्सर्ट करते हैं तो यह परिणाम तय नहीं करता है। एक मजबूत उत्तर सर्वर-मध्यस्थता वाले OT मॉडल की CRDT मॉडल से तुलना करता है और बताई गई बाधाओं के लिए एक को चुनता है।
दूसरा, क्या उत्तर सर्वर के ड्यूरेबिलिटी वादे से लोकल अनुभव को अलग करता है? नेटवर्क राउंड ट्रिप से पहले टाइपिंग को स्थानीय रूप से लागू होना चाहिए। "एक्नॉलेज्ड का मतलब खोया नहीं" के लिए आवश्यक है कि सर्वर ack लौटाने से पहले उपलब्धता क्षेत्रों (availability zones) में एक अपडेट को ड्यूरेबल रूप से रेप्लिकेट करे। तब तक, क्लाइंट अपडेट को एक पेंडिंग कतार में रखता है और उसी ऑपरेशन पहचान (operation identity) के साथ पुनः प्रयास करता है।
तीसरा, क्या डिज़ाइन ड्यूरेबल कंटेंट को एफेमरल प्रेजेंस से अलग करता है? डॉक्यूमेंट कंटेंट, कमेंट एंकर और वर्ज़न हिस्ट्री को रिकवर होना चाहिए। कर्सर मूवमेंट उच्च-मंथन (high-churn) वाला होता है और डिस्कनेक्ट होने के बाद समाप्त हो जाता है। डॉक्यूमेंट लॉग में प्रत्येक कर्सर मूवमेंट को बनाए रखने से लागत बढ़ती है और बासी स्थिति के साथ रिकवरी प्रदूषित होती है।
चौथा, क्या उम्मीदवार रिच-टेक्स्ट सेमेंटिक्स के बारे में तर्क कर सकता है? एक कन्वर्जेंट कैरेक्टर अनुक्रम स्वचालित रूप से एक डॉक्यूमेंट ट्री को मान्य नहीं बनाता है। सूचियों, तालिकाओं, कमेंट एंकर, स्कीमा अपग्रेड और undo स्कोप के लिए स्पष्ट मॉडल, वर्ज़न और इनवेरिएंट्स की आवश्यकता होती है। जैसे ही कोई रिमोट उपयोगकर्ता उनके पहले इन्सर्ट करता है, प्लेन इंटीजर ऑफ़सेट भी बदल जाते हैं।
अंत में, क्या क्षमता, हॉटस्पॉट, मल्टी-रीजन ओनरशिप, अनुमतियां और सत्यापन एक क्लोज्ड लूप बनाते हैं? एक मजबूत उत्तर राइट लोड और प्रति-रूम फैन-आउट की गणना करता है, धीमे क्लाइंट्स को सीमित करता है, बताता है कि रद्द किए गए ऑफ़लाइन एडिट्स आसानी से मर्ज क्यों नहीं हो सकते हैं, और कन्वर्जेंस और ड्यूरेबिलिटी साबित करने के लिए पुन: व्यवस्थित अपडेट्स, डुप्लिकेट्स, पार्टीशन्स और फेलओवर का उपयोग करता है।
उत्तर देने से पहले स्पष्ट करने वाले प्रश्न
- क्या एडिट किया जा रहा है? प्राथमिक डिज़ाइन एक संरचित रिच-टेक्स्ट ट्री का उपयोग करता है। इमेज बाइट्स ऑब्जेक्ट स्टोरेज में रहते हैं; डॉक्यूमेंट में संदर्भ और विशेषताएँ होती हैं।
- कॉन्फ़्लिक्ट का उत्पाद अर्थ क्या है? समवर्ती अपडेट एक दूसरे को अधिलेखित (overwrite) किए बिना नियतात्मक (deterministically) रूप से कन्वर्ज होते हैं। सिस्टम दो विरोधाभासी वाक्यों के व्यावसायिक इरादे का अनुमान नहीं लगाता है।
- एक्नॉलेज्ड का क्या अर्थ है? सर्वर केवल तभी ack करता है जब अपडेट होम रीजन में तीन उपलब्धता क्षेत्रों में रेप्लिकेट किए गए ड्यूरेबल लॉग में प्रवेश कर जाता है।
- क्या वैश्विक रैखिक क्रम (global linear order) की आवश्यकता है? नहीं। कंटेंट CRDT के माध्यम से कन्वर्ज होती है। ऑडिट, रिकवरी और एक्नॉलेजमेंट वॉटरमार्क के लिए एक लॉग ऑफ़सेट मौजूद है, मर्ज शुद्धता के लिए नहीं।
- क्लाइंट कितने समय तक ऑफ़लाइन रह सकता है? 24 घंटे तक। यह स्थानीय CRDT स्थिति और अनएक्नॉलेज्ड अपडेट्स को बरकरार रखता है, फिर डेल्टा का आदान-प्रदान करने से पहले पुनः ऑथराइज करता है।
- अनुमति स्तर क्या हैं? एक
viewerपढ़ता है, एकcommenterकेवल कमेंट डोमेन को बदलता है, और एकeditorकंटेंट को बदलता है। शामिल होना, फिर से जुड़ना और हर राइट ऑथराइज्ड है। - क्या कर्सर स्थिति ड्यूरेबल है? नहीं। प्रेजेंस हार्टबीट और TTL का उपयोग करती है। एक खोया हुआ कर्सर अपडेट अगले स्थिति अपडेट द्वारा बदल दिया जाता है।
- क्या कई क्षेत्र एक ही डॉक्यूमेंट के लिए राइट्स स्वीकार कर सकते हैं? प्राथमिक डिज़ाइन प्रत्येक डॉक्यूमेंट को एक होम रीजन सौंपता है और राइट्स को वहां अग्रेषित करता है, जिससे ऑथराइजेशन, ऑडिट और फेलओवर सरल हो जाता है।
- वर्ज़न हिस्ट्री कितने समय तक रखी जाती है? मान लें कि उपयोगकर्ता-दृश्यमान वर्ज़न 30 दिनों के लिए रखे जाते हैं। वे ऑनलाइन सिंक के लिए उपयोग किए जाने वाले कॉम्पैक्टेड स्नैपशॉट से अलग हैं।
- क्या एंड-टू-एंड एन्क्रिप्शन स्कोप में है? मुख्य डिज़ाइन सर्वर को अनुमतियों और कंटेंट स्कीमा को मान्य करने की अनुमति देता है। एंड-टू-एंड एन्क्रिप्शन एक फॉलो-अप ट्रेड-ऑफ है।
30-सेकंड उत्तर रूपरेखा
"मैं एक सर्वर-रिले किए गए CRDT का उपयोग करूंगा: एडिट्स को स्थानीय रूप से लागू करें, प्रत्येक WebSocket अपडेट को पुनः ऑथराइज करें, क्रॉस-ज़ोन ड्यूरेबल पर्सिस्टेंस के बाद ही ack करें, फिर डॉक्यूमेंट रूम द्वारा ब्रॉडकास्ट करें। रीकनेक्ट्स छूटे हुए अंतरों के लिए स्टेट वेक्टर्स का उपयोग करते हैं या एक स्नैपशॉट लोड करते हैं; ड्यूरेबल कंटेंट और TTL-आधारित प्रेजेंस अलग रहते हैं। पीक लोड 400,000 अपडेट या लगभग 120 MB/s है। एक 100-संपादक हॉट रूम प्रति सेकंड लगभग 19,800 रिमोट डिलीवरी बनाता है, इसलिए गेटवे अपडेट्स को बैच करते हैं और धीमे-क्लाइंट बफ़र्स को सीमित करते हैं। मैं कन्वर्जेंस और ड्यूरेबिलिटी के लिए पुन: व्यवस्थित और डुप्लिकेट अपडेट्स, 24 घंटे के ऑफ़लाइन रीकनेक्ट्स, अनुमति निरसन (revocation) और होम-रीजन फेलओवर का परीक्षण करूंगा।"
चरण-दर-चरण गहन विश्लेषण
सात इनवेरिएंट्स के साथ शुरुआत करें:
- स्थानीय इनपुट कभी भी नेटवर्क की प्रतीक्षा नहीं करता है, और सभी अपडेट प्राप्त करने वाले रेप्लिका समान मान्य डॉक्यूमेंट में कन्वर्ज होते हैं।
- क्रॉस-ज़ोन ड्यूरेबल पर्सिस्टेंस सफल होने के बाद ही सर्वर कंटेंट अपडेट को एक्नॉलेज करता है।
- पुन: प्रयास (retries), डुप्लिकेट प्रसारण और पुन: व्यवस्थित डिलीवरी किसी एडिट को दो बार लागू नहीं कर सकते हैं या अंतिम परिणाम को बदल नहीं सकते हैं।
- वर्तमान पहचान और अनुमतियां सर्वर सत्र से आती हैं, अपडेट पेलोड के अंदर की भूमिका से कभी नहीं।
- कंटेंट, कमेंट्स और वर्ज़न हिस्ट्री पुनर्प्राप्त होते हैं; कर्सर और ऑनलाइन स्थिति समाप्त हो सकती है।
- एक स्कीमा-असंगत (schema-incompatible) क्लाइंट अज्ञात संरचनाओं को लिखना जारी नहीं रख सकता है।
- प्रत्येक ड्रॉप, अस्वीकृति, डिग्रेडेशन और रिकवरी परिणाम देखने योग्य (observable) है।
पहला चरण: OT और CRDT के बीच चयन करें।
OT आमतौर पर संदर्भ के रूप में एक क्रमित सर्वर वर्ज़न का उपयोग करता है और समवर्ती ऑपरेशन्स के विरुद्ध प्रत्येक आने वाले ऑपरेशन को बदलता है (transforms)। यह एक स्थापित ट्रांसफ़ॉर्मेशन इंजन के साथ एक सर्वर-प्रामाणिक (server-authoritative) प्रणाली के अनुकूल है, लेकिन ट्रांसफ़ॉर्मेशन फ़ंक्शंस, बनाए रखा गया इतिहास और ऑफ़लाइन रीबेस सभी सही होने चाहिए। एक CRDT डेटा संरचना में समवर्तीता को एनकोड करता है। अपडेट अलग-अलग क्रमों में और एक से अधिक बार आ सकते हैं, और उन सभी को प्राप्त करने के बाद रेप्लिका कन्वर्ज हो जाते हैं। इसकी लागत कॉज़ल मेटाडेटा, विलोपन मार्कर (deletion markers), जटिल रिच-टेक्स्ट बाइंडिंग और ऑथराइजेशन व सिमेंटिक संघर्षों के लिए अलग हैंडलिंग है।
चूंकि प्रॉम्प्ट के लिए 24 घंटे की ऑफ़लाइन एडिटिंग और मल्टी-रीजन एक्सेस की आवश्यकता होती है, इसलिए प्राथमिक डिज़ाइन सर्वर रिले और ड्यूरेबल पर्सिस्टेंस के साथ एक परिपक्व अनुक्रम/ट्री CRDT चुनता है। CRDT को विकेंद्रीकृत परिनियोजन (decentralized deployment) की आवश्यकता नहीं होती है और यह सर्वर को नहीं हटाता है। सर्वर अभी भी पहचान, स्कीमा वैलिडेशन, आकार सीमा, ड्यूरेबल एक्नॉलेजमेंट, इतिहास, अनुपालन और रूम फैन-आउट का मालिक है।
दूसरा चरण: संरचित डॉक्यूमेंट और संदेश अनुबंध (message contract) को परिभाषित करें।
डॉक्यूमेंट रूट में स्थिर IDs वाले ब्लॉक होते हैं। पैराग्राफ, हेडिंग और लिस्ट आइटम CRDT टेक्स्ट और फ़ॉर्मेटिंग विशेषताओं के स्वामी हैं। कमेंट थ्रेड एक अलग डोमेन में रहते हैं और सापेक्ष स्थितियों (relative positions) के साथ श्रेणियों (ranges) से जुड़े होते हैं। एक स्कीमा वर्ज़न अनुमत नोड्स, विशेषताओं और माइग्रेशन नियमों को परिभाषित करता है। एक पूर्णांक ऑफ़सेट (integer offset) अस्थिर होता है: इसके पहले का सम्मिलन उस चीज़ को बदल देता है जिसकी ओर यह इंगित करता है। एक सापेक्ष स्थिति CRDT तत्व से जुड़ती है और रेप्लिका के कन्वर्ज होने के बाद लगातार हल होती है।
WebSocket सबप्रोटोकॉल इन एप्लिकेशन संदेशों का उपयोग कर सकता है:
join {
documentId, sessionId, schemaVersion, stateVector
}
update {
documentId, clientId, clientSeq, schemaVersion, payload
}
ack {
clientId, clientSeq, durableOffset
}
sync {
payload, durableOffset, schemaVersion
}
presence {
sessionId, relativeCursor, relativeSelection, statusSeq
}(documentId, clientId, clientSeq) पुनः प्रयास आइडेम्पोटेंसी कुंजी है। durableOffset एक्नॉलेजमेंट और ऑडिटिंग का समर्थन करता है लेकिन CRDT मर्ज शुद्धता में भाग नहीं लेता है। संदेशों में कंप्रेस्ड और अनकंप्रेस्ड आकार की सीमाएँ और एक स्कीमा अनुमति सूची होती है। अज्ञात नोड्स या अनधिकृत डोमेन परिवर्तनों को प्रसारित करने के बजाय स्पष्ट रूप से अस्वीकार कर दिया जाता है।
तीसरा चरण: लोडिंग, लाइव रूम्स और स्टोरेज पथों को अलग करें।
Client
-> HTTPS snapshot service -> metadata + snapshot store
-> WebSocket gateway -> document room router -> collaboration service
-> durable update log
-> room pub/sub -> gateways
Client
-> presence channel -> regional ephemeral store -> room fan-outक्लाइंट पहले HTTPS पर डॉक्यूमेंट मेटाडेटा, वर्तमान स्कीमा और एक हालिया कॉम्पैक्टेड स्नैपशॉट लोड करता है, फिर एक WebSocket खोलता है। गेटवे कनेक्शन्स और रूम सब्सक्रिप्शन का मालिक है लेकिन मर्ज नियम नहीं बनाता है। कोलैबोरेशन सेवा डॉक्यूमेंट द्वारा उसके होम रीजन में रूट करती है, प्रत्येक अपडेट को ऑथराइज और मान्य करती है, इसे बनाए रखती है, इसे ack करती है और इसे प्रकाशित करती है। रूम बस सब्सक्राइबर्स वाले प्रत्येक गेटवे पर एक बार प्रकाशित करती है, और प्रत्येक गेटवे प्रति प्राप्तकर्ता एक क्रॉस-नोड संदेश भेजने के बजाय स्थानीय रूप से फैन-आउट करता है।
चौथा चरण: स्थानीय संपादन, एक्नॉलेजमेंट और पुन: प्रयास को एक स्पष्ट स्टेट मशीन बनाएं।
एक स्थानीय संपादन दृश्य को तुरंत अपडेट करता है और एक स्थानीय रूप से ड्यूरेबल पेंडिंग कतार में प्रवेश करता है। ऑनलाइन रहते हुए, संदेशों की संख्या कम करने के लिए क्लाइंट 20 से 50 मिलीसेकंड की विंडो में आसन्न कीस्ट्रोक को बैच कर सकता है। वह समय एक इनपुट धारणा है और इसे इंटरैक्शन परीक्षणों के साथ ट्यून किया जाना चाहिए। प्रत्येक अपडेट के लिए, सर्वर सत्र को प्रमाणित करता है, वर्तमान अनुमति पढ़ता है, स्कीमा और संसाधन सीमाओं को मान्य करता है, रेप्लिकेट किए गए लॉग में जोड़ता है, एक ack लौटाता है, और ब्रॉडकास्ट करता है। केवल ack ही अपडेट को पेंडिंग कतार से हटाता है।
यदि कमिट के बाद लेकिन ack से पहले कनेक्शन विफल हो जाता है, तो क्लाइंट उसी clientSeq का पुन: प्रयास करता है। सर्वर विशिष्टता बाधा (uniqueness constraint) मूल एक्नॉलेजमेंट लौटा सकती है। CRDT आइडेम्पोटेन्स दोहराए गए एप्लिकेशन को भी सुरक्षित बनाता है, लेकिन ऑडिट और बिलिंग रिकॉर्ड को अभी भी डिडुप्लिकेट करने की आवश्यकता होती है। एक धीमे क्लाइंट को एक सीमित सेंड बफ़र प्राप्त होता है। हाई-वॉटर मार्क के बाद, गेटवे पहले प्रेजेंस को हटा देता है और फिर क्लाइंट को एक स्टेट वेक्टर से पुनः सिंक करने के लिए कहता है, बजाय इसके कि एक कनेक्शन को असीमित रूम मेमोरी का उपभोग करने की अनुमति दी जाए।
पांचवां चरण: ऑनलाइन, ऑफ़लाइन और रीकनेक्ट सिंक्रोनाइज़ेशन के लिए स्टेट वेक्टर्स का उपयोग करें।
कम्यूटेटिव, एसोसिएटिव और आइडेम्पोटेंट CRDT अपडेट रेप्लिका को अलग-अलग क्रमों में अपडेट प्राप्त करने और सुरक्षित रूप से पुनः प्रयास करने की अनुमति देते हैं। पुनः कनेक्ट होने पर, एक क्लाइंट एक स्टेट वेक्टर भेजता है जो उसके पास पहले से मौजूद कॉज़ल स्थिति का वर्णन करता है, और सर्वर लापता अंतर की गणना करता है। यदि डेल्टा बहुत बड़ा है, स्कीमा बदल गया है, या ऑनलाइन इतिहास विंडो समाप्त हो गई है, तो सर्वर वर्तमान पूर्ण CRDT स्नैपशॉट भेजता है और फिर भी-ऑथराइज्ड स्थानीय अपडेट लागू करता है।
क्रम प्रमाणित करना, अधिकृत करना, स्कीमा पर बातचीत करना और फिर कंटेंट का आदान-प्रदान करना है। यदि उपयोगकर्ता के ऑफ़लाइन होने के दौरान एडिट अनुमति रद्द कर दी गई थी, तो कन्वर्जेंस परिवर्तनों को स्वीकार करने की अनुमति नहीं है। सर्वर एक स्थिर permission_revoked त्रुटि लौटाता है और निर्यात या प्रतिलिपि के लिए एक स्थानीय पुनर्प्राप्ति पथ रखता है, लेकिन यह ड्राफ्ट को साझा डॉक्यूमेंट में नहीं लिखता है। उत्पाद वर्तमान एक्सेस नियंत्रण को बनाए रखने के लिए "प्रत्येक ऑफ़लाइन एडिट मर्ज होता है" का त्याग करता है।
छठा चरण: स्नैपशॉट, वर्ज़न हिस्ट्री और कॉम्पैक्शन डिज़ाइन करें।
ड्यूरेबल लॉग documentId द्वारा विभाजित होता है और अपडेट आईडी, लेखक, स्कीमा, पेलोड, प्राप्त करने का समय और ड्यूरेबल ऑफ़सेट रिकॉर्ड करता है। एक बैकग्राउंड कॉम्पैक्टर CRDT स्थिति लोड करता है, सीधे लोड करने योग्य स्नैपशॉट में वृद्धि को जोड़ता है, और कवर किए गए ऑफ़सेट को रिकॉर्ड करता है। यह पुराने इंक्रीमेंट्स को तभी हटाता है जब नया स्नैपशॉट वैलिडेशन पास कर लेता है, ऑब्जेक्ट स्टोरेज में ड्यूरेबल होता है, और रिकवरी और ऑडिट विंडो के लिए रोलबैक पॉइंट बनाए रखता है।
बाइनरी अपडेट्स को मर्ज करने से डुप्लिकेट जानकारी हट जाती है लेकिन यह अपने आप हटाए गए कंटेंट को गारबेज-कलेक्ट नहीं करता है। विलोपन मार्कर, ऑफ़लाइन सिंक्रोनाइज़ेशन, कमेंट एंकर, प्रति-उपयोगकर्ता undo और ऐतिहासिक वर्ज़न परस्पर क्रिया करते हैं। इसलिए कॉम्पैक्शन को वास्तविक डॉक्यूमेंट परीक्षणों की आवश्यकता होती है। उपयोगकर्ता-दृश्यमान इतिहास स्वतंत्र नामित स्नैपशॉट या परिवर्तन इंडेक्स संग्रहीत करता है; ऑनलाइन सिंक कॉम्पैक्शन उत्पाद वर्ज़न हिस्ट्री का विकल्प नहीं है।
सातवां चरण: प्रेजेंस को अलग करें और हॉटस्पॉट फैन-आउट को नियंत्रित करें।
प्रेजेंस में एक सत्र, प्रदर्शन नाम, रंग, सापेक्ष कर्सर, चयन और मोनोटोनिक statusSeq शामिल हैं, जो हार्टबीट और TTL द्वारा रीफ़्रेश किए जाते हैं। यह कभी भी डॉक्यूमेंट CRDT या ड्यूरेबल लॉग में प्रवेश नहीं करता है। प्राप्तकर्ता पुराने अनुक्रम नंबरों को त्याग देते हैं, और डिस्कनेक्ट स्थिति समाप्त हो जाती है। एक कर्सर अपडेट खोने का केवल एक क्षणिक प्रभाव होता है क्योंकि अगला अपडेट इसे बदल देता है।
दो अपडेट प्रति सेकंड पर 100-संपादक वाला रूम प्रति सेकंड 200 कंटेंट अपडेट उत्पन्न करता है। प्रत्येक अपडेट को अन्य 99 उपयोगकर्ताओं को भेजने का अर्थ है प्रेजेंस से पहले प्रति सेकंड लगभग 19,800 रिमोट डिलीवरी। गेटवे एक छोटे समय के स्लाइस से अपडेट्स को बैच करते हैं, डॉक्यूमेंट रूम द्वारा प्रकाशित करते हैं, प्रेजेंस आवृत्ति को सीमित करते हैं, और प्रति कनेक्शन बाइट और संदेश वॉटरमार्क लागू करते हैं। एक अत्यधिक हॉट डॉक्यूमेंट को एक समर्पित रूम एक्टर और pub/sub विभाजन प्राप्त हो सकता है, लेकिन लोड को कम करने के लिए सिस्टम कभी भी ड्यूरेबल कंटेंट एडिट्स का नमूना (sample) नहीं लेता है।
आठवां चरण: वैश्विक क्षमता और कनेक्शन संसाधनों की पुनर्गणना करें।
दो लाख (200,000) संपादक दो अपडेट प्रति सेकंड की दर से प्रति सेकंड 400,000 अपडेट उत्पन्न करते हैं। औसतन 300-बाइट बाइनरी पेलोड पर, रॉ राइट्स लगभग 120 MB/s या 10.37 TB/दिन हैं। रेप्लिकेशन, इंडेक्स, हेडर, स्नैपशॉट और वर्ज़न हिस्ट्री अतिरिक्त हैं। यदि एक गेटवे कनेक्शन 50 KiB घेरता है, तो 20 लाख (2 million) कनेक्शन्स को लगभग 100 GiB गेटवे स्थिति की आवश्यकता होती है। प्रति गेटवे 20,000 कनेक्शन्स पर, विफलता और परिनियोजन हेडरूम से पहले आधार रेखा 100 गेटवे है।
ये अनुमान शुरुआती बिंदु हैं। रॉ कंटेंट स्टोरेज से पहले हॉट-रूम इग्रेस, टीएलएस और एन्कोडिंग सीपीयू, धीमे-क्लाइंट बफ़र्स और ड्यूरेबल-लॉग पार्टीशन्स बाधाएं बन सकते हैं। डॉक्यूमेंट और टेनेंट द्वारा अपडेट और फैन-आउट दर, ack विलंबता, स्टेट-वेक्टर डेल्टा आकार, रीकनेक्ट्स, बफ़र वॉटरमार्क, स्नैपशॉट आयु और कन्वर्जेंस-जांच विफलताओं की निगरानी करें।
नौवां चरण: मल्टी-रीजन व्यवहार, फेलओवर और सुरक्षा को सीमित करें।
डॉक्यूमेंट मेटाडेटा एक होम रीजन और बढ़ते युग (epoch) को रिकॉर्ड करता है। एक क्लाइंट पास के गेटवे के माध्यम से प्रवेश करता है, जबकि कंटेंट राइट्स होम रीजन में रूट होते हैं। तत्काल स्थानीय अनुप्रयोग टाइपिंग से क्रॉस-रीजन RTT को छुपाता है। यदि होम रीजन विफल हो जाता है, तो कंट्रोल प्लेन पहले युग को आगे बढ़ाता है, फिर नया क्षेत्र रेप्लिकेट किए गए लॉग और नवीनतम स्नैपशॉट से पुनर्स्थापित करता है। पर्सिस्टेंस लेयर पुराने एक्टर के युग को अस्वीकार कर देती है ताकि दो रूम ओनर्स दोनों ड्यूरेबल एक्नॉलेजमेंट जारी न कर सकें।
CRDT कन्वर्जेंस किसी एक ऑथराइजेशन निर्णय, ड्यूरेबल एक्नॉलेजमेंट या फेलओवर बाड़ लगाने (fencing) की जगह नहीं लेता है। सुरक्षा के लिए डॉक्यूमेंट, अपडेट, दर और डीकंप्रेशन-अनुपात सीमाओं की भी आवश्यकता होती है; ओरिजिन, सत्र और डॉक्यूमेंट ऑथराइजेशन जांच; ट्रांजिट और रेस्ट में एन्क्रिप्शन; शेयरिंग, अनुमति परिवर्तनों और निर्यात के लिए ऑडिटिंग; और लॉग जो एक्सेस टोकन, डॉक्यूमेंट बॉडी और सटीक कर्सर विवरण को छोड़ देते हैं।
दसवां चरण: प्रॉपर्टी परीक्षणों और दोष इंजेक्शन (fault injection) के साथ डिज़ाइन को साबित करें।
समान प्रारंभिक डॉक्यूमेंट पर कई क्लाइंट्स से अपडेट उत्पन्न करें। उन्हें यादृच्छिक क्रम में, डुप्लिकेट, देरी और बैचों के साथ लागू करें। प्रत्येक रेप्लिका को समान सीरियलाइज़्ड परिणाम और मान्य स्कीमा के साथ समाप्त होना चाहिए। समान-स्थिति इन्सर्ट, ओवरलैपिंग डिलीट, इसके चाइल्ड को एडिट करते समय पैरेंट को हटाना, समवर्ती फ़ॉर्मेटिंग और टेक्स्ट, कमेंट एंकर, प्रति-उपयोगकर्ता undo और स्कीमा अपग्रेड जोड़ें।
ड्यूरेबल एपेंड के बाद लेकिन ack से पहले कोलैबोरेशन सेवा को समाप्त करें (kill); पुन: प्रयास से एक ऑडिट किया गया अपडेट उत्पन्न होना चाहिए। Ack के बाद लेकिन ब्रॉडकास्ट से पहले इसे समाप्त करें; रिकवरी को अपडेट डिलीवर करना चाहिए। 24 ऑफ़लाइन घंटों के बाद फिर से कनेक्ट करें और स्टेट-वेक्टर डेल्टा और स्नैपशॉट दोनों पथों का अभ्यास करें। ऑफ़लाइन अपडेट सबमिट करने से पहले अनुमति रद्द करें; स्थानीय पुनर्प्राप्ति को संरक्षित करते हुए साझा पर्सिस्टेंस को उन्हें अस्वीकार करना चाहिए। अंत में, कंटेंट और प्रेजेंस के साथ 100-संपादक वाले हॉट रूम का लोड-परीक्षण करें, p95 लेटेंसी, मेमोरी वॉटरमार्क और इच्छित डिग्रेडेशन ऑर्डर का सत्यापन करें।
उच्च-गुणवत्ता वाला नमूना उत्तर
"मैं तीन अनुबंधों के साथ शुरुआत करूंगा: स्थानीय इनपुट तुरंत लागू होता है; सभी अपडेट प्राप्त करने वाले रेप्लिका कन्वर्ज होते हैं; और केवल तीन उपलब्धता क्षेत्रों में ड्यूरेबल रूप से लॉग किए गए अपडेट को ही एक्नॉलेज किया जाता है। 24 घंटे की ऑफ़लाइन आवश्यकता एक परिपक्व संरचित CRDT का पक्ष लेती है, जबकि सर्वर प्रमाणीकरण, स्कीमा, पर्सिस्टेंस और फैन-आउट के लिए आधिकारिक रहता है।
एक CRDT स्नैपशॉट लोड करने के बाद, क्लाइंट एक डॉक्यूमेंट रूम में शामिल होता है। एक स्थानीय संपादन पहले लागू होता है और clientId + clientSeq के तहत एक पेंडिंग कतार में प्रवेश करता है, फिर WebSocket पर एक बाइनरी अपडेट के रूप में यात्रा करता है। कोलैबोरेशन सेवा वर्तमान अनुमति, स्कीमा और संसाधन सीमाओं की फिर से जांच करती है, अपडेट को ड्यूरेबल रूप से जोड़ती है, इसे ack करती है, और इसे रूम में प्रकाशित करती है। एक पुन: प्रयास समान अनुक्रम रखता है। अपडेट पुन: व्यवस्थित करने और दोहराव को सहन करते हैं। पुनः कनेक्ट होने पर, क्लाइंट एक स्टेट वेक्टर भेजता है और लापता परिवर्तन या एक पूर्ण स्नैपशॉट प्राप्त करता है। यदि ऑफ़लाइन अनुमति रद्द कर दी गई थी, तो साझा राइट अस्वीकार कर दिया जाता है और केवल एक स्थानीय निर्यात उपलब्ध रहता है।
कंटेंट और प्रेजेंस अलग-अलग पथों का उपयोग करते हैं। कर्सर सापेक्ष स्थितियों का उपयोग करते हैं, जबकि TTL-आधारित प्रेजेंस ड्यूरेबल रूप से लॉग नहीं होती है। प्रत्येक डॉक्यूमेंट का एक होम रीजन और युग (epoch) होता है। फेलओवर रेप्लिकेट किए गए लॉग और स्नैपशॉट से पुनर्स्थापित करने से पहले युग को आगे बढ़ाता है, इसलिए पुराना रूम ओनर अपडेट्स को एक्नॉलेज करना जारी नहीं रख सकता है।
पीक पर, 200,000 संपादक गुणा दो अपडेट प्रति सेकंड 400,000 अपडेट प्रति सेकंड के बराबर होता है। 300 बाइट्स पर, यह 120 MB/s और रॉ अपडेट का 10.37 TB/दिन है। 100-संपादक वाला हॉट डॉक्यूमेंट प्रति सेकंड लगभग 200 अपडेट और 19,800 रिमोट डिलीवरी बनाता है, इसलिए रूम बस एक बार प्रकाशित होती है, गेटवे स्थानीय रूप से बैच और फैन-आउट करते हैं, और धीमे-क्लाइंट बफ़र्स सीमित होते हैं। मैं अपडेट्स को तब तक क्रमपरिवर्तित (permuting) और डुप्लिकेट करके सिस्टम को साबित करूंगा जब तक कि प्रत्येक रेप्लिका कन्वर्ज न हो जाए, फिर ack सीमा के आसपास क्रैश, 24 घंटे के ऑफ़लाइन रीकनेक्ट्स, अनुमति निरसन, स्कीमा अपग्रेड और होम-रीजन विफलता को इंजेक्ट करूंगा।"
सामान्य गलतियाँ
- केवल "WebSockets का उपयोग करें" कहना → ट्रांसपोर्ट समवर्ती संपादन को हल नहीं करता है → OT या CRDT चुनें और कन्वर्जेंस व लागत की व्याख्या करें।
- प्रत्येक संपादन के लिए संपूर्ण डॉक्यूमेंट सहेजना → समवर्ती उपयोगकर्ता एक-दूसरे को अधिलेखित करते हैं और डॉक्यूमेंट आकार के साथ बैंडविड्थ बढ़ती है → मर्ज करने योग्य वृद्धिशील अपडेट भेजें।
- इन-मेमोरी प्राप्ति के बाद Ack करना → एक प्रक्रिया क्रैश एक्नॉलेज किए गए काम को खो देती है → क्रॉस-ज़ोन ड्यूरेबल एपेंड के बाद Ack करें।
- CRDT को ऑथराइजेशन मानना → गणितीय कन्वर्जेंस एक निरस्त (revoked) उपयोगकर्ता को नहीं रोकता है → शामिल होने, फिर से जुड़ने और हर राइट को ऑथराइज करें।
- कर्सर को पूर्णांक ऑफ़सेट के रूप में सहेजना → समवर्ती इन्सर्ट अभीष्ट स्थिति को स्थानांतरित करते हैं → CRDT तत्वों के सापेक्ष स्थितियों का उपयोग करें।
- कंटेंट लॉग में कर्सर गति को बनाए रखना → उच्च-मंथन वाली एफेमरल स्थिति स्टोरेज और रिकवरी को बढ़ाती है → एक TTL प्रेजेंस चैनल का उपयोग करें।
- सटीक रूप से एक बार (exactly-once) डिलीवरी का दावा करना → रीकनेक्ट्स और प्रसारण डुप्लिकेट हो सकते हैं → आइडेम्पोटेंट अपडेट, अद्वितीय पहचान और रीप्ले करने योग्य स्थिति का उपयोग करें।
- स्नैपशॉट के तुरंत बाद सभी इतिहास हटाना → ऑफ़लाइन सिंक, रोलबैक, undo या स्कीमा माइग्रेशन आवश्यक संदर्भ खो सकते हैं → केवल मान्य रिकवरी वॉटरमार्क से परे ही कलेक्ट करें।
- केवल कंटेंट इनग्रेस की गणना करना → हॉट-रूम फैन-आउट और धीमे क्लाइंट अक्सर पहले संसाधनों को समाप्त कर देते हैं → डिलीवरी, इग्रेस और बफ़र्स की भी गणना करें।
- कंट्रोल प्लेन के बिना हर जगह सक्रिय राइट्स स्वीकार करना → ऑथराइजेशन, ack और फेलओवर ओनरशिप अस्पष्ट हो जाती है → एक होम रीजन और युग का उपयोग करें।
फॉलो-अप प्रश्न और उत्तर
फॉलो-अप एक: OT के बजाय CRDT क्यों चुनें?
24 घंटे की ऑफ़लाइन आवश्यकता और पुन: व्यवस्थित, डुप्लिकेट मल्टी-रीजन ट्रांसपोर्ट CRDT अपडेट मॉडल के साथ संरेखित होते हैं, और एक परिपक्व कार्यान्वयन स्टेट वेक्टर्स के साथ अंतर का आदान-प्रदान कर सकता है। OT अभी भी मान्य है। एक सिद्ध सर्वर ट्रांसफ़ॉर्म इंजन, एक क्रमित एडिट सेवा और सीमित ऑफ़लाइन व्यवहार के साथ, यह अधिक नियंत्रित मेटाडेटा और सर्वर सेमेंटिक्स प्रदान कर सकता है। निर्णय उत्पाद बाधाओं और टीम क्षमता से आता है, न कि किसी एक संक्षिप्त नाम को सार्वभौमिक रूप से नया घोषित करने से।
फॉलो-अप दो: क्या CRDT एक ड्यूरेबल अपडेट लॉग की आवश्यकता को समाप्त करता है?
नहीं। CRDT मर्जिंग और कन्वर्जेंस को हल करता है। एक्नॉलेज्ड ड्यूरेबिलिटी, ऑडिट, इतिहास, रिकवरी और नए-डिवाइस लोडिंग को अभी भी ड्यूरेबल स्थिति की आवश्यकता होती है। सिस्टम स्नैपशॉट में इंक्रीमेंट्स को कॉम्पैक्ट कर सकता है और रिकवरी विंडो के बाद पुरानी लॉग प्रविष्टियों को कलेक्ट कर सकता है, लेकिन इसे एक सत्यापन योग्य ड्यूरेबिलिटी सीमा और रोलबैक बिंदु को बनाए रखना चाहिए।
फॉलो-अप तीन: क्या होगा यदि किसी ऑफ़लाइन उपयोगकर्ता की अनुमति रद्द कर दी गई हो?
कंटेंट का आदान-प्रदान करने से पहले पुनः प्रमाणित और ऑथराइज करें। एक स्थिर त्रुटि के साथ साझा राइट को अस्वीकार करें और निर्यात या प्रतिलिपि के लिए एक स्थानीय प्रतिलिपि रखें; इसे चुपचाप न छोड़ें। एक व्यवसाय किसी व्यवस्थापक को एक पृथक अनुमोदन क्षेत्र में ड्राफ्ट की समीक्षा करने दे सकता है, लेकिन वह पथ वर्तमान डॉक्यूमेंट ACL को बायपास नहीं कर सकता है।
फॉलो-अप चार: कई उपयोगकर्ताओं के साथ Undo कैसे काम करता है?
डिफ़ॉल्ट रूप से, वर्तमान उपयोगकर्ता के सबसे हाल के स्थानीय ऑपरेशन्स को पूर्ववत करें (undo) और CRDT के माध्यम से व्युत्क्रम ऑपरेशन्स (inverse operations) को मर्ज करें। एक संपूर्ण पुराने स्नैपशॉट को पुनर्स्थापित करने से अन्य उपयोगकर्ताओं का बाद का काम मिट जाएगा। प्रत्येक ऑपरेशन के लिए उपयोगकर्ता और लेनदेन सीमा रिकॉर्ड करें, लक्षित undo विंडो के लिए हटाए गए कंटेंट को बनाए रखें, और संरचनात्मक परिवर्तनों के लिए एडिटर बाइंडिंग में प्रतिवर्ती सेमेंटिक्स को परिभाषित करें।
फॉलो-अप पांच: समवर्ती संपादन के बाद कर्सर कूदने (jumping) से कैसे बचते हैं?
पूर्ण वर्ण ऑफ़सेट के बजाय CRDT तत्वों के सापेक्ष कर्सर और कमेंट एंकर संग्रहीत करें। रिमोट अपडेट लागू करने के बाद सापेक्ष स्थिति को वर्तमान इंडेक्स में हल करें। यदि एंकर और मूल संरचना दोनों हटा दिए गए थे, तो कर्सर को छिपाएं, कमेंट को अलग किए गए के रूप में चिह्नित करें, या एक स्पष्ट उत्पाद नियम के अनुसार निकटतम मान्य ब्लॉक पर वापस आएं।
फॉलो-अप छह: क्या होगा यदि दस हजार लोग एक डॉक्यूमेंट खोलते हैं?
संपादकों को केवल-पढ़ने वाले (read-only) दर्शकों से अलग करें। प्रत्येक कंटेंट अपडेट को रूम बस पर एक बार प्रकाशित करें और गेटवे से फैन-आउट करें। केवल-पढ़ने वाले क्लाइंट कम आवृत्ति पर मर्ज किए गए अपडेट प्राप्त कर सकते हैं या संपादक की शुद्धता को बदले बिना अल्पकालिक स्नैपशॉट पोल कर सकते हैं। प्रेजेंस केवल दृश्यमान या नमूना लिए गए प्रतिभागियों को दिखाती है, और प्रत्येक कनेक्शन में एक सीमित सेंड बफ़र होता है। सभी दस हजार कर्सर दिखाने के लिए अपने स्वयं के बैंडविड्थ और UI बजट की आवश्यकता होगी।
फॉलो-अप सात: क्या एडिटर एंड-टू-एंड एन्क्रिप्शन का समर्थन कर सकता है?
क्लाइंट CRDT अपडेट को एन्क्रिप्ट कर सकते हैं जबकि सर्वर रिले करता है और सिफरटेक्स्ट संग्रहीत करता है। ट्रेड-ऑफ यह है कि सर्वर अब रिच-टेक्स्ट स्कीमा को मान्य नहीं कर सकता है, कंटेंट खोज नहीं सकता है, मॉडरेट नहीं कर सकता है, बारीक निर्यात नहीं कर सकता है, या खोए हुए डेटा को आसानी से पुनर्प्राप्त नहीं कर सकता है। कुंजी रोटेशन, सदस्य निष्कासन और पुराने सदस्यों के ऑफ़लाइन अपडेट भी कठिन हो जाते हैं। पहले थ्रेट मॉडल और डॉक्यूमेंट, डिवाइस और सदस्यता कुंजी प्रोटोकॉल को परिभाषित करें; अकेले WebSocket के आसपास TLS ट्रांसपोर्ट एन्क्रिप्शन है, एंड-टू-एंड एन्क्रिप्शन नहीं।
फॉलो-अप आठ: आप एक साइलेंट रेप्लिका फोर्क का पता कैसे लगाते हैं?
एक शांत अवधि या रीकनेक्ट के बाद, एक क्लाइंट अपने स्टेट वेक्टर और एक गैर-संवेदनशील स्थिति डाइजेस्ट की रिपोर्ट करता है। केवल उसी ड्यूरेबल वॉटरमार्क पर रेप्लिका की तुलना करें; एक बेमेल पूर्ण पुन: सिंक को ट्रिगर करता है और एक डायग्नोस्टिक नमूना बरकरार रखता है। सतत कैनरी डॉक्यूमेंट कई क्षेत्रों से ज्ञात समवर्ती अपडेट जारी करते हैं और अंतिम डाइजेस्ट, स्कीमा, ack गणना और लॉग वॉटरमार्क को सत्यापित करते हैं। विभिन्न इन-फ़्लाइट वॉटरमार्क पर डाइजेस्ट की तुलना करने से झूठे अलार्म पैदा होंगे।