चल दर।
मैं परामर्श के लिए पहुंचने वाले ग्राहकों के लिए डेटा नमूने तैयार करने के लिए एक स्क्रिप्ट विकसित कर रहा था। नमूने में प्रत्येक फ़ाइल में 100 पंक्तियाँ हैं, और वे 55 स्थानों में विभाजित हैं। मेरी क्वेरी इस तरह दिखती है
SELECT * FROM `project.dataset.table` WHERE ts BETWEEN TIMESTAMP("2022-12-01") AND TIMESTAMP("2023-02-28") AND locale = "US" LIMIT 100;
डेटा "यूरोप-पश्चिम-4" में संग्रहीत किया गया था, और पूछताछ के लिए मूल्य निर्धारण $6 प्रति टीबी है । इसलिए, स्क्रिप्ट चलाकर, मैंने संसाधित किया:
बहुत महँगा।
स्क्रिप्ट जावास्क्रिप्ट मॉड्यूल में लिखी गई थी।
// bq-samples.mjs import { BigQuery } from "@google-cloud/bigquery"; import { Parser } from "@json2csv/plainjs"; import makeDir from "make-dir"; import { write } from "./write.mjs"; import { locales } from "./locales.mjs"; import { perf } from "./performance.mjs"; const q = (locale, start, end, limit) => `SELECT * FROM \`project.dataset.table\` WHERE ts BETWEEN TIMESTAMP("2022-12-01") AND TIMESTAMP("2023-02-28") AND locale = "${locale}" LIMIT ${limit}` async function main() { const timer = perf() const dir = await makeDir('samples') const bigquery = new BigQuery() const csvParser = new Parser({}) try { const jobs = locales.map((locale) => async () => { // get query result from BigQuery const [job] = await bigquery.createQueryJob({ query: q(locale, "2022-12-01", "2023-02-28", 100), }) const [rows] = await job.getQueryResults() // parse rows into csv format const csv = parse(csvParser, rows) // write data into csv files and store in the file system await write(csv, dir, locale, "2022-12-01", "2023-02-28", 100) }) await Promise.all(jobs.map((job) => job())) console.log(`✨ Done in ${timer.stop()} seconds.`) } catch (error) { console.error('❌ Failed to create sample file', error) } } await main()
यह प्रति लोकेल सीएसवी प्रारूप में एक नमूना फ़ाइल उत्पन्न करता है। प्रक्रिया सीधी है:
यह पता चला है कि मैंने अपनी क्वेरी में कई चीज़ें गलत की हैं। यदि आप मूल्य निर्धारण मॉडल को फिर से देखते हैं, तो आप देखेंगे कि लागत केवल आपके द्वारा संसाधित किए जाने वाले डेटा से संबंधित है। तो यह स्पष्ट है कि मेरी क्वेरी ने 100 पंक्तियों का उत्पादन करने के लिए बहुत अधिक डेटा देखा।
इस अंतर्दृष्टि के साथ, आइए क्वेरी को चरण दर चरण अनुकूलित करें।
यह थोड़ा उल्टा है। मेरे चयन कथन का इससे कोई लेना-देना क्यों है कि यह कितना डेटा संसाधित करता है? मेरे द्वारा चुने गए स्तंभों के बावजूद, मुझे उन्हीं संसाधनों और डेटा से पढ़ना चाहिए, है ना?
यह केवल पंक्ति-उन्मुख डेटाबेस के लिए सही है।
BigQuery वास्तव में एक स्तंभकार डेटाबेस है। यह स्तंभ-उन्मुख है, जिसका अर्थ है कि डेटा स्तंभों में संरचित है। BigQuery अपने अंतर्निहित कंप्यूटिंग इंजन के रूप में Dremel का उपयोग करता है। जब डेटा को कोल्ड स्टोरेज से Dremel में सक्रिय स्टोरेज में ले जाया जाता है, तो यह डेटा को ट्री स्ट्रक्चर में स्टोर करता है।
प्रत्येक लीफ नोड प्रोटोबॉफ़ प्रारूप में एक स्तंभ-उन्मुख "रिकॉर्ड" है।
BigQuery में, प्रत्येक नोड एक VM है। एक क्वेरी निष्पादन रूट सर्वर (नोड) से इंटरमीडिएट सर्वर के माध्यम से चयनित कॉलम को पुनः प्राप्त करने के लिए लीफ सर्वर पर प्रसारित होता है।
हम अलग-अलग कॉलम चुनने के लिए क्वेरी को संशोधित कर सकते हैं:
SELECT session_info_1, session_info_2, session_info_3, user_info_1, user_info_2, user_info_3, query_info_1, query_info_2, query_info_3, impression_info_1, impression_info_2, impression_info_3, ts FROM `project.dataset.table` WHERE ts BETWEEN TIMESTAMP("2022-12-01") AND TIMESTAMP("2023-02-28") AND locale = "US" LIMIT 100;
बस स्पष्ट रूप से सभी स्तंभों का चयन करके, मैं संसाधित डेटा को 3.08 टीबी से 2.94 टीबी तक कम करने में सक्षम था। यह 100 जीबी की कमी है।
Google क्लाउड अनुशंसा करता है कि हम तिथि के अनुसार विभाजन तालिकाएँ बनाते हैं । यह हमें डेटा के केवल एक सबसेट को क्वेरी करने देता है।
क्वेरी को और ऑप्टिमाइज़ करने के लिए, हम वेयर स्टेटमेंट में दिनांक सीमा को कम कर सकते हैं क्योंकि टेबल को “ts” कॉलम द्वारा विभाजित किया गया है।
SELECT session_info_1, session_info_2, session_info_3, user_info_1, user_info_2, user_info_3, query_info_1, query_info_2, query_info_3, impression_info_1, impression_info_2, impression_info_3, ts FROM `project.dataset.table` WHERE ts = TIMESTAMP("2022-12-01") AND locale = "US" LIMIT 100;
मैंने दिनांक सीमा को तीन महीने के बजाय एक दिन तक सीमित कर दिया है। मैं संसाधित डेटा को 37.43 जीबी तक कम करने में सक्षम था। यह मूल क्वेरी का केवल एक अंश है।
लागत कम करने का दूसरा तरीका यह है कि आप जिस डेटासेट से क्वेरी कर रहे हैं उसे कम करें। क्वेरी परिणामों को छोटे डेटासेट के रूप में संग्रहीत करने के लिए BigQuery गंतव्य तालिका प्रदान करता है। गंतव्य तालिकाएँ दो रूपों में आती हैं: अस्थायी और स्थायी।
क्योंकि अस्थायी तालिकाओं का जीवनकाल होता है और इसे साझा करने और क्वेरी करने के लिए डिज़ाइन नहीं किया गया है, मैंने क्वेरी परिणाम को अमल में लाने के लिए एक स्थायी गंतव्य तालिका बनाई है:
// bq-samples.mjs const dataset = bigquery.dataset('materialized_dataset') const materialzedTable = dataset.table('materialized_table') // ... const [job] = await bigquery.createQueryJob({ query: q(locale, '2022-12-01', '2023-02-28', 100), destination: materialzedTable, })
क्वेरी परिणाम गंतव्य तालिका में संग्रहीत किए जाएंगे। यह भविष्य के प्रश्नों के लिए एक संदर्भ के रूप में काम करेगा। जब भी गंतव्य तालिका से क्वेरी करना संभव होगा, BigQuery तालिका से डेटा संसाधित करेगा। यह हमारे द्वारा देखे जाने वाले डेटा आकार को बहुत कम कर देगा।
BigQuery में लागत कम करने के लिए यह एक बहुत ही रोचक अध्ययन है। केवल तीन आसान चरणों के साथ:
मैं संसाधित डेटा आकार को 3 टीबी से घटाकर 37.5 जीबी करने में सक्षम था। यह कुल लागत को 3,000 डॉलर से घटाकर 30 डॉलर कर देता है।
यदि आप BigQuery आर्किटेक्चर के बारे में अधिक जानने में रुचि रखते हैं, तो यहां वे संदर्भ दिए गए हैं जिनसे मुझे मदद मिली:
आप Google क्लाउड दस्तावेज़ीकरण में BigQuery लागत अनुकूलन के बारे में अधिक पढ़ सकते हैं।
केस स्टडी पर मेरे साथ सहयोग करने और मुझे BigQuery की वास्तुकला को समझने में मदद करने वाली बहुमूल्य अंतर्दृष्टि प्रदान करने के लिए अबू नशीर का विशेष धन्यवाद।
कनेक्ट करना चाहते हैं?
यह लेख मूल रूप से डाव-चिह की वेबसाइट पर पोस्ट किया गया था।