मौसम डेटा वेयरहाउस बनाना भाग 1: TimescaleDB में 1 ट्रिलियन पंक्तियों का मौसम डेटा लोड करना
हम जो कर रहे हैं उसका मतलब
मौसम डेटा वेयरहाउस बनाने की वजह
- जलवायु परिवर्तन के संकेतों का विश्लेषण करने के लिए दुनिया भर के ऐतिहासिक मौसम डेटा को इकट्ठा करके उसका विश्लेषण करना उपयोगी लगा
- अगर बड़े पैमाने का मौसम डेटा वेयरहाउस हो, तो यह क्षेत्रवार समझा जा सकता है कि क्या Jakarta वास्तव में अधिक गर्म हुआ है, या तूफान अधिक गंभीर हुए हैं, या Chile कुल मिलाकर अधिक गर्म या अधिक बादलों वाला हुआ है
- इससे यह पता लगाया जा सकता है कि पृथ्वी पर किस क्षेत्र ने सबसे अधिक जलवायु परिवर्तन का अनुभव किया है, और किस प्रकार के परिवर्तन हुए हैं
- इस तरह का वैश्विक विश्लेषण करने के लिए डेटा वेयरहाउस क्वेरी की गति बढ़ानी होगी, और डेटा की मात्रा बहुत बड़ी है
- पहला कदम डेटा को PostgreSQL में लोड करना है। टाइम-सीरीज़ क्वेरी की गति बढ़ाने के लिए TimescaleDB और जियोस्पेशल क्वेरी की गति बढ़ाने के लिए PostGIS आशाजनक लगते हैं
डेटा परिचय
- वास्तविक अवलोकन डेटा नहीं, बल्कि ERA5 climate reanalysis product डेटा का उपयोग किया गया
- ERA5 उन climate model runs का परिणाम है जिन्हें observational data द्वारा constrain किया गया है; जहाँ अवलोकन अधिक हैं वहाँ यह अवलोकनों से मिलता-जुलता है, और जहाँ अवलोकन नहीं हैं वहाँ यह भौतिक रूप से सुसंगत रहता है और जलवायु सांख्यिकी से मेल खाता है
- ERA5, 1940 से पूरी पृथ्वी के लिए 0.25 डिग्री resolution पर प्रति घंटे का डेटा देता है। तापमान, वर्षा, बादलपन, पवन वेग जैसे प्रत्येक variable के लिए 750 मिलियन से अधिक पंक्तियों का डेटा है
- इस डेटा को relational DB में तेज़ी से insert करना आसान नहीं है
डेटा insert करने के तरीके
single-row insert statement
- यह सबसे सरल तरीका है, लेकिन बहुत धीमा है। प्रति सेकंड 3000 insert की दर से पूरा डेटा लोड करने में लगभग 8 साल लगेंगे
- parsing, table/column validation, execution plan, table lock, buffer write, disk write, commit आदि का overhead बहुत अधिक है
multi-value insert
- एक insert statement से कई पंक्तियाँ insert की जाती हैं। इससे network, parsing और execution plan overhead कम होता है
- psycopg3, प्रति सेकंड 25,000~30,000 insert के साथ सबसे तेज़ रहा
- लेकिन फिर भी पूरा डेटा लोड करने में लगभग 10 महीने लगेंगे
copy statement
- bulk data loading के लिए optimized तरीका। यह CSV या binary file से सीधे पढ़कर parsing, planning और WAL usage को optimize करता है
- अगर CSV पहले से मौजूद है, तो सरलता से copy statement इस्तेमाल किया जा सकता है
- psycopg3 का copy प्रति सेकंड 100,000 से अधिक insert कर सकता है। overhead जोड़ने पर भी पूरा डेटा 3 महीने के भीतर लोड किया जा सकता है
- लंबे समय तक high-speed insert को copy से चलाते समय bottleneck पर ध्यान देना ज़रूरी है
parallel copy
- कई copy jobs को parallel चलाकर गति बढ़ाई जाती है
- एक single table में insert पर parallelization का असर बहुत बड़ा नहीं है, इसलिए 16 से अधिक worker पर अतिरिक्त performance gain नहीं मिलता
बाहरी टूल का उपयोग
- pg_bulkload और timescaledb-parellel-copy का benchmark किया गया
- pg_bulkload तेज़ है, लेकिन default रूप से WAL को skip करता है, इसलिए सुरक्षित नहीं है
- timescaledb-parallel-copy कई workers के साथ प्रति सेकंड 300,000 से अधिक पंक्तियाँ सुरक्षित रूप से insert कर सकता है
PostgreSQL settings tuning
- fsync और full_page_writes को बंद करने से disk write से बचकर गति बढ़ सकती है, लेकिन यह जोखिम भरा है
- unlogged tables भी WAL का उपयोग नहीं करतीं, इसलिए तेज़ हैं, लेकिन crash होने पर truncate हो सकती हैं। hypertable को unlogged नहीं बनाया जा सकता
सबसे अच्छा तरीका क्या है?
- psycopg3 के साथ सीधे hypertable में copy करना सबसे अच्छा है। CSV files के लिए timescaledb-parallel-copy का उपयोग करें
- parallelization के लिए 12~16 worker उपयुक्त हैं
- safety rules हटाने पर प्रति सेकंड 460,000 तक संभव है, लेकिन यह जोखिम भरा है
- hardware upgrade से और अधिक गति मिल सकती है
- ClickHouse शायद अधिक तेज़ हो, लेकिन PostgreSQL सीखना था इसलिए TimescaleDB चुना गया
- प्रति सेकंड 460,000 की दर से पूरा डेटा 20 दिनों के भीतर लोड किया जा सकता है
GN⁺ की राय
- ERA5 डेटा को relational DB में डालकर उसका विश्लेषण करने की कोशिश दिलचस्प है। पहले आम तौर पर NetCDF डेटा का सीधे xarray या dask से विश्लेषण किया जाता था, लेकिन डेटा वेयरहाउस बनाने पर अधिक जटिल queries चलाना संभव होगा।
- यह प्रभावशाली है कि लेखक के 5 साल पुराने hardware पर भी प्रति सेकंड 460,000 insert संभव थे। आधुनिक hardware पर प्रति सेकंड 1 मिलियन भी संभव हो सकता है। लेकिन fsync और full_page_writes को बंद करना DB integrity को नुकसान पहुँचा सकता है, इसलिए सावधानी ज़रूरी है.
- PostgreSQL की parallel processing क्षमता single table पर बहुत मददगार नहीं लगती। अगर parallel processing और partitioning को जोड़ा जाए, तो और ऊँची performance मिल सकती है। Citus जैसे Postgres horizontal scaling solutions पर भी विचार किया जा सकता है.
- यह रोचक है कि जलवायु परिवर्तन के विश्लेषण में ERA5 डेटा उपयोगी हो सकता है। जिन क्षेत्रों में observational data कम है, वहाँ के ऐतिहासिक जलवायु विश्लेषण में यह काम आ सकता है। लेकिन ERA5 आखिरकार model output ही है, यही उसकी सीमा है। इसे observations से adjust किया गया है, फिर भी uncertainty को ध्यान में रखना होगा.
- analysis platform के रूप में Snowflake या BigQuery जैसे cloud data warehouse का इस्तेमाल आम है। लेकिन लेखक की तरह अपने hardware के साथ काम करते हुए सीखना भी बहुत मूल्यवान है। खासकर climate data का आकार बहुत बड़ा होता है, इसलिए उसे cloud में ले जाना आसान नहीं है। आगे वास्तविक analysis results देखने की उत्सुकता है.
2 टिप्पणियां
GN+ की राय में सम्मानसूचक भाषा है..?
Hacker News राय
संक्षेप में यह इस प्रकार है:
भू-स्थानिक डेटा विश्लेषण करते समय coordinate system (CRS) और map projection को समझना महत्वपूर्ण है। बड़े पैमाने के भू-स्थानिक कार्यों के लिए Google BigQuery सबसे बेहतर है।
relational DB ग्रिड-आधारित मौसम डेटा के लिए उपयुक्त है या नहीं, यह प्रयोग करके ही पता लगाना चाहिए।
Timescale में Hypertable के धीमे होने का कारण डिफ़ॉल्ट रूप से बनने वाला timestamp कॉलम index हो सकता है।
create_default_indexes=>falseविकल्प से index creation को छोड़ना, या डेटा इनपुट के बाद index बनाना बेहतर है।मौसम डेटा को RDBMS में ले जाने से क्या लाभ मिलता है, इस पर विश्लेषण पर्याप्त नहीं है। Serverless + object storage से भी बहुत तेज़ response speed मिल सकती है।
ERA5 जैसे अधिकांश मौसम/जलवायु datasets नियमित latitude-longitude grid से बने होते हैं, इसलिए उनकी संरचना को पूरी तरह तोड़ देना अच्छा नहीं है। ARCO-ERA5 जैसे cloud-optimized versions का उपयोग करना बेहतर है।
PostgreSQL में WAL को बंद करके और
VACUUM FREEZEकमांड को समय-समय पर चलाने से बड़े पैमाने पर डेटा लोड करते समय performance और बढ़ाई जा सकती है।अगर COPY का उपयोग नहीं किया जा सकता, तो rows को JSON string में encode करके एक single query parameter के रूप में भेजना और
json_to_recordsetका उपयोग करना भी एक अच्छा तरीका है.