18 पॉइंट द्वारा xguru 2024-02-05 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Apple iCloud और CloudKit के लिए Cassandra और FoundationDB का उपयोग करता है
  • ये डेटाबेस अत्यधिक multi-tenancy आर्किटेक्चर में अरबों डेटाबेस स्टोर करते हैं

समय से परे वास्तविक दुनिया के सबक

  • Meta और Apple दोनों यूज़र फीचर्स को सहज बनाने के लिए asynchronous processing का उपयोग करते हैं
  • दोनों कंपनियाँ scalability समस्याओं को हल करने के लिए stateless आर्किटेक्चर का उपयोग करती हैं
  • विश्वसनीयता और availability सुनिश्चित करने के लिए resources को तार्किक रूप से isolate किया जाता है
  • विविध आवश्यकताओं को सरल तरीके से संभाला जाता है
  • developer experience को बेहतर बनाने के लिए abstraction layers बनाई जाती हैं
  • यूज़र को समझकर हर layer, API और design तय किया जाता है

Cassandra

  • Cassandra एक व्यापक column-oriented NoSQL database management system है
  • इसे मूल रूप से Facebook में Facebook inbox search फीचर के लिए विकसित किया गया था
    • दिलचस्प बात यह है कि Meta ने Cassandra के अपने अधिकांश उपयोग को ZippyDB से बदल दिया है
  • iCloud आंशिक रूप से Cassandra का उपयोग करता है, और Apple दुनिया के सबसे बड़े Cassandra deployments में से एक चलाता है
    • 3 लाख से अधिक instances/nodes
    • सैकड़ों petabytes डेटा
    • प्रति cluster 2 petabytes से अधिक
    • प्रति सेकंड लाखों queries
    • हज़ारों applications
  • Apple में Cassandra को अब भी सक्रिय रूप से बेहतर बनाया जा रहा है
  • लेकिन CloudKit + Cassandra को scalability limits का सामना करना पड़ा, इसलिए FoundationDB अपनाया गया

FoundationDB

  • Apple FoundationDB का सार्वजनिक रूप से उपयोग करता है और 2015 में इसे अधिग्रहित किया था
  • FoundationDB बड़े पैमाने के डेटा को संभालने के लिए डिज़ाइन किया गया open source distributed transactional key-value store है
    • यह read/write workloads और write-heavy workloads दोनों के लिए उपयुक्त है
  • Apple CloudKit में FoundationDB Record Layer का व्यापक उपयोग करता है
  • FoundationDB Record Layer structured data storage के लिए Java API प्रदान करता है
  • Record Layer अत्यधिक multi-tenancy को समर्थन देता है

FoundationDB में Record Layer इस्तेमाल करने का कारण

  • FoundationDB distributed systems और concurrency control का काम संभालता है
  • Record Layer एक relational database की तरह काम करता है, जिससे FoundationDB का उपयोग आसान हो जाता है
  • CloudKit सबसे ऊपरी layer पर है और application developers के लिए features और APIs प्रदान करता है
  • Record Layer के ज़रिए Apple बड़े पैमाने की multi-tenancy को समर्थन देता है
    • इसका उपयोग extreme multi-tenancy के लिए किया जाता है, जहाँ हर application के हर user को स्वतंत्र record store दिया जाता है
    • हज़ारों schemas साझा करने वाले अरबों स्वतंत्र databases होस्ट किए जाते हैं

CloudKit FoundationDB और Record Layer का उपयोग कैसे करता है

  • CloudKit में applications को defined schema का पालन करने वाले 'logical containers' के रूप में दर्शाया जाता है
    • यह schema efficient data retrieval और queries के लिए आवश्यक record types, fields और indexes को संक्षेप में बताता है
    • applications CloudKit के भीतर data को 'zones' में व्यवस्थित कर सकती हैं, ताकि records को तार्किक रूप से समूहित किया जा सके और ज़रूरत पड़ने पर client devices के साथ sync किया जा सके
  • हर user को FoundationDB के भीतर एक unique subspace दिया जाता है, और जिस-जिस application के साथ वह user इंटरैक्ट करता है उसके लिए record store बनाया जाता है
    • मूल रूप से CloudKit users की संख्या × applications की संख्या के बराबर विशाल logical databases को मैनेज करता है
    • हर database में अपने records, indexes और metadata का सेट होता है, जिससे कुल संख्या अरबों databases तक पहुँचती है
  • जब CloudKit को client device से request मिलती है, तो load balancing के माध्यम से उसे उपलब्ध CloudKit service process तक पहुँचाया जाता है
    • वह process संबंधित Record Layer record store के साथ इंटरैक्ट करके request को प्रोसेस करता है
  • CloudKit defined application schema को Record Layer के भीतर metadata definitions में बदलता है, जिन्हें अलग metadata store में रखा जाता है
    • इस metadata को CloudKit-विशिष्ट system fields से समृद्ध किया जाता है, जो record creation, modification time और record किस zone में स्टोर है, यह ट्रैक करते हैं
    • हर zone के भीतर records तक कुशल पहुँच के लिए primary key के आगे zone name को prefix के रूप में जोड़ा जाता है
    • user-defined indexes के साथ-साथ CloudKit 'system indexes' भी मैनेज करता है, जैसे record type के हिसाब से size ट्रैक करने वाले indexes, जिनका उपयोग storage quota management जैसे आंतरिक उद्देश्यों के लिए होता है

FoundationDB और Record Layer को साथ इस्तेमाल करने से Apple की वे 4 बड़ी समस्याएँ हल हुईं जिन्हें केवल Cassandra से सुलझाया नहीं जा सकता था

1. व्यक्तिगत full-text search समस्या का समाधान

  • FoundationDB personalized full-text search को समर्थन देता है, ताकि users अपने डेटा तक तेज़ी से पहुँच सकें
  • FoundationDB के key ordering का उपयोग करके text की शुरुआत (prefix matching) को तेज़ी से खोजा जा सकता है, और अतिरिक्त overhead के बिना अधिक जटिल searches भी की जा सकती हैं, जैसे proximity search और phrase search, जिनमें पास-पास या किसी खास क्रम में मौजूद शब्द खोजे जाते हैं
  • पारंपरिक search systems में search index को up-to-date रखने के लिए अक्सर background में अतिरिक्त processes चलानी पड़ती हैं, लेकिन Apple की system सब कुछ real time में संभालती है, इसलिए डेटा बदलते ही search index तुरंत अपडेट हो जाता है और अतिरिक्त steps की ज़रूरत नहीं पड़ती

2. high-concurrency zone समस्या का समाधान

  • CloudKit FoundationDB का उपयोग करके एक साथ होने वाले बहुत सारे updates को सहज रूप से संभालता है
  • पहले Cassandra का उपयोग करते समय CloudKit कई devices के बीच data sync करने के लिए हर zone के changes को ट्रैक करने वाले special index पर निर्भर था
    • जब किसी device को data update करना होता, तो वह नया क्या है यह देखने के लिए इस index की जाँच करता
    • लेकिन एक साथ कई updates होने पर conflicts पैदा हो सकते थे
  • FoundationDB का उपयोग करने पर CloudKit एक विशेष प्रकार के index का उपयोग करता है, जो conflicts पैदा किए बिना हर change का सटीक क्रम ट्रैक करता है
    • यह हर change को एक unique 'version' देकर किया जाता है, और sync की ज़रूरत पड़ने पर CloudKit इन versions को देखकर तय करता है कि device ने कौन से updates मिस किए
  • load को अधिक समान रूप से बाँटने के लिए अगर CloudKit को data को कई storage clusters के बीच स्थानांतरित करना पड़े, तो स्थिति जटिल हो जाती है क्योंकि हर cluster के version numbers मेल नहीं खाते
    • इसे हल करने के लिए CloudKit हर user के data को एक 'move count' देता है, जिसे 'incarnation' कहा जाता है, और जब भी data नए cluster में जाता है यह बढ़ जाता है
    • हर record update में user का वर्तमान 'incarnation' number शामिल होता है, इसलिए migration के बाद भी CloudKit incarnation और version number दोनों देखकर सही update order समझ सकता है
  • नई system में स्विच करते समय CloudKit को ऐसे पुराने data को संभालना पड़ा जिनमें ये version numbers नहीं थे
    • लेकिन इस समस्या को इस तरह समझदारी से हल किया गया कि पुराने system के updates को नई system के updates से पहले sort किया जा सके
    • इससे apps में जटिल बदलाव करने या पुराना code बनाए रखने की ज़रूरत नहीं पड़ी
    • सही history order बनाए रखने के लिए incarnation, version और पुराने update counter values को साथ में देखा गया

3. high-latency query समस्या का समाधान

  • FoundationDB को कम latency के बजाय high concurrency के लिए डिज़ाइन किया गया है। यानी यह individual operations की गति पर कम और एक साथ बहुत सारे operations संभालने पर अधिक केंद्रित है
  • इस design का पूरा लाभ लेने के लिए Record Layer कई कामों को 'asynchronously' करता है
    • यानी future completion वाले tasks को queue में डालकर इस बीच दूसरे काम किए जा सकते हैं
    • यह approach इन tasks के दौरान होने वाली delays को छिपाने में मदद करती है
  • लेकिन FoundationDB database से संवाद करने के लिए जिस tool का उपयोग करता है, वह networking के लिए single thread का उपयोग करता है और एक समय में एक ही काम करने के लिए डिज़ाइन किया गया है
    • पहले के versions में इस setup की वजह से system में traffic congestion होता था, क्योंकि सभी operations उसी network thread पर अपनी बारी का इंतज़ार करते थे
    • चूँकि Record Layer भी इसी single-thread approach का उपयोग कर रहा था, इसलिए bottleneck बनता था
  • इसे बेहतर करने के लिए Apple ने इस network thread पर workload कम किया
    • अब system queue बनाए बिना database के साथ कई पहलुओं पर एक साथ काम करता है, इसलिए complex operations तेज़ हो गए
    • इससे latency या दिखाई देने वाली धीमापन भी छिप जाता है, क्योंकि system दूसरे operations शुरू करने से पहले एक operation के पूरा होने का इंतज़ार नहीं करता

4. conflicting transactions समस्या का समाधान

  • FoundationDB में 'transaction conflict' तब होता है जब एक transaction किसी विशेष key को पढ़ रहा हो और उसी समय दूसरा transaction उसी key को modify कर दे
    • FoundationDB उन key sets पर नियंत्रण की सुविधा देता है जो read या write के समय ऐसे conflicts पैदा कर सकते हैं, जिससे इन्हें बारीकी से मैनेज किया जा सकता है
  • अनावश्यक conflicts से बचने का एक सामान्य तरीका है कई keys पर ऐसे special reads करना जो conflicts पैदा नहीं करते, यानी 'snapshot' reads
    • यदि इस read में कोई महत्वपूर्ण key मिलती है, तो transaction पूरे range के बजाय केवल उन specific keys को flag करता है जहाँ संभावित conflict हो सकता है
    • इससे transaction केवल उन्हीं बदलावों से प्रभावित होता है जो वास्तव में परिणाम के लिए महत्वपूर्ण हैं
  • Record Layer इस strategy का उपयोग ranking index system के हिस्से के रूप में skip list नाम की संरचना को कुशलतापूर्वक मैनेज करने के लिए करता है
    • लेकिन इन conflict ranges को manually सेट करना मुश्किल हो सकता है, खासकर जब वे application की मुख्य logic के साथ मिश्रित हों, जिससे पहचानना कठिन bugs पैदा हो सकते हैं
    • इसलिए FoundationDB पर बने systems में इन patterns को संभालने के लिए custom indexes जैसे higher-level tools बनाना बेहतर है
    • यह approach उस स्थिति से बचने में मदद करती है जहाँ conflict rules को ढीला करने की ज़िम्मेदारी हर client application पर छोड़ दी जाए, जिससे गलतियाँ और असंगतियाँ पैदा हो सकती हैं

1 टिप्पणियां

 
xguru 2024-02-05

Hacker News की राय

  • एक Hacker News उपयोगकर्ता ने Apple में काम करते समय डेटाबेस और file system के बीच के अंतर पर अपनी समझ साझा की। उन्होंने कहा कि डेटाबेस और file system मूल रूप से एक ही काम करते हैं और खास समस्याओं को हल करने के लिए किए गए optimization हैं। उदाहरण के लिए, iCloud दिखाता है कि डेटाबेस के आधार पर file system को कैसे परिभाषित किया जा सकता है। इस उपयोगकर्ता ने वीडियो स्टोरेज के लिए Cassandra इस्तेमाल करने का अनुभव भी साझा किया।

  • एक अन्य उपयोगकर्ता ने अपनी पिछली कंपनी में FoundationDB और RecordLayer का उपयोग करके transactional catalog system बनाने का अनुभव बताया। यह सिस्टम बहुत प्रभावी था, और gRPC तथा Protobuf का उपयोग करना स्वाभाविक लगा। हालांकि, उन्होंने यह भी कहा कि FoundationDB को बड़े पैमाने पर चलाने की entry barrier काफी ऊँची है।

  • एक उपयोगकर्ता ने माना कि Apple Notes की sync सुविधा markdown-आधारित note application की तुलना में conflict को बेहतर तरीके से संभालती है। उन्होंने बताया कि इसी वजह से वे अंततः Apple Notes पर चले गए।

  • FoundationDB पर पहले की पोस्टों का भी उल्लेख किया गया। इनमें FoundationDB के distributed key-value store, Record Layer, Apple द्वारा उसके अधिग्रहण, और FoundationDB कैसे काम करता है तथा उसकी विशेषताओं से जुड़े लिंक शामिल थे।

  • cloud-आधारित storage और collaboration की ओर धीरे-धीरे बढ़ रहे native desktop software की architecture के बारे में एक दिलचस्प बिंदु उठाया गया। schema change और version migration को अच्छी तरह संभालना महत्वपूर्ण है, क्योंकि यह बड़े पैमाने पर और बिना admin के हस्तक्षेप के होता है।

  • एक उपयोगकर्ता ने इच्छा जताई कि iCloud में Time Machine backup स्टोर करने की सुविधा होनी चाहिए।

  • चूँकि FoundationDB, SQLite पर आधारित है, इसलिए इस बात पर जिज्ञासा जताई गई कि क्या HCTree engine को FoundationDB में लागू किया जा सकता है। HCTree में SQLite की read/write performance को 10 गुना तक बेहतर बनाने की क्षमता हो सकती है।

  • iCloud उपयोगकर्ताओं की फाइलों को जिस तरह संभालता है, उसे लेकर असंतोष भी जताया गया। कभी-कभी iCloud जगह खाली करने के लिए हाल ही में इस्तेमाल की गई फाइलों, apps और photos को अपने-आप cloud में भेज देता है, जो समस्या बन सकता है।

  • एक उपयोगकर्ता ने बैंक में काम करते समय इस्तेमाल किए गए Hyperion नामक reporting system को याद किया। यह सिस्टम हर रिपोर्ट के लिए एक नया डेटाबेस बनाता था। उस समय यह अजीब लगा था, लेकिन अब पीछे मुड़कर देखने पर उन्हें लगा कि यह अपने समय से आगे का तरीका था।