प्रांप्ट और लागू संदर्भ
50 मिलियन दैनिक सक्रिय उपयोगकर्ताओं, 5 मिलियन पीक समवर्ती कनेक्शनों और प्रति दिन 2 बिलियन संदेशों वाली एक टेक्स्ट चैट सेवा डिज़ाइन करें। यह प्रत्यक्ष बातचीत (direct conversations), अधिकतम 200 सदस्यों वाले समूहों, प्रति उपयोगकर्ता एकाधिक डिवाइस, ऑफ़लाइन कैच-अप, डिलीवरी और रीड रसीदों, प्रेजेंस और टाइपिंग संकेतकों का समर्थन करती है। अटैचमेंट, सार्वजनिक चैनल, क्रॉस-रीजन एक्टिव-एक्टिव राइट्स, फ़ुल-टेक्स्ट सर्च, और एंड-टू-एंड एन्क्रिप्शन फ़ॉलो-अप दायरे में हैं।
सेवा किसी सेंड को केवल तभी स्वीकार (acknowledge) करती है जब संदेश स्थायी रूप से संग्रहीत (durably stored) हो जाता है। इसे किसी स्वीकृत संदेश को चुपचाप नहीं खोना चाहिए। सामान्य लोड के तहत पहले से ऑनलाइन प्राप्तकर्ताओं के लिए, टिकाऊ स्वीकृति से लेकर कनेक्टेड डिवाइस पर आगमन तक का p99 एक सेकंड से कम होना चाहिए। ट्रांसपोर्ट पुनः डिलीवर कर सकता है, इसलिए डिडुप्लीकेशन के बाद क्लाइंट्स को एक लॉजिकल संदेश दिखाई देना चाहिए। ऑर्डरिंग एक बातचीत के भीतर आवश्यक है, असंबंधित बातचीत के पार नहीं।
2026 में प्रकाशित या अपडेट की गई तीन सार्वजनिक सिस्टम-डिज़ाइन गाइड चैट को एक प्रत्यक्ष साक्षात्कार प्रॉम्प्ट के रूप में प्रस्तुत करती हैं और लगातार पर्सिस्टेंट कनेक्शन, कनेक्शन रूटिंग, प्रति-बातचीत ऑर्डरिंग, ऑफ़लाइन सिंक्रोनाइज़ेशन, रसीदों और प्रेजेंस की जांच करती हैं। WebSocket मानक द्विदिशीय ट्रांसपोर्ट और नियंत्रण फ़्रेम को परिभाषित करता है, जबकि Matrix क्लाइंट-सर्वर विनिर्देश क्लाइंट ट्रांजेक्शन आईडी, इंक्रीमेंटल सिंक टोकन, रीड रसीदें और एफेमरल टाइपिंग इवेंट्स के प्रोडक्शन-ग्रेड उदाहरण प्रदान करता है। वे स्रोत स्थापित करते हैं कि विषय और इसकी विफलता सीमाएं वर्तमान और तकनीकी रूप से आधारित हैं; इस प्रॉम्प्ट में स्केल और SLO काल्पनिक साक्षात्कार इनपुट हैं।
साक्षात्कारकर्ता क्या मूल्यांकन करता है
पहला संकेत कॉन्ट्रैक्ट सटीकता है। "Sent," "delivered," और "read" अलग-अलग तथ्य हैं। सर्वर पावती (acknowledgment) का अर्थ है टिकाऊ स्वीकृति। डिलीवरी रसीद का अर्थ है कि चयनित प्राप्तकर्ता डिवाइस को संदेश प्राप्त हुआ। रीड रसीद के लिए एक स्पष्ट उत्पाद नियम की आवश्यकता होती है कि उपयोगकर्ता ने वास्तव में बातचीत प्रदर्शित की है। तीनों को एक स्थिति के रूप में मानने से विश्वसनीयता के झूठे दावे और गलत अपठित (unread) संख्याएं उत्पन्न होती हैं।
दूसरा संकेत यह है कि क्या उम्मीदवार एंड-टू-एंड एग्जैक्टली-वंस (exactly-once) वादे से बचता है। सर्वर द्वारा कमिट करने के बाद लेकिन पावती आने से पहले क्लाइंट का समय समाप्त (time out) हो सकता है। पुनः कनेक्ट होने के बाद गेटवे डिलीवरी दोहरा सकता है। व्यावहारिक कॉन्ट्रैक्ट एक स्थिर क्लाइंट संदेश आईडी, एक सर्वर इडेम्पोटेन्सी रिकॉर्ड, और सर्वर संदेश आईडी द्वारा क्लाइंट डिडुप्लीकेशन के साथ संयुक्त एट-लीस्ट-वंस (at-least-once) ट्रांसपोर्ट है।
तीसरा संकेत ऑर्डरिंग सीमा है। एक वैश्विक क्रम असंबंधित बातचीत को क्रमबद्ध (serialize) कर देगा। एक उपयोगी उत्पाद कॉन्ट्रैक्ट प्रत्येक स्वीकृत संदेश को उसकी बातचीत के भीतर एक मोनोटोनिक अनुक्रम (monotonic sequence) देता है। इसलिए एक बातचीत के सभी राइट्स एक वर्तमान ओनर या सीक्वेंसर तक पहुँचते हैं। यह अलग-अलग बातचीतों को स्वतंत्र रूप से स्केल करने की अनुमति देते हुए स्थानीय क्रम को सुरक्षित रखता है, और यह एक वास्तविक हॉट-कन्वर्सेशन सीमा को उजागर करता है।
चौथा संकेत टिकाऊ (durable) और अल्पकालिक (ephemeral) स्थिति का पृथक्करण है। संदेश, सदस्यता अंतराल (membership intervals), और रीड कर्सर विफलताओं के बाद भी बचे रहते हैं। प्रेजेंस और टाइपिंग समाप्त (expire) हो सकते हैं और छोड़े जा सकते हैं। टाइपिंग ट्रैफ़िक को टिकाऊ संदेश लॉग साझा करने की अनुमति देने से स्टोरेज बर्बाद होता है और एक कॉस्मेटिक बर्स्ट वास्तविक संदेशों में देरी कर सकता है।
अंतिम संकेत रिकवरी सोच है। उत्तर में खोई हुई सेंड पावती, गेटवे विफलता, पुनः कनेक्ट स्टॉर्म, पुराने बातचीत ओनर, धीमे डिवाइस, सदस्यता परिवर्तन, डुप्लिकेट फ़ैन-आउट और एक हॉट समूह को शामिल किया जाना चाहिए। क्षमता संख्याएं प्रॉम्प्ट से प्राप्त की जानी चाहिए और फिर सार्वभौमिक सर्वर सीमाओं के रूप में प्रस्तुत किए जाने के बजाय लोड परीक्षणों द्वारा कैलिब्रेट की जानी चाहिए।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- कौन सी सामग्री और बातचीत के प्रकार दायरे में हैं? यह उत्तर टेक्स्ट, प्रत्यक्ष बातचीत और 200 तक के समूहों को संभालता है। अटैचमेंट ऑब्जेक्ट स्टोरेज और मेटाडेटा संदेशों का उपयोग करते हैं; सार्वजनिक चैनलों को एक अलग फ़ैन-आउट और इतिहास रणनीति की आवश्यकता होती है।
- प्रत्येक रसीद का क्या अर्थ है? सर्वर स्वीकृत, डिवाइस प्राप्त और उपयोगकर्ता द्वारा पढ़ा गया अलग-अलग मोनोटोनिक तथ्य हैं। "Read" केवल तभी होता है जब क्लाइंट प्रासंगिक बातचीत प्रदर्शित करता है, न कि केवल तब जब उसे कोई पुश प्राप्त होता है।
- किस ऑर्डरिंग की आवश्यकता है? प्रॉम्प्ट को प्रति बातचीत एक स्थिर क्रम की आवश्यकता होती है। यह वादा नहीं करता है कि उपयोगकर्ता की वॉल क्लॉक क्रम निर्धारित करती है या कि दो अलग-अलग बातचीत एक अनुक्रम साझा करती हैं।
- क्या कोई उपयोगकर्ता एकाधिक डिवाइसों से भेज सकता है? हाँ। प्रत्येक डिवाइस का अपना प्रमाणित कनेक्शन और सिंक कर्सर होता है; प्रेषक पुनः प्रयास उसी क्लाइंट संदेश आईडी का पुनर्चक्रण करते हैं।
- सदस्यता बदलने पर क्या होता है? स्वीकृति के समय प्राधिकरण की जाँच की जाती है। उत्पाद को यह परिभाषित करना होगा कि क्या कोई नया सदस्य पुराना इतिहास पढ़ सकता है और कोई हटाया गया सदस्य स्थानीय रूप से क्या रखता है। यह डिज़ाइन बातचीत अनुक्रम द्वारा सदस्यता अंतराल संग्रहीत करता है।
- संदेश और इडेम्पोटेन्सी रिकॉर्ड कितने समय तक रखे जाते हैं? संदेश प्रतिधारण एक उत्पाद और अनुपालन निर्णय है। इडेम्पोटेन्सी मैपिंग को अधिकतम क्लाइंट पुनः प्रयास विंडो को कवर करना चाहिए; इसे पहले हटाने से डुप्लिकेट फिर से बन सकते हैं।
- किन क्षेत्रों का उपयोग किया जाता है? आधार उत्तर प्रत्येक बातचीत को एक होम क्षेत्र सौंपता है और जानबूझकर इसका फ़ेलओवर करता है। कई क्षेत्रों में एक साथ लिखने योग्य प्रतिकृतियों (replicas) के लिए अधिक जटिल संघर्ष और ऑर्डरिंग मॉडल की आवश्यकता होती है।
- एक-सेकंड के लक्ष्य से बाहर क्या है? ऑफ़लाइन पुश प्रदर्शन, रीकनेक्ट कैच-अप, उपयोगकर्ता पढ़ने का समय, और क्रॉस-रीजन डिजास्टर रिकवरी को पहले से कनेक्टेड डिवाइस पर लाइव डिलीवरी से अलग मापा जाता है।
30-सेकंड उत्तर रूपरेखा
"मैं टिकाऊ संदेश पथ से कनेक्शन प्रबंधन को अलग करूँगा। क्लाइंट एक स्थिर क्लाइंट संदेश आईडी के साथ एक प्रमाणित WebSocket पर भेजता है। बातचीत-रूटेड सेवा सदस्यता की पुनः जांच करती है, अगला प्रति-बातचीत अनुक्रम असाइन करती है, संदेश और इडेम्पोटेन्सी परिणाम को परमाणु रूप से (atomically) संग्रहीत करती है, और केवल तभी इसे स्वीकार करती है। एक एसिंक्रोनस फ़ैन-आउट वर्कर सक्रिय प्राप्तकर्ता डिवाइसों को देखता है और संदेश को उनके गेटवे पर भेजता है; ऑफ़लाइन या विफल डिवाइस कर्सर-आधारित सिंक API से पुनर्प्राप्त होते हैं। डिलीवरी और रीड कर्सर मोनोटोनिक रूप से आगे बढ़ते हैं, जबकि प्रेजेंस और टाइपिंग एक अलग समाप्त होने वाले पथ का उपयोग करते हैं। ट्रांसपोर्ट कम से कम एक बार (at least once) है, इसलिए सर्वर और क्लाइंट दोनों डिडुप्लिकेट करते हैं। बताए गए पैमाने पर मैं लगभग 23,000 औसत और 230,000 पीक सेंड्स प्रति सेकंड, 1 KB प्रत्येक पर लगभग 2 TB लॉजिकल संदेश डेटा प्रति दिन की योजना बनाऊँगा, और SLO के विरुद्ध पर्सिस्टेंट कनेक्शन, हॉट समूह, रीकनेक्ट स्टॉर्म, पुनः प्रयास, सदस्यता परिवर्तन और ओनर फ़ेलओवर का लोड-परीक्षण करूँगा।"
चरण-दर-चरण गहन विश्लेषण
चरण 1: उत्पाद अनुबंधों को फ़्रीज़ करें और पहले क्षमता लिफाफे की गणना करें।
प्रति दिन दो बिलियन संदेश औसतन लगभग 23,148 सेंड्स प्रति सेकंड होते हैं। यदि पीक औसत से दस गुना है, तो इनग्रेस योजना लगभग 230,000 सेंड्स प्रति सेकंड के आसपास शुरू होती है। साधारण मेटाडेटा और इंडेक्स सहित प्रति संग्रहीत संदेश अनुमानित 1 KB पर, लॉजिकल राइट वॉल्यूम प्रति दिन लगभग 2 TB है; तीन प्रतिकृतियां संघनन (compaction), फ़ाइल सिस्टम रिजर्व, बैकअप और रसीद राइट्स से पहले प्रति दिन लगभग 6 TB बनाती हैं। ये योजना धारणाएं हैं, मापी गई हार्डवेयर सीमाएं नहीं।
पाँच मिलियन समवर्ती कनेक्शन गेटवे योजना पर हावी हैं। मान लीजिए कि चुने गए उदाहरण, TLS सेटअप, हार्टबीट अंतराल और लक्ष्य p99 पर एक लोड परीक्षण प्रति गेटवे 50,000 स्वस्थ कनेक्शन साबित करता है। न्यूनतम आवश्यकता 100 गेटवे है। उस मापी गई सीमा के 70% पर संचालन के लिए लगभग 143 की आवश्यकता होती है, जिसे 150 तक पूर्णांकित किया जाता है, साथ ही ज़ोन-विफलता रिजर्व भी। परीक्षण में संदेश, रीकनेक्ट और धीमे क्लाइंट शामिल होने चाहिए; अकेले एक निष्क्रिय-सॉकेट गणना भ्रामक है।
चरण 2: क्लाइंट प्रोटोकॉल और उसकी पहचान को परिभाषित करें।
प्रत्येक डिवाइस एक क्षेत्रीय गेटवे के लिए एक प्रमाणित WebSocket खोलता है। गेटवे जहां लागू हो वहां मूल (origin) को मान्य करता है, फ़्रेम आकार और भेजने की दर को सीमित करता है, प्राधिकरण को ताज़ा करता है, और मृत कनेक्शनों का पता लगाने के लिए पिंग/पोंग प्लस एक लीज का उपयोग करता है। RFC 6455 कनेक्शन यांत्रिकी की आपूर्ति करता है; एप्लिकेशन प्रोटोकॉल अभी भी प्रमाणीकरण, पावती, अनुक्रमण, पुनः प्रयास और बैकप्रेशर का मालिक है।
केंद्रीय फ़्रेम को इस प्रकार व्यक्त किया जा सकता है:
SEND {
conversation_id, client_message_id, body, client_sent_at
}
ACK {
client_message_id, message_id, conversation_seq, accepted_at
}
MESSAGE {
conversation_id, message_id, conversation_seq, sender_id, body, accepted_at
}
SYNC {
device_sync_cursor, limit
}client_message_id एक बार उत्पन्न होता है और उस भेजने वाले डिवाइस से प्रत्येक पुनः प्रयास के लिए पुन: उपयोग किया जाता है। message_id प्राप्तकर्ता डिडुप्लीकेशन के लिए उपयोग की जाने वाली सर्वर पहचान है। conversation_seq एक बातचीत के भीतर प्रदर्शन और कैच-अप क्रम है। accepted_at डायग्नोस्टिक्स के लिए सर्वर समय है, ऑर्डरिंग प्राधिकरण नहीं।
चरण 3: स्वीकार करने से पहले प्रति लॉजिकल सेंड एक बार कमिट करें।
गेटवे SEND को चैट सेवा पर अग्रेषित करता है। सेवा वर्तमान वार्तालाप शार्ड प्राप्त करती है, प्रेषक को प्रमाणित करती है, वर्तमान सदस्यता संस्करण पर सदस्यता की पुष्टि करती है, आकार को मान्य करती है, और प्रति-उपयोगकर्ता और प्रति-बातचीत सीमाएं लागू करती है। शार्ड ओनर उस बातचीत के लिए स्वीकृत राइट्स को क्रमबद्ध करता है।
एक टिकाऊ ट्रांजेक्शन में, यह अगले अनुक्रम को आवंटित करता है, संदेश लिखता है, और एक अद्वितीय मैपिंग लिखता है जैसे कि (sender_device_id, client_message_id) → message_id। एक डुप्लिकेट अनुरोध दूसरा संदेश जोड़ने के बजाय पूर्व परिणाम लौटाता है। केवल एक कोरम-कमिटेड रिकॉर्ड ही ACK प्राप्त करता है। यदि पावती खो जाती है, तो पुनः प्रयास सुरक्षित है। यदि कमिट से पहले स्टोरेज विफल हो जाता है, तो कोई पावती नहीं भेजी जाती है।
संदेशों को conversation_id द्वारा विभाजित किया जाता है और conversation_seq द्वारा क्रमबद्ध किया जाता है। सदस्यता परिवर्तनों को भी क्रमबद्ध किया जाता है, या प्रभावी अनुक्रम सीमाओं को संदर्भित किया जाता है, इसलिए प्राधिकरण अकेले अंततः सुसंगत (eventually consistent) वर्तमान-सदस्य कैश पर निर्भर नहीं करता है। एक फेंस्ड ओनर युग (fenced owner epoch) फ़ेलओवर के बाद एक पुराने ओनर को राइट्स स्वीकार करने से रोकता है।
चरण 4: टिकाऊ कमिट के बाद फ़ैन आउट करें।
कमिट किया गया लॉग एक डिलीवरी कार्य उत्सर्जित करता है। एक कनेक्शन निर्देशिका (user_id, device_id) को एक गेटवे और कनेक्शन लीज पर मैप करती है। एक प्रत्यक्ष बातचीत या अधिकतम 200 के समूह के लिए, फ़ैन-आउट वर्कर संदेश अनुक्रम पर प्रभावी सदस्यता स्नैपशॉट लोड करता है, गेटवे द्वारा ऑनलाइन डिवाइसों को समूहित करता है, और बैच किए गए गेटवे कमांड भेजता है। बॉडी को एक बार संग्रहीत किया जाता है; फ़ैन-आउट प्रति प्राप्तकर्ता एक टिकाऊ बॉडी की प्रतिलिपि बनाने के बजाय एक संदर्भ या संक्षिप्त इवेंट ले जाता है।
गेटवे प्रत्येक कनेक्शन की बंधी हुई आउटबाउंड कतार (bounded outbound queue) में इवेंट रखता है। स्थानीय रूप से ईवेंट स्वीकार करने के बाद एक डिवाइस एक मोनोटोनिक डिलीवरी कर्सर लौटाता है। यदि कोई कनेक्शन धीमा है, तो गेटवे बिना किसी सीमा के बफरिंग बंद कर देता है, इसे रीसिंक के लिए चिह्नित करता है, और इसे एक एप्लिकेशन कारण के साथ बंद कर देता है। टिकाऊ लॉग सत्य बना रहता है, इसलिए इन-मेमोरी लाइव डिलीवरी छोड़ने से संदेश नहीं खोता है।
ऑफ़लाइन उपयोगकर्ता के लिए, सिस्टम एक गोपनीयता-सुरक्षित मोबाइल पुश संकेत भेज सकता है। पुश एक वेक-अप तंत्र है, संदेश संग्रहण या डिलीवरी का प्रमाण नहीं। खोलने पर, क्लाइंट प्रमाणित करता है और टिकाऊ सेवा से सिंक करता है।
चरण 5: रीकनेक्ट और मल्टी-डिवाइस सिंक को स्पष्ट करें।
प्रत्येक डिवाइस एक अपारदर्शी (opaque) device_sync_cursor को बनाए रखता है। GET /sync?after=cursor या समकक्ष फ़्रेम ऑर्डर किए गए वार्तालाप डेल्टास, सदस्यता परिवर्तन, रसीद डेल्टास और एक नया कर्सर लौटाता है। सर्वर को प्रतिक्रिया से छोड़े गए इवेंट्स से आगे कर्सर को आगे नहीं बढ़ाना चाहिए। यदि कोई कर्सर समाप्त हो गया है या अंतर बहुत बड़ा है, तो सर्वर एक कनेक्शन पर अनबाउंड रीप्ले का प्रयास करने के बजाय एक बाउंडेड स्नैपशॉट प्लस निरंतरता टोकन लौटाता है।
लाइव डिलीवरी और सिंक ओवरलैप हो सकते हैं, इसलिए क्लाइंट message_id द्वारा मर्ज करता है और (conversation_id, conversation_seq) द्वारा ऑर्डर करता है। एक नया डिवाइस नीति-अनुमत इतिहास प्राप्त करता है और अपना स्वयं का कर्सर स्थापित करता है। रीड स्टेट उपयोगकर्ता-स्तरीय और प्रति बातचीत मोनोटोनिक है; डिलीवरी स्टेट प्रति डिवाइस रह सकती है। एकत्रीकरण नियमों में यह कहा जाना चाहिए कि "delivered" का अर्थ कोई भी डिवाइस है या प्रत्येक सक्रिय डिवाइस।
चरण 6: रसीदें, प्रेजेंस और टाइपिंग को ईमानदार रखें।
एक रीड अपडेट उच्चतम प्रदर्शित conversation_seq ले जाता है; सर्वर एक सशर्त अधिकतम (conditional maximum) का उपयोग करता है ताकि देर से आने वाले अनुरोध कर्सर को पीछे न ले जा सकें। Matrix विनिर्देश का रसीद मॉडल दिखाता है कि रीड एक डेल्टा क्यों है जो पुरानी स्थिति को बदल देता है और केवल रसीद इस बात का अपर्याप्त प्रमाण क्यों है कि उपयोगकर्ता ने सामग्री देखी।
प्रेजेंस और टाइपिंग एक अलग रास्ते का अनुसरण करते हैं। गेटवे एक छोटी प्रेजेंस लीज को ताज़ा करते हैं। टाइपिंग इवेंट्स अधिकृत, दर-सीमित, एक बातचीत तक सीमित, समेकित और कुछ सेकंड के बाद समाप्त होते हैं। उन्हें अधिभार (overload) के दौरान छोड़ा जा सकता है और वे कभी भी टिकाऊ संदेश लॉग में प्रवेश नहीं करते हैं। हार्टबीट ट्रैफ़िक को राइट स्टॉर्म में बदलने से बचने के लिए "Last seen" को एक स्पष्ट गोपनीयता नीति और मोटे अपडेट की आवश्यकता होती है।
चरण 7: विश्वसनीयता का दावा करने से पहले विफलता पथ डिज़ाइन करें।
- खोया हुआ
ACK: क्लाइंट उसीclient_message_idको पुनः प्रयास करता है; सर्वर संग्रहीत परिणाम लौटाता है। - गेटवे क्रैश: डिवाइस जिटर (jitter) के साथ पुनः कनेक्ट होते हैं और कर्सर से फिर से शुरू होते हैं; कनेक्शन लीज समाप्त हो जाती है।
- फ़ैन-आउट वर्कर क्रैश: टिकाऊ डिलीवरी कार्य का पुनः प्रयास किया जाता है; गेटवे और क्लाइंट डिडुप्लिकेट करते हैं।
- बातचीत ओनर क्रैश: एक नया युग (epoch) और कोरम स्थिति एक प्रतिस्थापन का चुनाव करती है; पुराने ओनर फेंस्ड होते हैं।
- धीमा डिवाइस: बंधी हुई कतारें अनबाउंड मेमोरी का उपभोग करने के बजाय रीसिंक को ट्रिगर करती हैं।
- हॉट बातचीत: एक सीक्वेंसर राइट दर को सीमित करता है। कमिट को बैच करें, हॉट शार्ड को अलग करें, और एक उत्पाद दर सीमा लागू करें; सामान्य हैश विभाजन जोड़ने से एक सख्त अनुक्रम समानांतर नहीं हो सकता है।
- सदस्यता रेस: संदेशों के साथ सदस्यता परिवर्तनों को अनुक्रमित करें और प्रभावी अंतराल के विरुद्ध अधिकृत करें।
- क्षेत्रीय आउटेज: पुराने होम क्षेत्र को फेंस करने के बाद ही बातचीत को प्रचारित प्रतिकृति पर रूट करें; पुनर्प्राप्ति समय और संभावित गैर-स्वीकृत नुकसान स्वीकृत संदेशों के लिए नो-लॉस गारंटी से अलग हैं।
पुनः कनेक्ट के प्रयास जिटर वाले एक्सपोनेंशियल बैकऑफ़ और प्रवेश नियंत्रण (admission control) का उपयोग करते हैं। अन्यथा एक क्षेत्रीय गेटवे पुनरारंभ पांच मिलियन स्वस्थ ग्राहकों को एक हैंडशेक स्टॉर्म में बदल सकता है जो पुनर्प्राप्ति को रोकता है।
चरण 8: स्तरित परीक्षणों और अवलोकन क्षमता के साथ इनवेरिएंट्स को साबित करें।
प्रॉपर्टी परीक्षण पुनः प्रयास, पुन: व्यवस्थित डिलीवरी, सदस्यता परिवर्तन और ओनर युग उत्पन्न करते हैं, फिर प्रति क्लाइंट आईडी एक लॉजिकल संदेश, अद्वितीय बातचीत अनुक्रम, मोनोटोनिक कर्सर, और निष्कासन सीमा के बाद कोई अनधिकृत संदेश नहीं होने का दावा करते हैं। इंटीग्रेशन परीक्षण कमिट से पहले, कमिट के बाद लेकिन पावती से पहले, और फ़ैन-आउट के दौरान प्रक्रिया को क्रैश करते हैं। कैओस परीक्षण एक गेटवे, वर्कर, शार्ड ओनर, ज़ोन और कनेक्शन-निर्देशिका विभाजन को हटाते हैं।
लोड परीक्षण पांच मिलियन दीर्घकालिक कनेक्शन, 230,000 पीक सेंड्स प्रति सेकंड, समूह फ़ैन-आउट, धीमे प्राप्तकर्ता और बड़े पैमाने पर पुनः कनेक्ट का मॉडल बनाते हैं। स्वीकृति विलंबता, लाइव-डिलीवरी विलंबता, सिंक अंतराल, क्लाइंट डिडुप्लीकेशन से पहले और बाद में डुप्लिकेट दर, अनुक्रम अंतराल, हॉट-शार्ड संतृप्ति, आउटबाउंड कतार बाइट्स, रीकनेक्ट प्रवेश, और अनधिकृत-रीड इनकार का निरीक्षण करें। एक कैनरी रोलआउट केवल तभी फैलता है जब स्थायित्व और प्राधिकरण इनवेरिएंट्स स्वच्छ रहते हैं।
उच्च गुणवत्ता वाला नमूना उत्तर
"मैं पहले तीन अलग-अलग परिणामों को परिभाषित करूँगा: टिकाऊ सर्वर स्वीकृति, डिवाइस डिलीवरी और उपयोगकर्ता द्वारा पढ़ना। सेवा केवल कोरम द्वारा संदेश संग्रहीत करने के बाद ही स्वीकार करती है। नेटवर्क डिलीवरी कम से कम एक बार (at least once) बनी रहती है, इसलिए प्रेषक द्वारा उत्पन्न क्लाइंट संदेश आईडी पुनः प्रयासों को इडेम्पोटेंट बनाती है और प्राप्तकर्ता सर्वर संदेश आईडी द्वारा डिडुप्लिकेट करते हैं।
क्लाइंट क्षेत्रीय WebSocket गेटवे से कनेक्ट होते हैं। एक कनेक्शन निर्देशिका फ़ैन-आउट श्रमिकों को बताती है कि कौन सा गेटवे प्रत्येक उपयोगकर्ता डिवाइस को रखता है, लेकिन गेटवे इतिहास के मालिक नहीं हैं। एक चैट सेवा बातचीत आईडी द्वारा वर्तमान फेंस्ड ओनर को प्रत्येक राइट रूट करती है। वह ओनर सदस्यता की फिर से जांच करता है, एक प्रति-बातचीत अनुक्रम आवंटित करता है, और संदेश प्लस इडेम्पोटेन्सी परिणाम को परमाणु रूप से संग्रहीत करता है। असंबंधित बातचीत समानांतर में निष्पादित होती है; एक बहुत ही हॉट बातचीत एक जानबूझकर की गई सीरियल बाधा बनी रहती है।
कमिट के बाद, श्रमिक ऑनलाइन डिवाइसों में फ़ैन आउट करते हैं। विफल या ऑफ़लाइन डिलीवरी को कर्सर-आधारित सिंक API के माध्यम से सुधारा जाता है। लाइव और रीप्ले पथ ओवरलैप हो सकते हैं, इसलिए संदेश आईडी डुप्लिकेट को अवशोषित करती हैं और बातचीत अनुक्रम स्थानीय क्रम को पुनर्स्थापित करते हैं। रीड कर्सर अधिकतम अनुक्रम द्वारा आगे बढ़ते हैं। प्रेजेंस और टाइपिंग समाप्त होने वाली, सर्वोत्तम-प्रयास (best-effort) स्थिति का उपयोग करते हैं और टिकाऊ संदेशों को ब्लॉक नहीं कर सकते हैं।
प्रति दिन 2 बिलियन संदेशों पर, औसत इनग्रेस लगभग 23,000 प्रति सेकंड है; मैं दस गुना पीक पर लगभग 230,000 की योजना बनाऊँगा। प्रॉम्प्ट की 1 KB योजना धारणा पर, लॉजिकल संदेश स्टोरेज लगभग 2 TB प्रति दिन और तीन प्रतिकृतियों के साथ 6 TB है। पांच मिलियन कनेक्शनों के लिए, एक मापा गया 50,000-कनेक्शन गेटवे सीमा 100 बेयर नोड्स या ज़ोन रिजर्व से पहले 70% उपयोग पर लगभग 150 का तात्पर्य है।
मैं खोई हुई पावती, गेटवे और ओनर विफलताओं, पुराने युगों, डुप्लिकेट फ़ैन-आउट, धीमे डिवाइसों, सदस्यता रेसों, एक हॉट समूह और एक रीकनेक्ट स्टॉर्म को मान्य करूँगा। रिलीज गेट स्वीकृत संदेशों का कोई नुकसान नहीं, डिडुप्लीकेशन के बाद कोई डुप्लिकेट लॉजिकल संदेश नहीं, कोई अनुक्रम प्रतिगमन नहीं, सदस्यता अंतराल के बाहर कोई पहुंच नहीं, और प्रतिनिधि लोड के तहत लाइव-डिलीवरी p99 का पालन करना है।"
सामान्य गलतियाँ
- गलती: सर्वर स्वीकृति, डिलीवरी और रीड को एक स्थिति कहना → परिणाम: विश्वसनीयता और अनरीड मेट्रिक्स असत्यापनीय हो जाते हैं → समाधान: अलग-अलग मोनोटोनिक स्थितियों और ओनर्स को परिभाषित करें।
- गलती: नेटवर्क पर एग्जैक्टली-वंस डिलीवरी का वादा करना → परिणाम: खोई हुई पावती या पुनः कनेक्ट एक अस्पष्टीकृत डुप्लिकेट पैदा करता है → समाधान: स्थिर सेंड आईडी और डिडुप्लीकेशन के साथ एट-लीस्ट-वंस ट्रांसपोर्ट का उपयोग करें।
- गलती: सभी संदेशों को विश्व स्तर पर ऑर्डर करना → परिणाम: असंबंधित बातचीत एक अड़चन साझा करती हैं → समाधान: केवल प्रत्येक बातचीत के भीतर एक अनुक्रम निर्दिष्ट करें।
- गलती: टिकाऊ कमिट से पहले स्वीकार करना → परिणाम: एक प्रक्रिया या ज़ोन विफलता चुपचाप एक स्वीकृत संदेश को मिटा सकती है → समाधान: केवल एक कोरम-कमिटेड रिकॉर्ड को स्वीकार (ack) करें।
- गलती: WebSocket गेटवे पर इतिहास संग्रहीत करना → परिणाम: कनेक्शन आंदोलन डेटा आंदोलन बन जाता है और गेटवे हानि इतिहास को खतरे में डालती है → समाधान: बंधी हुई कनेक्शन स्थिति से परे गेटवे को स्टेटलेस रखें।
- गलती: धीमे डिवाइस के लिए अंतहीन बफर करना → परिणाम: एक क्लाइंट गेटवे मेमोरी को समाप्त कर सकता है → समाधान: कतार को सीमित करें, डिस्कनेक्ट करें और टिकाऊ स्टोरेज से रीसिंक करें।
- गलती: प्रेजेंस और टाइपिंग को टिकाऊ लॉग में डालना → परिणाम: समाप्त होने वाला कॉस्मेटिक ट्रैफ़िक लागत बढ़ाता है और संदेशों में देरी कर सकता है → समाधान: एक अधिकृत, दर-सीमित, सर्वोत्तम-प्रयास TTL पथ का उपयोग करें।
- गलती: केवल एक पुराने वर्तमान-सदस्य कैश से अधिकृत करना → परिणाम: हटाए गए उपयोगकर्ता एक रेस में भेज या प्राप्त कर सकते हैं → समाधान: सदस्यता सीमाओं को ऑर्डर करें और उनके विरुद्ध स्वीकृति को फेंस करें।
- गलती: निष्क्रिय सॉकेट गणना द्वारा गेटवे का आकार तय करना → परिणाम: TLS, हार्टबीट, फ़ैन-आउट और रीकनेक्ट योजना को तोड़ते हैं → समाधान: लक्ष्य p99 पर पूर्ण वर्कलोड को बेंचमार्क करें और विफलता हेडरूम आरक्षित करें।
फ़ॉलो-अप प्रश्न और उत्तर
फ़ॉलो-अप 1: आप एंड-टू-एंड एन्क्रिप्शन कैसे जोड़ेंगे?
प्रेषक डिवाइसों पर संदेश बॉडी को एन्क्रिप्ट करें और केवल सिफरटेक्स्ट प्लस आवश्यक रूटिंग मेटाडेटा संग्रहीत करें। प्रत्येक डिवाइस को एक पहचान कुंजी, हस्ताक्षरित डिवाइस सूची और बातचीत कुंजी वितरण की आवश्यकता होती है; किसी डिवाइस या सदस्य को जोड़ने या हटाने से नीति के अनुसार कुंजियाँ घूमती (rotate) या पुनर्वितरित होती हैं। सर्वर अभी भी सिफरटेक्स्ट को अनुक्रमित और रूट कर सकता है, लेकिन सर्वर-साइड खोज, सामग्री मॉडरेशन, रिकवरी, पूर्वावलोकन और दुरुपयोग से निपटना बाधित हो जाता है। डिलीवरी मेटाडेटा, प्रतिभागी सेट, समय और आकार अवलोकन योग्य रह सकते हैं, इसलिए एन्क्रिप्शन मेटाडेटा गोपनीयता कार्य को समाप्त नहीं करता है।
फ़ॉलो-अप 2: क्या एक हॉट समूह को कई सीक्वेंसरों में विभाजित किया जा सकता है?
किसी अन्य ऑर्डरिंग प्राधिकरण के बिना एक सख्त सन्निहित (contiguous) अनुक्रम को संरक्षित करते हुए नहीं। बातचीत को अधिक सामान्य शार्ड्स में हैश करने से अभी भी एक मर्ज या सर्वसम्मति बिंदु शेष रहता है। पहले कमिट को बैच करें और शार्ड को अलग करें, फिर प्रति-बातचीत सीमाएं लागू करें। यदि उत्पाद आंशिक क्रम (partial order) स्वीकार कर सकता है, तो थ्रेड या प्रेषक द्वारा विभाजन करें और कारण संबंधों (causal relationships) को उजागर करें, लेकिन यह कॉन्ट्रैक्ट और क्लाइंट जटिलता को बदल देता है।
फ़ॉलो-अप 3: प्रेषक एक ACK देखता है, लेकिन एक प्राप्तकर्ता एक सप्ताह के लिए ऑफ़लाइन रहता है। क्या संदेश डिलीवर किया गया था?
यह स्वीकार किया गया था, उस डिवाइस पर डिलीवर नहीं किया गया था। टिकाऊ संदेश प्रतिधारण नीति के तहत उपलब्ध रहता है, और एक पुश संकेत डिवाइस को जगा सकता है। पुनः कनेक्ट होने पर डिवाइस अपने कर्सर से सिंक करता है और फिर डिलीवरी की रिपोर्ट करता है। उत्पाद UI और मेट्रिक्स को सर्वर-स्वीकृत, किसी भी डिवाइस पर डिलीवर, सभी सक्रिय डिवाइसों पर डिलीवर और रीड को अलग रखना चाहिए।
फ़ॉलो-अप 4: संपादन (edits) और विलोपन (deletes) ऑर्डरिंग के साथ कैसे इंटरैक्ट करते हैं?
इतिहास को अदृश्य रूप से बदलने के बजाय मूल संदेश को संदर्भित करने वाले नए ऑर्डर किए गए इवेंट्स के रूप में उनका प्रतिनिधित्व करें। क्लाइंट इवेंट स्ट्रीम को वर्तमान दृश्य में जोड़ते हैं। संपादन या विलोपन स्वीकार किए जाने पर प्राधिकरण की जाँच की जाती है, और नीति समय सीमा को परिभाषित करती है और यह भी कि क्या विलोपन सामग्री को हटाता है, एक टॉम्बस्टोन चिह्नित करता है, या द्वितीयक स्टोर से एसिंक्रोनस मिटाने को ट्रिगर करता है।
फ़ॉलो-अप 5: क्या होगा यदि कोई हटाया गया सदस्य पुराने कर्सर के साथ पुनः कनेक्ट होता है?
सिंक सेवा उपयोगकर्ता के सदस्यता अंतराल का मूल्यांकन करती है, न कि केवल कर्सर के कब्जे का। यह केवल उस उपयोगकर्ता के लिए अधिकृत इवेंट्स लौटाती है और इसमें सदस्यता हटाने की सीमा शामिल होती है। एक कर्सर एक अपारदर्शी स्थिति है, कोई क्षमता नहीं। कैश्ड अटैचमेंट और स्थानीय प्रतियों को अलग निरसन और प्रतिधारण अपेक्षाओं की आवश्यकता होती है क्योंकि सर्वर किसी डिवाइस पर पहले से सहेजे गए डेटा को मिटा नहीं सकता है।
फ़ॉलो-अप 6: आप बहुत बड़े सार्वजनिक चैनलों का समर्थन कैसे करेंगे?
200 का समूह फ़ैन-आउट-ऑन-राइट डिज़ाइन अब फिट नहीं बैठता है। चैनल लॉग को एक बार संग्रहीत करें, फ़ॉलोअर्स को कर्सर द्वारा खींचने (pull) दें, केवल कॉम्पैक्ट अपठित या पुश संकेत फ़ैन आउट करें, लोकप्रिय सेगमेंट को कैश करें, और व्यक्तिगत डिलीवरी रसीदों को शिथिल करें। विभाजन, मॉडरेशन, खोज और सेलिब्रिटी-चैनल हॉटस्पॉट प्रथम श्रेणी की समस्याएं बन जाते हैं, इसलिए इसे उसी डिज़ाइन में एक बड़े संख्यात्मक मान के बजाय एक अलग वर्कलोड के रूप में माना जाना चाहिए।