सारांश : लगभग 1 मिलियन सक्रिय उपयोगकर्ताओं और 150 मिलियन संग्रहीत गतिविधियों के लिए, मैं इसे सरल रखता हूं:
- अद्वितीय गतिविधियों के भंडारण के लिए एक रिलेशनल डेटाबेस का उपयोग करें (प्रति गतिविधि 1 रिकॉर्ड / "हुई बात") रिकॉर्ड्स को जितना हो सके उतना कॉम्पैक्ट बनाएं। संरचना ताकि आप जल्दी से गतिविधि आईडी या समय की कमी के साथ दोस्त आईडी के एक सेट का उपयोग करके गतिविधियों के एक बैच को पकड़ सकें।
- जब भी कोई गतिविधि रिकॉर्ड बनाई जाती है, तो गतिविधि आईडी को रेडिस पर प्रकाशित करें, आईडी को एक "गतिविधि स्ट्रीम" सूची में प्रत्येक उपयोगकर्ता के लिए जो मित्र / ग्राहक है, जो गतिविधि को देखना चाहिए, को जोड़ रहा है।
किसी भी उपयोगकर्ता के लिए गतिविधि स्ट्रीम प्राप्त करने के लिए क्वेरी Redis और फिर आवश्यकतानुसार db से संबंधित डेटा को पकड़ो। यदि उपयोगकर्ता को समय में बहुत दूर ब्राउज़ करने की आवश्यकता है (यदि आप भी यह पेशकश करते हैं) तो db को क्वेरी करने के लिए वापस गिरें
मैं लगभग 15 मिलियन गतिविधियों से निपटने के लिए एक सादे पुराने MySQL तालिका का उपयोग करता हूं।
यह कुछ इस तरह दिखता है:
id
user_id (int)
activity_type (tinyint)
source_id (int)
parent_id (int)
parent_type (tinyint)
time (datetime but a smaller type like int would be better)
activity_type
मुझे गतिविधि का प्रकार source_id
बताता है , मुझे वह रिकॉर्ड बताता है जो गतिविधि से संबंधित है। इसलिए अगर गतिविधि प्रकार का अर्थ "जोड़ा पसंदीदा" है, तो मुझे पता है कि source_id एक पसंदीदा रिकॉर्ड की आईडी को संदर्भित करता है।
parent_id
/parent_type
मेरे ऐप के लिए उपयोगी होते हैं - वे मुझे बताओ कि गतिविधि से संबंधित है। यदि किसी पुस्तक का पक्ष लिया गया था, तो parent_id / parent_type मुझे बताएगा कि गतिविधि किसी दिए गए प्राथमिक कुंजी (आईडी) के साथ पुस्तक (प्रकार) से संबंधित है
मैं (user_id, time)
उन गतिविधियों के लिए अनुक्रमित और क्वेरी करता हूं जो हैं user_id IN (...friends...) AND time > some-cutoff-point
। आईडी को अलग करना और एक अलग क्लस्टर इंडेक्स का चयन करना एक अच्छा विचार हो सकता है - मैंने इसके साथ प्रयोग नहीं किया है।
सुंदर बुनियादी सामान, लेकिन यह काम करता है, यह सरल है, और आपकी आवश्यकताओं में बदलाव के साथ काम करना आसान है। इसके अलावा, यदि आप MySQL का उपयोग नहीं कर रहे हैं, तो आप बेहतर सूचकांक-वार करने में सक्षम हो सकते हैं।
सबसे हाल की गतिविधियों तक तेजी से पहुंचने के लिए, मैं रेडिस के साथ प्रयोग कर रहा हूं । Redis अपने सभी डेटा इन-मेमोरी को स्टोर करता है, इसलिए आप अपनी सभी गतिविधियों को वहां नहीं रख सकते हैं, लेकिन आप अपनी साइट पर अधिकांश हिट स्क्रीन के लिए पर्याप्त स्टोर कर सकते हैं। प्रत्येक उपयोगकर्ता के लिए सबसे हाल ही में 100 या ऐसा कुछ। मिश्रण में रेडिस के साथ, यह इस तरह काम कर सकता है:
- अपना MySQL गतिविधि रिकॉर्ड बनाएं
- गतिविधि बनाने वाले उपयोगकर्ता के प्रत्येक मित्र के लिए, Redis में उनकी गतिविधि सूची में ID पुश करें।
- प्रत्येक सूची को अंतिम X आइटम पर ट्रिम करें
रेडिस तेज़ है और एक कनेक्शन में पाइपलाइन कमांड का एक तरीका प्रदान करता है - इसलिए 1000 दोस्तों को एक गतिविधि को धकेलने में मिलीसेकंड लगता है।
मैं जिस बारे में बात कर रहा हूं, उसके अधिक विस्तृत विवरण के लिए, रेडिस का ट्विटर उदाहरण देखें: http://redis.io/topics/twitter-one
फरवरी 2011 को अपडेट करें मुझे इस समय 50 मिलियन सक्रिय गतिविधियां मिली हैं और मैंने कुछ भी नहीं बदला है। इसके समान कुछ करने के बारे में एक अच्छी बात यह है कि यह कॉम्पैक्ट, छोटी पंक्तियों का उपयोग करता है। मैं कुछ बदलाव करने की योजना बना रहा हूं, जिसमें उन गतिविधियों के कई और कार्य और अधिक प्रश्न शामिल होंगे और मैं निश्चित रूप से चीजों को तेजी से रखने के लिए रेडिस का उपयोग करूंगा। मैं अन्य क्षेत्रों में रेडिस का उपयोग कर रहा हूं और यह वास्तव में कुछ प्रकार की समस्याओं के लिए अच्छी तरह से काम करता है।
जुलाई 2014 को अपडेट करें हम लगभग 700K मासिक सक्रिय उपयोगकर्ता हैं। पिछले कुछ वर्षों से, मैं प्रत्येक उपयोगकर्ता के लिए अंतिम 1000 गतिविधि आईडी के भंडारण के लिए रेडिस (जैसा कि बुलेटेड सूची में वर्णित है) का उपयोग कर रहा हूं। आमतौर पर सिस्टम में लगभग 100 मिलियन गतिविधि रिकॉर्ड होते हैं और वे अभी भी MySQL में संग्रहीत हैं और अभी भी वही लेआउट हैं। ये रिकॉर्ड हमें कम रेडिस मेमोरी के साथ दूर जाने देते हैं, वे गतिविधि डेटा के रिकॉर्ड के रूप में काम करते हैं, और अगर उपयोगकर्ता कुछ खोजने के लिए समय में आगे पृष्ठ की आवश्यकता होती है तो हम उनका उपयोग करते हैं।
यह एक चतुर या विशेष रूप से दिलचस्प समाधान नहीं था, लेकिन इसने मुझे अच्छी तरह से सेवा दी है।