32 पॉइंट द्वारा xguru 2022-05-16 | 6 टिप्पणियां | WhatsApp पर शेयर करें
  • BoltDB (embedded key-value DB) के निर्माता Ben Johnson अब FlyIO में Litestream पर काम कर रहे हैं
  • full-stack application की पारंपरिक संरचना n-Tier होती है: app server + DB server
    → इस आर्किटेक्चर में SQLite का उपयोग पहले केवल unit test के लिए होता था, लेकिन अब इसे data और persistence layer के रूप में पर्याप्त रूप से इस्तेमाल किया जा सकता है
  • Litestream एक open source टूल है जो replication के जरिए SQLite को full-stack application में उपयोग योग्य बनाता है

application database का संक्षिप्त इतिहास

  • 50 साल बहुत लंबा समय नहीं है, लेकिन software डेटा को कैसे manage करता है इसमें बहुत बड़े बदलाव आए हैं
    → 70 के दशक में relational database को परिभाषित करने वाले "Codd के नियम" थे
    → सारा डेटा tables में होता है, CRUD, schema, SQL language आदि
    → 80 और 90 के दशक में Oracle/DB2/Postgres/MySQL जैसे SQL database विस्फोटक रूप से बढ़े
    → 2000 के दशक के XML database अच्छे नहीं थे, और उसी समय बेहतरीन column DB उभरे
    → 2010 के दशक में बड़े open source distributed DB projects आए, और अब कोई भी cluster बनाकर terabyte स्तर के डेटा पर query चला सकता है

  • database के विकसित होने के साथ, DB को application से जोड़ने की रणनीतियाँ भी विकसित हुईं
    → Codd के बाद से tier-based separation हुआ
    → शुरुआत database tier से हुई
    → फिर memcached और Redis की caching tier आई
    → background job tier (Sidekiq), routing tier (PgBouncer), distribution tier आदि
    → कई tutorials इसे 3-Tier की तरह बताते हैं, लेकिन क्योंकि इसमें कितनी tiers जुड़ेंगी पता नहीं होता, इसलिए इसे "n-Tier" कहा जाता है

  • इन 50 वर्षों में हमने CPU, memory और disk को सैकड़ों गुना तेज़ और सस्ता होते भी देखा है
    → 2010 के दशक की database innovation को वास्तव में परिभाषित करने वाला शब्द "big data" था
    → लेकिन hardware improvements के कारण 2020 तक आते-आते उस concept को बनाए रखना भी कठिन हो गया
    → 1996 में 1GB DB manage करना बहुत बड़ी बात थी, लेकिन 2022 में इसे laptop या t3.micro पर चलाना भी पर्याप्त है

  • जब हम नए DB architecture के बारे में सोचते हैं, तो scalability limits हमें सम्मोहित कर देती हैं
    → अगर petabyte या कम से कम terabyte स्तर का डेटा handle नहीं कर सकते, तो मानो चर्चा में जगह ही नहीं मिलती
    → लेकिन अधिकांश applications, सफल होने पर भी, शायद ही कभी terabyte स्तर का डेटा देखेंगी
    → हम कील ठोकने के लिए jackhammer का उपयोग कर रहे हैं

SQLite की मीठी वापसी

  • एक database है जो इस प्रवृत्ति को अच्छी तरह दर्शाता है
  • यह दुनिया के सबसे प्रसिद्ध SQL DB में से एक है, अमेरिकी Congress Library का आधिकारिक archival format है, reliability और लगभग अकल्पनीय आकार के test suite के लिए मशहूर है, और इसका performance भी शानदार है
  • अब शायद नाम बताने की ज़रूरत नहीं, लेकिन पीछे हाथ उठाने वालों के लिए... यह SQLite की बात है
  • SQLite एक embedded DB है। यह सामान्य architecture tier में मौजूद नहीं होता, बल्कि आपके application server process में link होने वाली एक साधारण library है
    → यह किसी दूसरे server पर निर्भर नहीं करता, बल्कि अपने आप चलने वाला "single-process application" होता है
  • मैं DB बनाने वाला व्यक्ति हूँ, इसलिए मुझे इस तरह के applications में दिलचस्पी है
  • मैंने Go ecosystem का प्रसिद्ध embedded key/value DB, BoltDB, बनाया था
  • BoltDB स्थिर है, और in-process DB से जैसी अपेक्षा होती है वैसा ही nitro लगी खिलौना कार जैसा performance देता है
  • लेकिन BoltDB की सीमाएँ हैं
    → क्योंकि schema Go code में defined होता है, DB migration कठिन हो जाती है। tools आपको खुद बनाने पड़ते हैं। यहाँ तक कि REPL भी नहीं है
  • अगर आप सावधानी रखें, तो इस तरह के DB से बहुत शानदार performance मिल सकता है
  • लेकिन सामान्य उपयोग के लिए शायद आप ऐसे DB को production में नहीं चलाना चाहेंगे
  • मैंने सोचा कि BoltDB को अधिक applications के लिए उपयोगी बनाने के लिए क्या करना चाहिए, और मेरा निष्कर्ष था: "SQLite ठीक इसी काम के लिए बना है"
  • SQLite की भी सीमाएँ हैं। सबसे बड़ी यह कि single-process application में SPOF (Single Point of Failure) होता है: अगर server खो गया, तो database भी खो गया। यह SQLite की कमी नहीं, बल्कि उसका मूल design ही ऐसा है

Enter Litestream

  • SQLite को default के रूप में न अपनाने के पीछे लोगों के दो बड़े कारण हैं
    → पहला, storage failure के खिलाफ resilience
    → दूसरा, बड़े scale पर concurrency
  • Litestream के पास इन दोनों समस्याओं के लिए जवाब है
  • Litestream, SQLite के WAL (Write Ahead Log) mode journaling को नियंत्रित करके काम करता है
  • WAL mode में write operations, SQLite की मुख्य DB file से अलग log file में append होते हैं
  • readers query पूरी करने के लिए WAL file और main DB दोनों देखते हैं
  • सामान्यतः SQLite, WAL से main DB में pages को अपने-आप checkpoint करता है
  • Litestream इस बीच में दखल देता है: auto-checkpoint रोकने के लिए एक अनंत read transaction खोलता है, WAL updates को सीधे capture और replicate करता है, और फिर स्वयं checkpoint trigger करता है

    Litestream के बारे में समझने वाली सबसे महत्वपूर्ण बात यह है कि यह बस SQLite ही है। application standard SQLite का उपयोग करता है; यह dependencies नहीं जोड़ता, queries को parse नहीं करता, और proxy की तरह काम नहीं करता। यह सिर्फ SQLite की journaling और concurrency सुविधाओं का उपयोग करता है। अधिकतर मामलों में आपका code शायद Litestream की मौजूदगी से अनजान रहेगा

  • यह सुनने में जटिल लगता है, लेकिन वास्तव में बहुत सरल है। इस्तेमाल करने पर पता चलता है कि यह बस काम करता है
    $ litestream replicate fruits.db s3://my-bukkit:9000/fruits.db
    $ litestream restore -o fruits-replica.db s3://my-bukkit:9000/fruits.db
  • आम तौर पर लोग SQLite DB को replicate करके S3 में store करने के लिए इसका उपयोग करते हैं
  • इससे operations में बड़ा लाभ मिलता है। आपका DB resilient हो जाता है और उसे आसानी से move या migrate किया जा सकता है
  • लेकिन Litestream से और भी बहुत कुछ किया जा सकता है
  • अगले version में SQLite DBs के बीच real-time replication संभव होगी, जिससे distributed read replica और write-leader DB setup किया जा सकेगा
    → read replica writes को पकड़कर leader की ओर redirect कर सकती है
    → कई applications read-heavy होती हैं, इसलिए यह setup application को globally scalable DB दे सकता है

आपको इस विकल्प को अधिक गंभीरता से लेना चाहिए: application DB के रूप में SQLite

  • मेरी शुरुआती IT नौकरियों में से एक 2000 के दशक की शुरुआत में Oracle DBA की थी
  • मैंने Oracle सीखने के लिए ढेर सारी किताबें और documentation पढ़ने में समय बिताया
  • administrator manual लगभग 1000 pages का था, और वह सैकड़ों documents में से सिर्फ एक था
  • queries optimize करने या writes बेहतर बनाने के तरीके सीखना उस समय बहुत बड़ा फर्क पैदा करता था
  • जब hard disks प्रति सेकंड केवल कुछ दसियों megabytes पढ़ती थीं, तब बेहतर indexes का उपयोग 5 मिनट की query को 30 सेकंड की query में बदल सकता था
  • लेकिन DB optimization सामान्य applications के लिए अब धीरे-धीरे कम महत्वपूर्ण होती जा रही है
  • अगर आपके पास 1GB DB है, तो NVMe disk एक सेकंड से कम में सब कुछ memory में ला सकती है
  • मुझे SQL query optimization पसंद है, लेकिन बहुत से application developers के लिए यह एक dying skill बनती जा रही है
  • ठीक से tune न की गई queries भी कई databases में 1 सेकंड के अंदर चल जाती हैं
  • आधुनिक Postgres एक चमत्कार है। वर्षों तक उसका code पढ़ते हुए मैंने बहुत कुछ सीखा है
  • query optimizer, row-level security policies, 6 प्रकार के indexes आदि
  • अगर आपको ये features चाहिए तो ज़रूर उपयोग करें, लेकिन अधिकांश को इनकी ज़रूरत नहीं होती
  • और अगर आपको Postgres के ये features नहीं चाहिए, तब भी ज़िम्मेदारी बनी रहती है
  • चाहे आप कई accounts इस्तेमाल न करें, फिर भी host-based authentication configure करनी पड़ती है, और firewall खोलना पड़ता है
  • अधिक features का मतलब अधिक documentation भी है, इसलिए वास्तव में जिस software को आप चला रहे हैं उसे समझना कठिन हो जाता है
  • Postgre14 की documentation लगभग 3000 pages की है
  • SQLite, Postgres features का subset देता है। लेकिन सामान्यतः मुझे जो चाहिए उसका 99.9% इसमें है
  • बेहतरीन SQL support, window functions, CTE, full-text search, JSON support आदि
  • और जहाँ feature कम पड़ती है, वहाँ भी data मेरे application के बगल में होने से उसे fetch करके process करना बहुत महँगा नहीं पड़ता
  • दूसरी ओर, सचमुच कठिन समस्याएँ core database features से हल नहीं होतीं
  • इसके बजाय मैं सिर्फ latency और developer experience को optimize करना चाहता हूँ
  • इसलिए SQLite को गंभीरता से विचार करने का एक कारण यह है कि इसका operations model बेहद सरल है
  • database layer डिजाइन करने की जगह आप अपना समय सीधे application code लिखने में लगा सकते हैं
  • लेकिन एक और समस्या है

प्रकाश बहुत धीमा है: The Light is Too Damn Slow

  • हम सैद्धांतिक limits से टकराने लगे हैं। vacuum में प्रकाश 1 millisecond में 186 miles चलता है (Philadelphia से New York तक round trip की दूरी)
  • network switch, firewall, और application protocol layers जोड़ने पर यह और धीमा हो जाता है
  • एक ही AWS region के भीतर Postgres query का latency overhead 1 millisecond तक हो सकता है
  • इसका मतलब यह नहीं कि Postgres धीमा है, बल्कि यह कि हम data movement speed की सीमा तक पहुँच चुके हैं
  • आधुनिक applications HTTP requests handle करती हैं, और कई database queries, business logic या rendering से पहले ही 10ms खर्च कर देती हैं
  • application latency में एक magic number है: 100ms से कम response लगभग instant महसूस होता है
  • snappy application खुश users बनाती है
  • 100ms बहुत लगता है, लेकिन यह बहुत आसानी से खर्च हो जाता है
  • 100ms threshold इतनी महत्वपूर्ण है कि लोग latency घटाने के लिए pages prerender करते हैं और उन्हें CDN पर डालते हैं
  • हमें data को application के और करीब लाना चाहिए। कितना करीब? बहुत ही करीब
  • SQLite सिर्फ आपकी application के same machine पर नहीं होती, बल्कि आपकी application process के अंदर शामिल होती है
  • data को application के बगल में रखने से per-query latency 10~20 microseconds (μ) तक गिर सकती है
  • यानी same region में Postgres query की तुलना में 50~100x तेज़
  • लेकिन बात यहीं खत्म नहीं होती। हमने effectively per-query latency हटा दी है। अब हमारी application तेज़ भी है और सरल भी
  • हम बड़े queries को छोटे, manageable queries में बाँट सकते हैं, और नए features बनाने के लिए N+1 query patterns खोजने में अधिक समय दे सकते हैं
  • latency को कम करना सिर्फ production के लिए नहीं है। पारंपरिक client/server DB के साथ integration testing अक्सर local environment में कई मिनट तक खिंच जाती है, और CI में push करने पर भी यह पीड़ा बनी रहती है
  • code change से test completion तक feedback loop छोटा करने से समय बचता है और development के दौरान focus बना रहता है
  • SQLite में एक-line change करके in-memory चलाना और integration tests को कुछ सेकंड में पूरा करना संभव है

छोटा, तेज़, भरोसेमंद, और globally distributed: इनमें से 4 चुनिए

  • Litestream distributed है, replicated है, और सबसे महत्वपूर्ण बात, समझने में आसान है
  • सच में, "इसे एक बार आज़मा कर देखिए"। जानने के लिए बहुत कम चीज़ें हैं
  • मेरा तर्क यह है:
    • अगर SQLite के लिए stable और easy-to-use replication बना दी जाए, तो केवल SQLite पर चलने वाली full-stack applications बहुत आकर्षक हो जाती हैं
    • जिस दौर में पुराना "Rails से Blog बनाना" tutorial लिखा गया था, उस समय इस विकल्प को नज़रअंदाज़ किया गया, लेकिन आज का SQLite अधिकांश application write load संभाल सकता है, और replicas के जरिए कई instances पर reads को load-balance भी किया जा सकता है
  • Litestream की भी सीमाएँ हैं
    • क्योंकि यह single-node application के लिए बनाया गया है, इसलिए serverless platforms या rolling deploys पर यह बहुत अच्छा काम नहीं करता
    • क्योंकि सभी changes को क्रम से restore करना पड़ता है, DB restore में कुछ मिनट लग सकते हैं
    • हम real-time replication फीचर तैयार कर रहे हैं, लेकिन अलग process model replication guarantees पर fine-grained control में कुछ सीमाएँ लाता है
  • हम इससे बेहतर कर सकते हैं
    • पिछले एक साल में मेरा काम Litestream के core को परिभाषित करना और correctness पर focus करना रहा है
    • मैं अभी जहाँ पहुँचा हूँ उससे संतुष्ट हूँ
    • यह एक साधारण streaming backup tool के रूप में शुरू हुआ था, लेकिन धीरे-धीरे एक stable, distributed database की ओर विकसित हो रहा है
    • Fly.io में मेरा काम इसे और तेज़ और seamless बनाना है
    • Fly.io से अलग भी Litestream में और सुधार आते रहेंगे
  • Litestream को Fly.io में नया घर मिल गया है, लेकिन यह एक open source project बना रहेगा
  • आने वाले कुछ वर्षों के लिए मेरी योजना है कि application कहीं भी चल रही हो, Litestream को और उपयोगी बनाया जाए, और देखा जाए कि SQLite model आखिर कितनी दूर जा सकता है

6 टिप्पणियां

 
nicewook 2022-09-27

इसे एक बार फिर से ध्यान से पढ़ने का मन हो गया।

 
johngrib 2022-05-17

मेरे मन में भी कुछ ऐसा ही विचार आया था, लेकिन यह उससे कहीं ज़्यादा व्यवस्थित और गंभीर है। पढ़ते हुए मैं प्रभावित हुआ। अब Litestream को भी आज़माने का मन है।

 
japansea 2022-05-16

काश, remote से query चलाने की सुविधा भी होती... हाय

 
mrchypark 2022-05-16

यह सुनते ही Elixir याद आ जाता है। यह ऐसा टूल है जिसमें embedded distributed DB और orchestration language level पर दिए जाते हैं, लेकिन यह भविष्य है या नहीं, इस बारे में मुझे पूरा यक़ीन नहीं है।

 
nicewook 2022-05-16

दिलचस्पी से पढ़ा!

 
xguru 2022-05-16

मैंने सोचा था इसे बस हल्का-सा पढ़कर सारांश लिख दूँगा, लेकिन पढ़ते-पढ़ते इतना दिलचस्प लगा कि लिखाई लंबी हो गई।

Litestream - SQLite streaming replication tool

क्या किसी ने SQLite को Primary DB के रूप में इस्तेमाल किया है? इस सवाल के साथ जोड़कर देखें तो अच्छा रहेगा.

कुछ दिन पहले घोषित Cloudflare, Workers के लिए SQL database D1 पेश से भी शायद इसका एक संबंध दिखता है.

HN की टिप्पणियाँ भी देखें: https://news.ycombinator.com/item?id=31318708