paint-brush
Google Cloud BigQuery'yi Optimize Etme ve Maliyeti Kontrol Etmeile@dawchihliou
3,209 okumalar
3,209 okumalar

Google Cloud BigQuery'yi Optimize Etme ve Maliyeti Kontrol Etme

ile Daw-Chih Liou6m2023/04/18
Read on Terminal Reader
Read this story w/o Javascript

Çok uzun; Okumak

🙈 BigQuery'nin maliyetlerine nelerin katkıda bulunduğunu öğreneceksiniz. 🏛️ BigQuery mimarisine dalacağız. 💰 Bir sonraki Google Cloud faturanızda %99,97 tasarruf etmek için 3 kolay adımı öğreneceksiniz.
featured image - Google Cloud BigQuery'yi Optimize Etme ve Maliyeti Kontrol Etme
Daw-Chih Liou HackerNoon profile picture

Google Cloud BigQuery'deki Tek Sorguda Farkında Olmadan 6 Saatte 3.000 Dolar Kazandım. İşte Nedeni ve Maliyeti Optimize Etmek İçin 3 Kolay Adım.

Bu makalede

  • 🙈 BigQuery'nin maliyetlerine nelerin katkıda bulunduğunu öğreneceksiniz.
  • 🏛️ BigQuery'nin mimarisine dalacağız.
  • 💰 Bir sonraki Google Cloud faturanızda %99,97 tasarruf etmek için 3 kolay adımı öğreneceksiniz.


Hadi gidelim.


Nasıl oldu?

Danışmaya ulaşan müşteriler için veri örnekleri hazırlamak üzere bir senaryo geliştiriyordum. Örneklerin her dosyada 100 satırı vardır ve bunlar 55 yerel ayara bölünmüştür. Sorgum şuna benziyor


 SELECT * FROM `project.dataset.table` WHERE ts BETWEEN TIMESTAMP("2022-12-01") AND TIMESTAMP("2023-02-28") AND locale = "US" LIMIT 100;


Veriler "europe-west-4"te saklanıyordu ve sorgulamanın ücreti TB başına 6 ABD dolarıydı . Böylece betiği çalıştırarak şunu işledim:


  • Toplamda 500 TB veri


  • Ülke başına ortalama 3 TB veri


  • Veri örneği dosyası başına ortalama 54 ABD doları


Çok pahalı.

3.000 Dolara Mal Olan Senaryo

Komut dosyası JavaScript modüllerinde yazılmıştır.


 // 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()


Yerel ayar başına CSV formatında bir örnek dosya oluşturur. Süreç basittir:


  • BigQuery tablosunu yerel, başlangıç tarihi, bitiş tarihi ve limitle sorgulama.


  • Sorgu sonucunu CSV formatına dönüştürme.


  • CSV'yi dosya sistemine yazma.


  • İşlemi tüm yerel ayarlar için tekrarlıyoruz.

Sorun ne?

Sorgumda birkaç şeyi yanlış yaptığım ortaya çıktı. Fiyatlandırma modeline tekrar bakarsanız maliyetin yalnızca ne kadar veri işlediğinizle ilgili olduğunu fark edeceksiniz. Dolayısıyla sorgumun 100 satır üretemeyecek kadar fazla veri aradığı açık.


Bu öngörüyle sorguyu adım adım optimize edelim.

Seçme *

Bu biraz mantığa aykırı. Select ifademin neden işlediği veri miktarıyla bir ilgisi var? Seçtiğim sütunlar ne olursa olsun aynı kaynaklardan ve verilerden okuyor olmalıyım değil mi?


Bu yalnızca satır odaklı veritabanları için geçerlidir.


BigQuery aslında sütunlu bir veritabanıdır . Sütun odaklıdır, yani veriler sütunlar halinde yapılandırılmıştır. BigQuery, temel bilgi işlem motoru olarak Dremel'i kullanıyor. Dremel'de veriler soğuk depodan aktif depoya taşındığında verileri bir ağaç yapısında saklar.


Her yaprak düğümü Protobuf formatında sütun odaklı bir “kayıttır”.


Dremel veri yapısına genel bakış


BigQuery'de her düğüm bir sanal makinedir. Bir sorgu yürütme, seçilen sütunları almak için kök sunucudan (düğüm) ara sunucular aracılığıyla yaprak sunuculara yayılır.


Tek tek sütunları seçmek için sorguyu değiştirebiliriz:


 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;


Tüm sütunları açıkça seçerek işlenen veriyi 3,08 TB'tan 2,94 TB'a düşürmeyi başardım. Bu 100 GB'lık bir azalmadır .

Bölümlenmiş Tablo Kullanın ve Yalnızca Veri Alt Kümelerini Sorgulayın

Google Cloud, tabloları tarihe göre bölümlememizi önerir. Verilerin yalnızca bir alt kümesini sorgulamamıza olanak tanır.

Sorguyu daha da optimize etmek için, tablo “ts” sütununa göre bölümlendiğinden, Where ifadesindeki tarih aralığını daraltabiliriz.


 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;


Tarih aralığını üç ay yerine bir güne kadar daralttım. İşlenen veriyi 37.43 GB'a kadar indirmeyi başardım. Bu orijinal sorgunun sadece bir kısmı.

Aşamalarda Gerçekleştirilmiş Sorgu Sonuçlarını Kullan

Maliyetleri azaltmanın başka bir yolu da sorgulama yaptığınız veri kümesini azaltmaktır. BigQuery, sorgu sonuçlarını daha küçük veri kümeleri halinde depolamak için hedef tablolar sunar. Hedef tabloları iki şekilde gelir: geçici ve kalıcı.


Geçici tabloların bir ömrü olduğundan ve paylaşılmak ve sorgulanmak üzere tasarlanmadığından, sorgu sonucunu gerçekleştirmek için kalıcı bir hedef tablo oluşturdum:


 // 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, })


Sorgu sonuçları hedef tabloda saklanacaktır. Gelecekteki sorgular için referans görevi görecektir. Hedef tablodan sorgulama mümkün olduğunda BigQuery, tablodaki verileri işler. Aradığımız veri boyutunu büyük ölçüde azaltacaktır.

Son düşünceler

BigQuery'de maliyeti düşürmeye yönelik çok ilginç bir çalışma. Yalnızca üç kolay adımla:


  • * kullanmayın


  • Bölümlenmiş Tablo Kullanın ve Yalnızca Veri Alt Kümelerini Sorgulayın


  • Aşamalarda Gerçekleştirilmiş Sorgu Sonuçlarını Kullan


İşlenen veri boyutunu 3 TB'tan 37,5 GB'a düşürmeyi başardım. Toplam maliyeti önemli ölçüde 3.000 $'dan 30 $'a düşürür.


BigQuery mimarisi hakkında daha fazla bilgi edinmek istiyorsanız bana yardımcı olan referansları burada bulabilirsiniz:






BigQuery maliyet optimizasyonları hakkında daha fazla bilgiyi Google Cloud belgelerinde bulabilirsiniz.


Örnek olayda benimle işbirliği yaptığı ve BigQuery mimarisini anlamama yardımcı olan değerli bilgiler sağladığı için Abu Nashir'e özellikle teşekkür ederim.

Referanslar


Bağlanmak mı istiyorsunuz?

Bu makale ilk olarak Daw-Chih'in web sitesinde yayınlanmıştır.