- सिस्टम डिज़ाइन करते समय perfect consistency, availability, low latency और high throughput को एक साथ पूरी तरह हासिल करना व्यावहारिक रूप से बहुत कठिन होता है
- एप्लिकेशन के अनुरूप सही balance point ढूंढकर उपयुक्त डिज़ाइन चुनना महत्वपूर्ण है
- Bluesky ने following feed/timeline डिज़ाइन में write performance बेहतर करने के लिए consistency का कुछ हिस्सा त्यागने वाला trade-off अपनाया
- इसके परिणामस्वरूप, उपयोगकर्ताओं पर नकारात्मक असर डाले बिना P99 latency 96% से अधिक घट गई
टाइमलाइन fanout
- Bluesky में जब कोई उपयोगकर्ता पोस्ट करता है, तो सिस्टम उसे index करता है, database में store करता है, और API response के माध्यम से उपलब्ध कराता है
- साथ ही यह पोस्ट हर follower की timeline table में insert करने की “fanout” प्रक्रिया से गुजरती है
- इसमें follower list को fetch करने के बाद, हर follower की timeline table में reverse-order insertion किया जाता है
- timeline table उपयोगकर्ता-आधारित partitioning के साथ distributed DB (ScyllaDB) में store होती है, और high availability के लिए कई shards में replicate की जाती है
- हर उपयोगकर्ता अलग shard पर assign हो सकता है
- storage space बचाने के लिए, एक निश्चित लंबाई से आगे बढ़ने वाली timelines से पुराने post references को नियमित रूप से हटाया जाता है
hot shard समस्या
- Bluesky के लगभग 3.2 करोड़ उपयोगकर्ता हैं, और timeline database सैकड़ों shards में विभाजित है
- लाखों उपयोगकर्ताओं वाले सिस्टम में, ऐसे उपयोगकर्ता मौजूद हो सकते हैं जिनके following संबंध असामान्य रूप से बहुत अधिक हों
- उदाहरण: ऐसा उपयोगकर्ता जो लाखों नहीं तो कम से कम कई लाख accounts को follow करता हो
- एक shard में कई उपयोगकर्ताओं की timelines साथ में store होती हैं
- यदि कोई विशेष उपयोगकर्ता बहुत अधिक writes उत्पन्न करता है, तो वह shard overload होकर “hot shard” बन जाता है
- ऐसे hot shards पर write या read operations की भीड़ लग जाती है, और उसी shard के दूसरे उपयोगकर्ताओं तक भी latency फैल जाती है
latency का संचय
- यदि किसी उपयोगकर्ता के 2,000,000 followers हों, तो writes को क्रमवार करने पर 20 मिनट से अधिक लग सकते हैं
- इसे कम करने के लिए fanout को parallel करने पर average latency कम हो जाती है
- लेकिन P99 latency (लगभग 15 milliseconds या उससे अधिक) बार-बार होने पर पूरा parallel job धीमा हो सकता है
- followers बहुत अधिक होने पर, P99 या P99.9 latency के कारण कुल fanout time सबसे खराब स्थिति में कई मिनट से लेकर कई दसियों मिनट तक बढ़ सकता है
Lossy timeline
- जिन उपयोगकर्ताओं की following संख्या अत्यधिक अधिक है, उन्हें हर पोस्ट को बिल्कुल सही क्रम में दिखाना व्यवहारिक रूप से संभव नहीं है
- इंसान के लिए भी वास्तव में सभी पोस्ट consume करना कठिन है
- इसलिए, एक निश्चित threshold (उदाहरण:
reasonable_limit) से अधिक following वाले उपयोगकर्ताओं की timeline में कुछ writes को probabilistically “drop” करने का तरीका अपनाया गया
loss_factor = min(reasonable_limit / num_follows, 1) फ़ॉर्मूला उपयोग किया जाता है
- fanout के दौरान random value बनाई जाती है, और यदि वह
loss_factor से बड़ी हो, तो timeline write छोड़ दी जाती है
- इससे किसी विशेष उपयोगकर्ता की timeline पर होने वाली अत्यधिक writes सीमित होती हैं और पूरे shard की performance गिरने से बचती है
caching के बारे में
- timeline writes प्रति सेकंड दस लाख से अधिक हो सकती हैं, इसलिए हर write पर उपयोगकर्ता की following count सीधे DB से पूछना बहुत भारी पड़ता है
- इसके बजाय Redis में high-following accounts को sorted set के रूप में cache किया जाता है
- fanout service instances हर 30 सेकंड में इस cached जानकारी को memory में load करते हैं
- नतीजतन, fanout प्रक्रिया के दौरान भी high-following उपयोगकर्ताओं की जानकारी तेज़ी से प्राप्त की जा सकती है
- क्योंकि cached जानकारी का पूरी तरह ताज़ा होना ज़रूरी नहीं है, यह थोड़ा-सा अपूर्णता स्वीकार कर performance और scalability बढ़ाने का तरीका है
परिणाम
- lossy timeline लागू करने के बाद Timelines database में hot shards लगभग पूरी तरह गायब हो गए
- fanout के एक page को process करने में लगने वाली P99 latency 90% से अधिक कम हो गई
- कुल fanout job time में, P99 के आधार पर 5~10 मिनट लेने वाला काम 10 सेकंड से कम में सिमट गया
- इससे यह दिखता है कि consistency का कुछ हिस्सा त्यागकर भी service users की अपेक्षाएँ पूरी की जा सकती हैं और large-scale scalability बनाए रखी जा सकती है
- Bluesky timeline architecture में अभी भी सुधार की गुंजाइश है, लेकिन इस बदलाव ने write throughput और scalability को काफी बढ़ा दिया है
1 टिप्पणियां
Hacker News राय
सिस्टम पसंद करने वाले व्यक्ति के रूप में, मुझे इस तरह के लेख पसंद आते हैं। "सब कुछ परफेक्ट होना चाहिए" वाली सोच में फँसना आसान है
यह hybrid तरीके से account की popularity के आधार पर timeline implement क्यों नहीं करते, यह जानने की जिज्ञासा है
दिलचस्प समस्या के लिए दिलचस्प समाधान है। इसे साझा करने के लिए धन्यवाद
consistency को sacrifice करने वाली इस strategy को लेकर जिज्ञासा है। पढ़ने या लिखने के समय full fan-out के अलावा किसी और तरीके पर विचार है या नहीं, यह जानना चाहता हूँ
सभी users जिन हजारों users को follow करते हैं, उनके हर post को पूरी तरह chronological order में देना ज़रूरी नहीं है, लेकिन timeline में हमेशा नया content बना रहे, इसके लिए पर्याप्त content देना तर्कसंगत है
hot shard समस्या से बचने के लिए followers की संख्या सीमित करने का तरीका कैसे काम करेगा, यह जानने की जिज्ञासा है
AWS के पास इस समस्या के लिए एक अच्छा सामान्य तरीका है
जो accounts लाखों users को follow करते हैं, वे साफ तौर पर content scrape करने वाले bot accounts हैं। मैं तो उन्हें block करके बात खत्म कर देता
जब सीधे user profile पर जाकर सभी posts देखते हैं, तो कभी-कभी ऐसे posts मिलते हैं जो timeline में होने चाहिए थे लेकिन नहीं थे
यह जानने की जिज्ञासा है कि fan-out को इस तरह क्यों implement किया गया जहाँ हर "page" अगला page fetch करने को block करता है