চলো যাই.
পরামর্শের জন্য পৌঁছানো গ্রাহকদের জন্য ডেটা নমুনা প্রস্তুত করার জন্য আমি একটি স্ক্রিপ্ট তৈরি করছিলাম। নমুনাগুলির প্রতিটি ফাইলে 100টি সারি রয়েছে এবং সেগুলি 55টি লোকেলে বিভক্ত। আমার প্রশ্ন এই মত দেখায়
SELECT * FROM `project.dataset.table` WHERE ts BETWEEN TIMESTAMP("2022-12-01") AND TIMESTAMP("2023-02-28") AND locale = "US" LIMIT 100;
ডেটা "europe-west-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()
এটি প্রতি লোকেলে CSV বিন্যাসে একটি নমুনা ফাইল তৈরি করে। প্রক্রিয়াটি সহজবোধ্য:
দেখা যাচ্ছে যে আমি আমার প্রশ্নে বেশ কিছু ভুল করেছি। আপনি যদি মূল্যের মডেলটি আবার দেখেন, আপনি লক্ষ্য করবেন যে খরচটি শুধুমাত্র আপনি কতটা ডেটা প্রক্রিয়া করেন তার সাথে সম্পর্কিত। সুতরাং এটা স্পষ্ট যে আমার ক্যোয়ারী 100টি সারি তৈরি করতে অনেক বেশি ডেটা দেখেছে।
এই অন্তর্দৃষ্টি দিয়ে, আসুন ধাপে ধাপে প্রশ্নটি অপ্টিমাইজ করি।
এটা একটু বিপরীত. আমার নির্বাচিত বিবৃতিতে এটি কতটা ডেটা প্রক্রিয়া করে তার সাথে কেন কিছু করার আছে? আমি যে কলামগুলি নির্বাচন করি না কেন, আমার একই সংস্থান এবং ডেটা থেকে পড়া উচিত, তাই না?
এটি শুধুমাত্র সারি-ভিত্তিক ডাটাবেসের জন্য সত্য।
BigQuery আসলে একটি কলামার ডাটাবেস । এটি কলাম-ভিত্তিক, অর্থাত্ ডেটা কলামে গঠন করা হয়। BigQuery এর অন্তর্নিহিত কম্পিউটিং ইঞ্জিন হিসাবে 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 TB থেকে 2.94 TB কমাতে সক্ষম হয়েছি। এটি একটি 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 TB থেকে 37.5 GB কমাতে সক্ষম হয়েছি। এটি মোট খরচ উল্লেখযোগ্যভাবে $3,000 থেকে $30 কমিয়ে দেয়।
আপনি যদি BigQuery আর্কিটেকচার সম্পর্কে আরও জানতে আগ্রহী হন, তাহলে এখানে রেফারেন্সগুলি যা আমাকে সাহায্য করেছে:
আপনি Google ক্লাউড ডকুমেন্টেশনে BigQuery খরচ অপ্টিমাইজেশন সম্পর্কে আরও পড়তে পারেন।
কেস স্টাডিতে আমার সাথে সহযোগিতা করার জন্য আবু নাশিরকে বিশেষ ধন্যবাদ এবং মূল্যবান অন্তর্দৃষ্টি প্রদান করার জন্য যা আমাকে BigQuery এর আর্কিটেকচার বুঝতে সাহায্য করেছে।
সংযোগ করতে চান?
এই নিবন্ধটি মূলত Daw-Chih এর ওয়েবসাইটে পোস্ট করা হয়েছিল।