2010-02-06 7 views
16

आवेदन मैं पर काम कर रहा हूँ एक गतिविधि फ़ीड (ज्यादा फेसबुक की तरह) जहां प्रत्येक उपयोगकर्ता अपने मित्रों की गतिविधि देख सकते हैं में गतिविधि फ़ीड आइटम देते। मैं फ्लाई पर दिए गए उपयोगकर्ताओं की गतिविधि स्ट्रीम दिखाने के लिए एक मामूली स्केलेबल तरीका ढूंढ रहा हूं। मैं 'मामूली' कहता हूं क्योंकि मैं इसे केवल एक डेटाबेस (पोस्टग्रेस्क्ल) और के साथ ऐसा करने के लिए देख रहा हूं शायद memcached। उदाहरण के लिए, मैं चाहता हूं कि यह समाधान 100 मित्रों के साथ 200k उपयोगकर्ताओं को स्केल करे।एक मामूली स्केलेबल रास्ता

वर्तमान में, एक मास्टर गतिविधि तालिका दी गतिविधि के लिए प्रदान की गई एचटीएमएल (जिम एक दोस्त जोड़ा, जॉर्ज एक आवेदन, आदि स्थापित) संग्रहीत करता है। यह मास्टर गतिविधि तालिका स्रोत उपयोगकर्ता, एचटीएमएल, और एक टाइमस्टैम्प रखती है।

फिर, एक अलग ('जॉइन') तालिका है जो केवल उस व्यक्ति को पॉइंटर रखती है जो इस गतिविधि को अपने मित्र फ़ीड में देखना चाहिए, और मुख्य गतिविधि तालिका में ऑब्जेक्ट के लिए पॉइंटर होना चाहिए।

तो, अगर मैं 100 दोस्त हैं, और मैं 3 गतिविधियों करते हैं, तो शामिल होने तालिका तो 300 आइटम के लिए बड़ा हो जाएगा।

स्पष्ट रूप से यह तालिका बहुत तेज़ी से बढ़ेगी। यह अच्छी संपत्ति है, हालांकि, उपयोगकर्ता को दिखाने के लिए गतिविधि लाने से एक (अपेक्षाकृत) सस्ती क्वेरी होती है।

अन्य विकल्प सिर्फ मुख्य गतिविधि तालिका रखने के लिए और की तरह कुछ कह रही द्वारा यह क्वेरी करने के लिए है:

select * from activity where source_user in (1, 2, 44, 2423, ... my friend list) 

इस नुकसान यह है कि आप उपयोगकर्ताओं को, जो कभी भी सक्रिय हो सकता है के लिए क्वेरी कर रहे है, और के रूप में अपने मित्र सूची बढ़ती है, यह क्वेरी धीमी और धीमी हो सकती है।

मैं पेशेवरों और दोनों पक्षों की विपक्ष देखते हैं, लेकिन अगर कुछ अतः लोगों को मदद कर सकता है मुझे विकल्पों का वजन और एक तरह से सुझाव है या वे दूसरे मैं सोच रहा हूँ। मैं भी अन्य समाधान के लिए खुला, आदि कर रहा हूँ, हालांकि मैं इसे सरल रखने और CouchDB की तरह कुछ स्थापित नहीं करना चाहते हैं,

बहुत धन्यवाद!

उत्तर

12

मैं केवल मास्टर गतिविधि तालिका की ओर झुक रहा हूं। आपको लगता है कि साथ जाना है, तो यह है कि मैं क्या लागू करने पर विचार होगा:

  1. आप कई गतिविधि टेबल बना सकते हैं और जब डेटाबेस से डेटा प्राप्त करने में सभी एक संघ कर सकते हैं। उदाहरण के लिए, उन्हें मासिक - गतिविधि_2010_02, आदि पर रोल करें। बस अपने उदाहरण से जा रहे हैं - 200 के उपयोगकर्ता x 100 दोस्त x 3 गतिविधियां = 60 मिलियन पंक्तियां। PostgreSQL के लिए प्रदर्शन-आधारित चिंता नहीं है, लेकिन आप आसानी से सुविधा के लिए पूरी तरह से और आखिरकार आसानी से भविष्य के विस्तार के लिए विचार कर सकते हैं।

  2. इस नुकसान यह है कि आप उपयोगकर्ताओं को, जो कभी भी सक्रिय हो सकता है के लिए क्वेरी कर रहे है, और के रूप में अपने दोस्त की सूची होती है, इस क्वेरी धीमी और धीमी हो सकती है।

आप पूरे गतिविधि फ़ीड प्रदर्शित करने के लिए जा रहे हैं, कई बार की शुरुआत करने के लिए वापस जा रहे हैं? आपने मूल प्रश्न में अधिक जानकारी प्रदान नहीं की है, लेकिन मुझे लगता है कि आप टाइम स्टैंप द्वारा क्रमबद्ध अंतिम 10/20/100 आइटम दिखाएंगे। तत्काल प्रतिक्रिया प्रदान करने के लिए कुछ इंडेक्स और LIMIT क्लॉज पर्याप्त होना चाहिए (जैसा कि मैंने अभी तक लगभग 20 मिलियन पंक्तियों वाली तालिका पर परीक्षण किया है)। यह व्यस्त सर्वर पर धीमा हो सकता है, लेकिन यह ऐसा कुछ है जिसे हार्डवेयर और कैशिंग समाधानों के साथ काम किया जाना चाहिए, पोस्टग्रेस वहां बाधा नहीं होने वाला है।

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

select * from activity 
    where ts <= 123456789 
    and source_user in (1, 2, 44, 2423, ... my friend list) 

आप एक तालिका महीनों या वर्षों फैले वापस मिल गया है, तो दोस्तों के आईडी के लिए खोज केवल पहले कहां खंड द्वारा चयनित पंक्तियों के भीतर प्रदर्शन किया जाएगा।

यह ठीक है अगर मैं उन दो समाधानों के बीच चयन करता हूं जो आप अब विचार कर रहे हैं। मैं इस तरह की चीजों को भी देखता हूं:

  1. तालिका के अपने denormalisation पर पुनर्विचार। पूर्व-जेनरेट किए गए HTML आउटपुट को वास्तव में सबसे अच्छा तरीका संग्रहीत करना है? क्या आप इसके बजाए गतिविधियों की लुकअप टेबल और फ्लाई पर टेम्पलेट आउटपुट उत्पन्न करके प्रदर्शन-वार से बेहतर होंगे? प्री-जेनरेटेड एचटीएमएल शुरुआत में बेहतर प्रतीत हो सकता है, लेकिन डिस्क स्टोरेज, एपीआई, भविष्य के लेआउट में बदलाव और एचटीएमएल स्टोर करने जैसी चीजों पर विचार करना शायद आकर्षक नहीं हो सकता है। लुकअप टेबल में आपकी संभावित गतिविधियां हो सकती हैं - एक दोस्त, बदली गई स्थिति इत्यादि जोड़ा गया है, और गतिविधि लॉग उस संदर्भ में होगा और अगर कोई अन्य उपयोगकर्ता गतिविधि में शामिल होता है तो मित्र की आईडी।

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

उम्मीद है कि इससे मदद मिलती है।