ลด Storage cost ใน BigQuery กัน

หลายคนในองค์กรที่ใช้ BigQuery กันเยอะๆ แน่นอนว่าค่า Compute บานเบอะแน่ๆ จนไม่ทันได้สังเกตว่าค่า BQ Storage นั้นก็บวมเช่นกัน

เพราะสัดส่วนมันต่างกันเยอะมาก สมมติเรา Query กันที่ $1000 ค่า storage เองอาจจะอยู่แถว $50
เราเลยอาจจะมองแค่ งั้นไปลดค่า Query หรือ compute ก่อนดีไหม ซึ่งใช้เวลาสักพัก แต่หารู้ไม่ว่า จริงๆเราสามารถลด Cost ตัว storage ได้ทันที ใช้เวลาไม่เกิน 24 ชม. ก็เซฟไปหลายดอลล่าห์เลย

จากเคสที่ทีมได้ทำ สามารถลด cost ได้ 71.19% ต่อเดือน

(เนื่องจากไม่สามารถบอกตัวเลขจริงได้ จึงขอบอกเป็น % แทน)

ทีนี้เรามาทำความเข้าใจกันก่อนว่า BigQuery เก็บตังตัว Storage ยังไง

Storage Billing Models:

  1. Logical – (uncompressed, default model)
  2. Physical – (compressed)

หรือพูดง่ายๆว่า Logical เก็บแบบไม่บีบอัดข้อมูล โดยเป็น default ที่ GCP เซ็ตมาแต่แรก (แบบนี้ทำไมเขาไม่ทำมาให้แต่แรกเนอะ)

ดังนั้นเราสามารถเปลี่ยน Billing model ได้ โดยที่…

  • การเปลี่ยน Billing model ไม่มีผลต่อ query performance, latency, or integration ที่เชื่อมกับ application อื่นๆ เช่น Looker >> อันนี้ดีมาก !
  • ถ้าเปลี่ยน Billing model แล้ว จะใช้เวลา 24 ชม.ในการเปลี่ยนแปลง
  • ถ้าเราเปลี่ยน Billing model แล้วครั้งหนึ่ง ต้องรอ 14 วันถ้าจะเปลี่ยนอีกที

Pricing

แถม! เมื่อเทียบกันแล้ว Logical แพงกว่า Physical ถึง 2 เท่าเลย!

คำถามถัดมา งั้นเปลี่ยนให้เป็น Physical หมดสิ ถึงจะประหยัด!
แต่ยังก่อน ไม่ใช่ว่าทุก table จะเหมาะกับการบีบอัดหรอกนะ

เราจะมาดูกันว่า table ไหนควรเปลี่ยนบ้าง

วิธีเช็คว่า table ไหนควรเปลี่ยน

เราจะมาดูว่า table ปัจจุบันใช้ Logical หรือ Physical
และหากคำนวนแล้ว เปลี่ยนเป็น Physical จะถูกกว่าไหม

SQL
-- Singapore storage prices, USD per GiB-month.
DECLARE active_logical_price FLOAT64 DEFAULT 0.023;
DECLARE long_term_logical_price FLOAT64 DEFAULT 0.016;
DECLARE active_physical_price FLOAT64 DEFAULT 0.040;
DECLARE long_term_physical_price FLOAT64 DEFAULT 0.020;
WITH dataset_options AS (
SELECT
schema_name,
MAX(
IF(
option_name = 'storage_billing_model',
UPPER(option_value),
NULL
)
) AS configured_billing_model
FROM
`<project_name>`.`region-asia-southeast1`
.INFORMATION_SCHEMA.SCHEMATA_OPTIONS
GROUP BY schema_name
),
storage AS (
SELECT
table_storage.*,
CASE
WHEN dataset_options.configured_billing_model = 'PHYSICAL'
THEN 'PHYSICAL'
ELSE 'LOGICAL'
END AS billing_model
FROM
`<project_name>`.`region-asia-southeast1`
.INFORMATION_SCHEMA.TABLE_STORAGE_BY_PROJECT AS table_storage
LEFT JOIN dataset_options
ON table_storage.table_schema = dataset_options.schema_name
WHERE
table_storage.table_type = 'BASE TABLE'
AND NOT table_storage.deleted
)
SELECT
table_catalog AS project_id,
table_schema AS dataset_id,
table_name,
billing_model,
ROUND(active_logical_bytes / POW(1024, 3), 2)
AS active_logical_gib,
ROUND(long_term_logical_bytes / POW(1024, 3), 2)
AS long_term_logical_gib,
ROUND(active_physical_bytes / POW(1024, 3), 2)
AS active_physical_gib,
ROUND(long_term_physical_bytes / POW(1024, 3), 2)
AS long_term_physical_gib,
ROUND(time_travel_physical_bytes / POW(1024, 3), 2)
AS time_travel_physical_gib,
ROUND(COALESCE(fail_safe_physical_bytes, 0) / POW(1024, 3), 2)
AS fail_safe_physical_gib,
-- Cost if the dataset uses logical billing.
ROUND(
active_logical_bytes / POW(1024, 3) * active_logical_price
+ long_term_logical_bytes / POW(1024, 3) * long_term_logical_price,
2
) AS logical_cost_usd_month,
-- Active physical bytes already include time-travel bytes.
ROUND(
(
active_physical_bytes
+ COALESCE(fail_safe_physical_bytes, 0)
) / POW(1024, 3) * active_physical_price
+ long_term_physical_bytes / POW(1024, 3)
* long_term_physical_price,
2
) AS physical_cost_usd_month,
-- Estimate based on the dataset's actual billing model.
ROUND(
CASE billing_model
WHEN 'PHYSICAL' THEN
(
active_physical_bytes
+ COALESCE(fail_safe_physical_bytes, 0)
) / POW(1024, 3) * active_physical_price
+ long_term_physical_bytes / POW(1024, 3)
* long_term_physical_price
ELSE
active_logical_bytes / POW(1024, 3)
* active_logical_price
+ long_term_logical_bytes / POW(1024, 3)
* long_term_logical_price
END,
2
) AS estimated_cost_usd_month
FROM storage
ORDER BY estimated_cost_usd_month DESC;

Example result:

((ข้อมูลนี้เป็นเพียง mock data ที่ใกล้เคียงกับความจริง))

จะเห็นได้ว่าเราจะเห็น billing_model ของแต่ทุก table ว่าเป็น logical
โดยที่ table 2 แถวแรก เทียบแล้วเราจ่าย logical_cost_usd_month อยู่ที่ $100 แต่ถ้าปรับเป็น physical จะเหลือเพียง $3 ต่อเดือนเท่านั้น !

ส่วน table 2 แถวล่างจ่ายน้อยมาก $4 และ $5 เมื่อเทียบเป็น physical กลับจ่ายแพงกว่าที่ $100 และ $130

ดังนั้นเราจึงตัดสินใจได้ว่า ควรปรับ billing model ของ dataset ชื่อ analytics เป็น physical ได้เลย

ไม่ใช่ว่าทุก table จะเปลี่ยนมา physical แล้วถูก

ใน 2 แถวล่างกลับแพงกว่าเมื่อเปลี่ยนเป็น Physical เพราะมี time-travel and fail-safe history อยู่เป็นจำนวนมาก ซึ่งน่าจะเกิดจากการเขียนข้อมูลทับทั้งตารางบ่อยครั้ง

เป็นไปได้ว่า table พวกนี้เป็น truncate table.. หรือ create of replace table..

วิธีเปลี่ยน billing model

SQL
ALTER SCHEMA `<project_name>.<dataset>`
SET OPTIONS (
storage_billing_model = 'PHYSICAL'
);

ตัวอย่างนี้เราจะเปลี่ยน analytics

SQL
ALTER SCHEMA `project_a.analytics`
SET OPTIONS (
storage_billing_model = 'PHYSICAL'
);

Ref

https://docs.cloud.google.com/bigquery/docs/storage_overview#dataset_storage_billing_models

Comment and Feedback

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.