design patterns अधिसूचना प्रणाली का निर्माण




व्हाट इस डिजाईन (3)

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

तो ... हमारे पास कुछ आवश्यकताएं हैं:

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

ठीक है तो मैं क्या सोच रहा था कि मुझे कुछ प्रकार की कतार बनाना चाहिए जहां मैं घटनाओं को संग्रहीत करता हूं। तो मेरे पास पृष्ठभूमि की नौकरी होगी ( gearman ?) जो उस कतार को gearman और उन घटनाओं के आधार पर अधिसूचनाएं उत्पन्न करेगी। यह नौकरी प्रत्येक उपयोगकर्ता के लिए डेटाबेस में सूचनाएं संग्रहीत करेगी (इसलिए यदि कोई ईवेंट 10 उपयोगकर्ताओं को प्रभावित करता है, तो 10 अलग-अलग अधिसूचनाएं होंगी)। फिर जब उपयोगकर्ता अधिसूचनाओं की सूची के साथ एक पृष्ठ खोलता है तो मैं उनके लिए उन सभी अधिसूचनाओं को पढ़ता हूं (हम इसे 100 नवीनतम अधिसूचनाओं तक सीमित करने के बारे में सोचते हैं) और उन्हें एक साथ समूहित करते हैं और फिर अंततः उन्हें प्रदर्शित करते हैं।

जिन चीजों से मैं इस दृष्टिकोण के बारे में चिंतित हूं:

  • नरक के रूप में जटिल :)
  • डेटाबेस यहां सबसे अच्छा भंडारण है (हम MySQL का उपयोग कर रहे हैं) या मुझे कुछ और उपयोग करना चाहिए (रेडिस भी एक अच्छे फिट की तरह दिखता है)
  • मुझे अधिसूचना के रूप में क्या स्टोर करना चाहिए? यूज़र आईडी, यूजर आईडी जिसने इवेंट शुरू किया, इवेंट का प्रकार (ताकि मैं उन्हें समूहित कर सकूं और उपयुक्त टेक्स्ट प्रदर्शित कर सकूं) लेकिन फिर मुझे नहीं पता कि अधिसूचना के वास्तविक डेटा को कैसे स्टोर किया जाए (उदाहरण के लिए यूआरएल और छवि का शीर्षक पसंद किया गया था)। अगर मैं अधिसूचना उत्पन्न करता हूं तो मुझे उस जानकारी को "सेंकना" चाहिए, या मुझे रिकॉर्ड (छवि, प्रोफ़ाइल, ...) की आईडी को प्रभावित करना चाहिए और अधिसूचना प्रदर्शित करते समय डीबी से जानकारी खींचना चाहिए।
  • प्रदर्शन यहां ठीक होना चाहिए, भले ही मुझे अधिसूचना पृष्ठ प्रदर्शित करते समय 100 नोटिफिकेशन ऑन-द-फ्लाई को संसाधित करना पड़े
  • प्रत्येक अनुरोध पर संभावित प्रदर्शन समस्या क्योंकि मुझे उपयोगकर्ता को अपठित अधिसूचनाओं की संख्या प्रदर्शित करना होगा (जो स्वयं में एक समस्या हो सकती है क्योंकि मैं एक साथ नोटिफिकेशन समूहबद्ध करता हूं)। यह टाला जा सकता है हालांकि अगर मैंने पृष्ठभूमि में अधिसूचनाओं (जहां उन्हें समूहित किया गया है) का दृश्य उत्पन्न किया है, तो उड़ान भरने पर नहीं

तो आप मेरे प्रस्तावित समाधान और मेरी चिंताओं के बारे में क्या सोचते हैं? कृपया टिप्पणी करें यदि आपको लगता है कि मुझे कुछ और उल्लेख करना चाहिए जो यहां प्रासंगिक होगा।

ओह, हम अपने पेज के लिए PHP का उपयोग कर रहे हैं, लेकिन मुझे लगता है कि यह एक बड़ा कारक नहीं होना चाहिए।


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

आपकी चिंताओं के बारे में मैं क्या सोचता हूं:

  • हां, एक अधिसूचना प्रणाली जटिल है, लेकिन हालांकि नरक के रूप में नहीं। आप इस तरह के सिस्टम मॉडलिंग और कार्यान्वयन पर कई अलग-अलग दृष्टिकोण प्राप्त कर सकते हैं, और वे एक माध्यम से उच्च स्तर की जटिलता तक हो सकते हैं;

  • व्यक्तिगत रूप से, मैं हमेशा डेटाबेस-संचालित सामग्री बनाने की कोशिश करता हूं। क्यूं कर? क्योंकि मैं जो भी हो रहा है उसका पूरा नियंत्रण रखने की गारंटी दे सकता हूं - लेकिन यह सिर्फ मुझे है, आप डेटाबेस संचालित दृष्टिकोण के बिना नियंत्रण कर सकते हैं; मेरा विश्वास करो, आप उस मामले पर नियंत्रण चाहते हैं;

  • मुझे आपके लिए एक असली मामला उदाहरण दें, ताकि आप कहीं से शुरू कर सकें। पिछले वर्ष में मैंने किसी प्रकार के सोशल नेटवर्क में एक अधिसूचना प्रणाली का मॉडल और कार्यान्वित किया है (बिल्कुल फेसबुक की तरह नहीं)। जिस तरह से मैंने अधिसूचनाओं को स्टोर किया था? मेरे पास notifications तालिका थी, जहां मैंने target_user_id (उपयोगकर्ता की आईडी जो अधिसूचना उत्पन्न कर रहा है) रखा है, target_user_id (स्पष्ट प्रकार है, है ना?), notification_type_id (जो अधिसूचना प्रकारों के साथ एक अलग तालिका में संदर्भित है) ), और उन सभी आवश्यक चीजें जिन्हें हमें अपनी टेबल भरने की आवश्यकता है (टाइमस्टैम्प, झंडे, आदि)। मेरी notification_types तालिका एक notification_templates टेम्पलेट्स तालिका के साथ संबंध रखने के लिए प्रयोग की जाती है, जो प्रत्येक प्रकार की अधिसूचना के लिए विशिष्ट टेम्पलेट संग्रहीत करता है। उदाहरण के लिए, मेरे पास एक POST_REPLY प्रकार था, जिसमें एक टेम्पलेट प्रकार था जैसे {USER} HAS REPLIED ONE OF YOUR #POSTS । वहां से, मैंने {} को एक चर के रूप में और # संदर्भ संदर्भ के रूप में माना;

  • हां, प्रदर्शन करना चाहिए और ठीक होना चाहिए। जब आप अधिसूचनाओं के बारे में सोचते हैं तो आप सिर से पैर की अंगुली तक धक्का देने वाले सर्वर के बारे में सोचते हैं। या तो अगर आप AJAX अनुरोधों या जो कुछ भी कर रहे हैं, तो आपको प्रदर्शन के बारे में चिंता करने की आवश्यकता होगी। लेकिन मुझे लगता है कि यह दूसरी बार चिंता है;

वह मॉडल जिसे मैंने डिजाइन किया है, ज़ाहिर है, केवल एक ही नहीं जिसे आप अनुसरण कर सकते हैं, न तो सर्वश्रेष्ठ भी। मुझे उम्मीद है कि मेरा जवाब, कम से कम, आपको सही दिशा में ले जाएगा।


╔════════════════════╗
║notification        ║
╟────────────────────╢
║Username            ║
║Object              ║
║verb                ║
║actor               ║
║isRead              ║
╚════════════════════╝

यह 2 संग्रह होने के बजाय एक अच्छा जवाब दिखता है। आप उपयोगकर्ता नाम, ऑब्जेक्ट द्वारा क्वेरी कर सकते हैं और नई घटनाएं प्राप्त करने के लिए पढ़ सकते हैं (जैसे 3 लंबित मित्र अनुरोध, 4 प्रश्न पूछे गए आदि ...)

अगर इस स्कीमा में कोई समस्या है तो मुझे बताएं।


एक अधिसूचना किसी चीज़ (ऑब्जेक्ट = इवेंट, दोस्ती ..) के बारे में है (क्रिया = जोड़ा, अनुरोध किया ..) किसी के द्वारा (अभिनेता) और उपयोगकर्ता (विषय) को सूचित किया। यहां एक सामान्यीकृत डेटा संरचना है (हालांकि मैंने मोंगोडीबी का उपयोग किया है)। आपको कुछ उपयोगकर्ताओं को परिवर्तनों के बारे में सूचित करने की आवश्यकता है। तो यह प्रति उपयोगकर्ता सूचनाएं है .. जिसका अर्थ है कि यदि 100 उपयोगकर्ता शामिल थे, तो आप 100 अधिसूचनाएं उत्पन्न करते हैं।

╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
║notification ║      ║notification_object║      ║notification_change ║
╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
║ID           ║—1:n—→║ID                 ║—1:n—→║ID                  ║
║userID       ║      ║notificationID     ║      ║notificationObjectID║
╚═════════════╝      ║object             ║      ║verb                ║
                     ╚═══════════════════╝      ║actor               ║
                                                ╚════════════════════╝

(समय फ़ील्ड जोड़ें जहां आप फिट देखते हैं)

यह मूल रूप से प्रति ऑब्जेक्ट को बदलने के लिए मूल रूप से है, ताकि आप कह सकें कि "आपके पास 3 मित्र अनुरोध हैं"। और प्रति अभिनेता समूहिंग उपयोगी है, ताकि आप कह सकें "उपयोगकर्ता जेम्स बॉन्ड ने आपके बिस्तर में बदलाव किए हैं"। यह आपकी पसंद के अनुसार अधिसूचनाओं का अनुवाद और गिनती करने की क्षमता भी देता है।

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

चूंकि अधिसूचना साइट पर उपयोगकर्ताओं के लिए रीयलटाइम के करीब हैं, इसलिए मैं उन सभी श्रोताओं के लिए नोडजेस को php pushing अद्यतन के साथ nodejs + websockets क्लाइंट के साथ जोड़ दूंगा क्योंकि परिवर्तन जोड़ा जाता है।





design