Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

ควบคุมการเติบโตของ Database: กลยุทธ์รักษา Table Sizes ให้เล็กและหลีกเลี่ยง Data Bloat

Web Applications ส่วนใหญ่ใช้ Data Store บางประเภท มักเป็น Relational Database เมื่อ Web App สำเร็จ มันง่ายเกินไปที่จะเริ่ม "Hoarding" Data ใน Database แต Hoarding Data นำไปสู่ Unbounded Growth ของ Database Tables (ทั้ง Row Count และ Stored Data Size)

แม้ทำงานได้ดีถึงจุดหนึ่ง แตป้องกัน Data Bloat บางส่วน — หรือถ้าป้องกันไม่ได้ Plan Infrastructure ไว้ล่วงหน้า Manage Growth ให้เหมาะสม — เป็นเรื่อง Useful มาก

ก่อน Dive In มาดูว่าเราอาจจบลงกับ Bloated Applications ยังไง

More Data ไม่ได้หมายถึง Great เสมอไป

Applications ส่วนใหญ่ที่เราทำงาน Tend to Get Bigger ตามเวลา

ถ้าใช้ Cloud Provider สำหรับ Database คุณอาจ Hit Allocated Storage Limit เมื่อเกิดขึ้น ต้อง Upgrade Instance Type Heroku PostgreSQL Databases มี Limit เช่น Hobby Tier Limited 1GB Data

More Data มี Implications สำหรับ Query Speeds อะไรก่อนหน้านี้ Possible Without Index กลาย Impossible With Larger Tables Row Range Scans บางอย่าง Slower More Locks Acquired สำหรับ Database UPDATE และ DELETE Operations

How Database Tables Grow (ตารางเติบโตอย่างไร)

Data Hoarding เกิดขึ้น Gradually อะไร Not Problem Today กลาย Problem ในเดือนหนึ่งหรือ 6 เดือน สิ่ง Treacherous ที่สุดคือ Easy to Miss พิจารณา Classic Scenarios:

  • Compliance Reasons Adopt Gem paper_trail ได้ Table audit_log_entries ทุก Operation ที่ Significant สร้าง Row ใน Table นั้น Audit Log Entries ไม่ Archive
  • Accept Uploads ใช้ ActiveStorage ไม่ Delete Uploads activestorage_blobs Table Keeps Getting Bigger
  • Run Shared CMS Publishing Web Allow Article Segments Stored in Database Platform Successful แต Authors ส่วนใหญ่เขียน Article ใหญ่เท่าหนังสือ pages Table กลาย Sizeable แม้แค่ 몇 Thousand Pages
  • Allow User-uploaded Content ไม่ Delete Data Compliance Reasons ใช้ paranoia Delete via Flag user_items Table Grows Indefinitely ผ่าน 10M Rows โดยคุณไม่รู้

Patterns นี้มี Implications หากไม่จับทัน ถ้ามี Good View ของ Table Sizes คุณ Anticipate เมื่อ Upgrade และ Schedule Maintenance Off-peak Upgrades Less User Impact

Making Projections กลาย Easier เช่น:

  • Today events Table Fits in Memory Current Growth Rate ไม่ Fit in Memory ใน 7 เดือน
  • เรา 30% Storage Use RDS Instance Type จะ Hit 90% January ปีหน้า
  • เรา Full Table Scan Query บน payments Compute Function Over Every Row Where Input Depends on Query เรารู้ payments Table Exceed 2M Rows ใน 3 สัปดาห์ และ 20M January ปีหน้า

ทั้งหมด Potential Present as Incident หรือ Outage แตถ้า Attack Early Enough Mitigate ได้ง่าย เช่น:

  • Set Up Archiving Data Older Than 30 Days ใน events Table
  • Upgrade RDS Instance ใน 4 เดือน
  • Limit Full Table Scan เพิ่ม WHERE Condition Compute Function บน Smaller Subset of Rows

Gain Visibility Over Your Database Growth

ติดตาม Database Growth มี 2 ทาง:

  • Install Special Tooling (like Stats for MySQL) Connect Metrics Collection Engine via Prometheus, Telegraph, หรือ Tools อื่น
  • Use AppSignal โดยเฉพาะถ้าใช้อยู่แล้วสำหรับ App

AppSignal Store Several Metric Types หนึ่งคือ gauge Single Time Series Per Environment (production, staging, development) Update จาก Time to Time AppSignal Metrics Allow Tags Auto-create Tagged gauge Metrics สำหรับ Database Tables มาทำกัน:

  • db.row_count Approximate Number of Rows ใน Tables, Per Table (Approximates ด้านล่าง)
  • db.data_size_bytes Bytes ที่ Table ใช้
  • db.index_size_bytes Bytes ที่ Table's Indices ใช้

Note: Suffix Metric Name ด้วย Value Type ช่วยตอน Define Metric Display Separate "Data" และ "Indices" Metrics สำคัญ ถ้า Table มี Rows เยอะและ Indices หลายตัว Size ของ Indices อาจ 2-3x Size ของ Stored Data (ทุก Index Store Derived Data สร้าง Storage Overhead)

Counting Database Table Rows Quickly

"Approximate" Part ของ Row Count Essential ปกติถ้าอยาก Precise Row Count Query SELECT COUNT(1) FROM my_table แต่อาจช้ากว่าที่อยาก

ตอน COUNT Database Ensure Row Count ไม่เปลี่ยนระหว่าง Query — Lock Table หรือ Create Divergent Transaction ระหว่าง Query Runs Table ใหญ่ Query ช้ากว่า — More Rows Scanned, More Locks Accumulate

ดังนั้นตอนเราแค่อยาก "Close Enough" Approximation (สำหรับ Performance Estimation Precision 10-30k Rows Less/More Good Enough) เราใช้ Internal Database Engine Statistics Query Data Type นี้

Databases ส่วนใหญ่ Optimized Access Table Data Rows Written Out in "Pages" Engine Track Rows Assigned Pages ระดับ Insertion Order:

  • Rows 1-100 on Page 1
  • Rows 101-200 on Page 2
  • Rows 201-300 on Page 3

Engine Knows Pages Per Table และ Rough Row Count Per Page Multiply Pages Allocated × Page Size (Rows per Page) ให้ Estimate ข้อดี: Count เร็วมาก Table ไม่ต้อง Lock ระหว่าง Query

Record Table Sizes สำหรับ MySQL

Query ที่ต้อง Run:


Grab Columns ที่สนใจ: Data_length, Index_length, และ Rows Table Size = Data_length + Index_length Approximate Row Count Based on Pages ใน Rows

Package Into Code Block Collect Data สำหรับ Entire Database ใช้ Query Methods โดยตรงจาก ActiveRecord:



Record Table Sizes สำหรับ PostgreSQL

PostgreSQL ต้อง Query แบบ Elaborate ไม่มี Shortcut Query เหมือน SHOW TABLE STATUS Query Internal PostgreSQL Tables:


Note: Account Only public Schema (Default) หาก Include Other Schemas Remove WHERE t.table_schema = 'public' และ Replace table_info.fetch('name') ด้วย table_info.fetch('full_table_name')

Make Sure Metrics Update Regularly

Block นี้ต้อง Run Regular Intervals ใส่ Sidekiq Scheduler หรือ Rake Task จาก Cron เช่นใช้ good_job เพิ่มใน "cron" Section:



Create a Dashboard

เมื่อ Data Coming In Build Dashboard Copy Dashboard นี้:


Click Add dashboard แล้ว Import dashboard ใน Modal Dialog Dashboard ให้ Graphs เหมือนนี้:

ควบคุมการเติบโตของ Database: กลยุทธ์รักษา Table Sizes ให้เล็กและหลีกเลี่ยง Data Bloat

และ Table Sizes Graph:

ควบคุมการเติบโตของ Database: กลยุทธ์รักษา Table Sizes ให้เล็กและหลีกเลี่ยง Data Bloat

Note: ใช้ Wildcard Tags Auto-build Graphs สำหรับ Every Table ใน Database

Interpreting the Data

ตอนดู Data Watch Out Exponential หรือ Linear Growth ใน Row Count หรือ Size — Table Getting Bigger และ Bigger

ถ้าเห็นนี้ มี Options 2 อย่าง Architect สำหรับ Unbounded Growth — รู้เมื่อ Upgrade และ Upgrade Next Best Size อีกทาง Setup Regular Deletion Task — เพื่อนร่วมงานเก่า Wander Hillen เขียนบทความยอดเยี่ยมเรื่องนี้

เช่น Screenshot ด้านบน Tables บางตัว Shrink Regularly — นั่นคือ Regular Cleanup Tasks Run เห็น Data Accumulates จน Certain Point แต Ingress of Rows Constant Sizes และ Row Counts Drop

ตราบใดมี Drops นี้ และ Data Grows Steady Rate Database จะไม่ Surprise Limit Bust

Sum Up: Avoid Data Bloat จาก Database Tables

ในบทความนี้ เราดูวิธี Gain Visibility Over Database Growth และ Keep Data Bloat Down

Data Bloat Real Risk สำหรับ Apps ที่ Successful ใน Market ด้วย Metrics สำหรับ Database Tables คุณ Anticipate Better เมื่อ Scale Database Vertically และต้อง Install Regular Stale Data Cleanups AppSignal Gauges with Tags + SQL เล็กน้อย ได้ Data นี้ใน Format สะดวกและ Pleasant

Don't Let Your Database Surprise You!

ควบคุมการเติบโตของ Database: กลยุทธ์รักษา Table Sizes ให้เล็กและหลีกเลี่ยง Data Bloat

Julik Tarkhanov

Guest Author Julik Tarkhanov เป็น Staff Software Engineer at Cheddar Payments และ Author Multiple Ruby Open-source Libraries

บทความทั้งหมดโดย Julik Tarkhanov