27 ธ.ค. 2568·อ่าน 3 นาที

ใช้ PostgreSQL read replicas สำหรับการรายงาน: รักษาแดชบอร์ดให้เร็ว

ใช้ PostgreSQL read replicas สำหรับการรายงานเพื่อให้แดชบอร์ดตอบสนองเร็ว ในขณะเดียวกันปกป้องฐานข้อมูลหลักจากคำสั่งช้า สไปก์ และแรงกดจากล็อก

ใช้ PostgreSQL read replicas สำหรับการรายงาน: รักษาแดชบอร์ดให้เร็ว

ทำไมการรายงานถึงทำให้ฐานข้อมูลหลักช้าลง

รูปแบบที่มักพบคือ: แอปทำงานได้ดีเกือบทั้งวัน แต่พอมีคนเปิดแดชบอร์ด การเช็คเอาท์ การล็อกอิน หรือเครื่องมือซัพพอร์ตก็เริ่มช้าลง ไม่ได้ "ล่ม" แต่ทุกอย่างตอบสนองช้าลง นั่นมักเป็นเพราะฐานข้อมูลหลักถูกดึงไปสองทิศทางพร้อมกัน

ธุรกรรมปกติ (งานแอปในชีวิตประจำวัน) มักสั้นและเลือกอ่านเฉพาะแถวเล็กๆ ใช้ดัชนี และจบเร็วเพื่อให้คำขออื่นๆ เดินหน้าต่อได้ คำสั่งการรายงานทำงานต่างกัน: มักสแกนข้อมูลจำนวนมาก, join หลายตาราง, จัดเรียงและกลุ่มผลลัพธ์ และคำนวณยอดรวมข้ามวันหรือเดือนได้ ถึงแม้จะไม่บล็อกการเขียนโดยตรง แต่ยังใช้ทรัพยากรร่วมกันที่แอปต้องการ

นี่คือวิธีที่แดชบอร์ดมักกระทบฐานข้อมูล OLTP:

  • การอ่านหนักแข่งทรัพยากร CPU, หน่วยความจำ และ I/O ของดิสก์
  • การสแกนขนาดใหญ่ผลัก "หน้าร้อน" ออกจากแคช ทำให้คำถามปกติช้าลง
  • การจัดเรียงใหญ่และ GROUP BY บางครั้ง spill ไปที่ดิสก์และสร้างการโหลดเป็นช่วง
  • คำสั่งรันนานเพิ่มความขัดแย้งและทำให้การสไปก์กินเวลานานขึ้น
  • ตัวกรองแบบ ad hoc (ช่วงวันที่, เซกเมนต์) ทำให้โหลดไม่คาดเดา

read replica เป็นเซิร์ฟเวอร์ PostgreSQL แยกต่างหากที่คัดลอกข้อมูลจากเซิร์ฟเวอร์หลักอย่างต่อเนื่องและให้บริการคำสั่งอ่านเท่านั้น การใช้ PostgreSQL read replicas สำหรับการรายงานช่วยให้แดชบอร์ดย้ายงานหนักไปที่อื่น เพื่อให้ฐานข้อมูลหลักโฟกัสกับธุรกรรมที่เร็ว

ข้อต้องตั้งแต่ต้น: replica ช่วยงานอ่าน ไม่ใช่งานเขียน คุณไม่สามารถส่ง INSERT/UPDATE ไปยัง replica ธรรมดาได้อย่างปลอดภัย และผลลัพธ์อาจหน่วงจากหลักเล็กน้อยเพราะการจำลองต้องใช้เวลา สำหรับแดชบอร์ดหลายแบบ นี่เป็นการแลกเปลี่ยนที่ดี: ตัวเลขสดน้อยลงเล็กน้อยแลกกับประสิทธิภาพแอปที่สม่ำเสมอ

ถ้าคุณสร้างแดชบอร์ดภายใน (เช่น ใน AppMaster) การแยกนี้มักเข้ากันได้ดี: แอปยังเขียนไปที่หลัก ส่วนหน้ารายงานจะอ่านจาก replica

วิธีการทำงานของ read replicas ใน PostgreSQL (ภาษาเข้าใจง่าย)

read replica ของ PostgreSQL คือเซิร์ฟเวอร์ฐานข้อมูลตัวที่สองที่เก็บสำเนาเกือบแบบเรียลไทม์ของฐานข้อมูลหลัก หลักจัดการการเขียน (INSERT, UPDATE, DELETE) ส่วน replica ให้บริการการอ่าน (SELECT) เป็นหลัก ทำให้คำสั่งรายงานไม่แข่งขันกับธุรกรรมประจำวัน

Primary กับ replica ในหนึ่งนาที

คิดว่า primary เหมือนแคชเชียร์ในร้านที่ยุ่ง: ต้องตอบสนองเร็วเพราะทุกการขายจะอัปเดตสต็อก การชำระเงิน และคำสั่งต่างๆ Replica เหมือนหน้าจอแสดงผลที่โชว์ยอดและแนวโน้ม มันเฝ้าดูสิ่งที่แคชเชียร์ทำแล้วอัปเดตมุมมองของตัวเองช้ากว่าเล็กน้อย

เบื้องหลัง PostgreSQL คัดลอกการเปลี่ยนแปลงโดยส่งสตรีมของสิ่งที่เปลี่ยนบน primary แล้ว replay บน replica นั่นหมายความว่า replica จะมีโครงสร้างและข้อมูลเดียวกัน แค่นิดหน่อยล้าหลัง

ในแง่ปฏิบัติ replication คัดลอก:

  • ข้อมูลในตาราง (แถว)
  • การเปลี่ยนแปลงดัชนี (เพื่อให้คำสั่งสามารถใช้ดัชนีเดียวกัน)
  • การเปลี่ยนแปลงโครงสร้าง (เช่น คอลัมน์ใหม่ ตารางใหม่ และการมิเกรชันหลายแบบ)
  • การเปลี่ยนแปลงฐานข้อมูลส่วนใหญ่ที่เกิดจาก SQL ปกติ

สิ่งที่ replica ไม่ได้แก้: มันจะไม่ทำให้การเขียนหนักๆ ถูกลง และไม่แก้คำสั่งช้าเพราะโครงสร้างข้อมูลไม่ดีหรือขาดดัชนี ถ้าแดชบอร์ดของคุณสแกนตารางขนาดใหญ่บน replica มันยังคงช้าอยู่ แต่จะไม่ทำให้การเช็คเอาท์ช้าพร้อมกัน

นี่จึงเป็นเหตุผลที่ PostgreSQL read replicas สำหรับการรายงานเป็นที่นิยม: มันแยกงาน OLTP (ธุรกรรมสั้นและบ่อย) ออกจากงานสไตล์ OLAP (การอ่านยาว การจัดกลุ่ม และการรวมยอด) หากคุณสร้างแดชบอร์ดภายในหรือแผง admin (เช่น ใน AppMaster) การชี้หน้ารายงานไปที่ replica มักเป็นวิธีง่ายที่สุดที่จะรักษาทั้งสองฝั่งให้ทำงานดี

งานรายงานที่เหมาะให้ไปรันบน replica

กฎง่ายๆ: ถ้าคำสั่งอ่านข้อมูลจำนวนมากเพื่อสรุปผล มันเหมาะที่จะรันบน replica ด้วย PostgreSQL read replicas สำหรับการรายงาน คุณจะปกป้องการเช็คเอาท์ การลงชื่อเข้าใช้ และงานเชิงธุรกรรมอื่นๆ จากงานหนักที่แดชบอร์ดมักต้องทำ

รูปแบบแดชบอร์ดที่พบบ่อยคือช่วงวันที่กว้างพร้อมตัวกรองไม่กี่อย่าง “90 วันที่ผ่านมา แยกตามภูมิภาค สินค้า และช่องทาง” สามารถแตะข้อมูลเป็นล้านแถวได้ แม้ผลลัพธ์สุดท้ายจะแสดงแค่ไม่กี่แท่ง การสแกนเหล่านี้แข่งพื้นที่อ่านดิสก์และแคชกับฐานข้อมูลหลัก

งานที่เหมาะกับ replica

ทีมส่วนใหญ่เริ่มย้ายรายการเหล่านี้ไปยังฐานข้อมูลรายงาน:

  • การ join ขนาดใหญ่ข้ามหลายตาราง (orders + items + customers + refunds)
  • การรวมยอดเช่น SUM, COUNT DISTINCT, การคำนวณเปอร์เซ็นไทล์, cohort
  • คำสั่งรันนานที่จัดเรียงและกลุ่มผลลัพธ์ขนาดใหญ่
  • รายงานที่รันตามตารางเวลาเป็นชั่วโมง/วัน และทำงานหนักซ้ำๆ
  • เซสชัน BI สำรวจข้อมูลที่ผู้ใช้คลิกแล้วรันหลายรูปแบบ

ถึงแม้คำสั่งจะเป็น "อ่านเท่านั้น" มันก็ยังใช้ CPU, หน่วยความจำ และ I/O มาก GROUP BY ขนาดใหญ่สามารถดันคำสั่งอื่นๆ ออกจากหน่วยความจำ การสแกนซ้ำๆ ทำให้ buffer cache เขยื้อน ดังนั้น primary ต้องอ่านจากดิสก์บ่อยขึ้น

พฤติกรรมการเชื่อมต่อก็สำคัญ เครื่องมือ BI หลายตัวเปิดหลายการเชื่อมต่อต่อผู้ใช้ รีเฟรชไทล์ทุกไม่กี่นาที และรันการดึงข้อมูลพื้นหลัง ซึ่งสร้างสไปก์ของการเชื่อมต่อและคำสั่งพร้อมกัน Replica ทำให้สไปก์เหล่านั้นไปลงที่อื่นได้อย่างปลอดภัยกว่า

ตัวอย่างง่ายๆ: แดชบอร์ดปฏิบัติการโหลดเวลา 9:00 น. และมีคน 50 คนเปิดพร้อมกัน แต่ละหน้าเรียก widget หลายตัว แต่ละ widget รันคำสั่งพร้อมตัวกรองต่างกัน บน primary การระเบิดนี้อาจทำให้การสร้างคำสั่งซื้อช้าลง แต่บน replica แดชบอร์ดอาจช้าหรือหน่วงเล็กน้อย แต่ธุรกรรมยังคงเร็ว

ถ้าคุณสร้างแดชบอร์ดภายในแพลตฟอร์มอย่าง AppMaster การชี้หน้ารายงานไปที่ connection ของ replica มักเป็นชัยชนะง่ายๆ ตราบใดที่ทุกคนเข้าใจว่าข้อมูลอาจช้ากว่าไม่กี่วินาที (หรือเป็นนาที)

การแลกเปลี่ยน: ความสดของข้อมูล vs ความเร็ว (replication lag)

read replica ทำให้แดชบอร์ดเร็วขึ้นเพราะย้ายการอ่านหนักออกจากฐานข้อมูลหลัก ค่าใช้จ่ายคือ replica มักหน่วงเล็กน้อย ความล่าช้านี้เรียกว่า replication lag และเป็นข้อตัดสินหลักในการใช้ PostgreSQL read replicas สำหรับรายงาน

สิ่งที่ผู้ใช้สังเกตได้ตรงไปตรงมา: ตัวเลข "วันนี้" ต่ำกว่าความเป็นจริงเล็กน้อย คำสั่งซื้อล่าสุดหายไป หรือแผนภูมิอัปเดตช้ากว่าปกติไม่กี่นาที คนส่วนใหญ่ไม่แคร์ถ้าเทรนด์รายสัปดาห์หน่วงไป 2 นาที แต่มักกังวลถ้าหน้าจอ "เพิ่งชำระเงิน" แสดงข้อมูลผิด

lag เกิดเมื่อ primary ผลิตการเปลี่ยนแปลงเร็วกว่าที่ replica จะรับและ replay ได้ สาเหตุที่พบบ่อยได้แก่ การเขียนเป็นชุด (flash sales, imports), แบนด์วิดท์เครือข่ายจำกัด, ดิสก์ช้าใน replica หรือคำสั่งรันนานที่แข่งขัน CPU และ I/O ขณะที่ replica พยายามนำการเปลี่ยนแปลงมาใช้

วิธีปฏิบัติในการเลือก lag ที่ยอมรับได้คือจับคู่กับการตัดสินใจที่แดชบอร์ดสนับสนุน:

  • แดชบอร์ด KPI ฝ่ายบริหาร: หลายวินาทีถึงไม่กี่นาทีมักพอรับได้
  • คิวปฏิบัติการ (จัดส่ง, ซัพพอร์ต): มุ่งสู่ near real time โดยปกติเป็นวินาที
  • การปิดบัญชีการเงินหรือตรวจสอบ: รันบน snapshot ควบคุม ไม่ใช่ "สด"
  • หน้าลูกค้า "คำสั่งล่าสุดของฉัน": ต้อง near real time หรืออ่านจาก primary

กฎง่ายๆ: ถ้ารายงานต้องรวมธุรกรรมที่เพิ่ง commit ทันที ต้องอ่านจาก primary (หรือระบบที่ออกแบบมาเพื่อความสดรับประกัน) ตัวอย่างทั่วไปคือการตรวจสอบสต็อกระหว่าง checkout, การตรวจสอบการฉ้อโกง, และสิ่งที่ต้องการการกระทำทันที

ตัวอย่าง: แดชบอร์ดฝ่ายขายสามารถอ่านจาก replica และรีเฟรชทุกนาทีได้อย่างปลอดภัย แต่หน้าการยืนยันคำสั่งควรอ่านจาก primary เพราะการแสดง "ไม่พบคำสั่ง" สำหรับคำสั่งที่เพิ่งส่งจะกลายเป็นเรื่องซัพพอร์ตแน่นอน

ถ้าแอปของคุณหรือเครื่องมือ no-code ให้เลือกการเชื่อมต่อฐานข้อมูลได้ (เช่น ชี้หน้าจออ่านอย่างเดียวไปที่ replica ใน AppMaster) คุณสามารถแยกได้โดยไม่ต้องเปลี่ยนการออกแบบ UI

ทีละขั้นตอน: การตั้งค่า read replicas สำหรับแดชบอร์ด

จากสคีมาเป็นแดชบอร์ด
ออกแบบข้อมูลและสร้างแอปพร้อมใช้งานใน production โดยไม่ต้องเขียน backend
ลองใช้งาน

การตั้งค่า replica สำหรับแดชบอร์ดเป็นเรื่องของการตัดสินใจชัดเจนไม่กี่อย่างตั้งแต่ต้น แล้วคอยแยกทราฟฟิกรายงานออกจากฐานข้อมูลหลัก

1) วางโทโปลอจีให้ถูกต้องก่อน

เริ่มจากโทโพโลยี Replica ตัวเดียวมักเพียงพอสำหรับเครื่องมือ BI เดียวและแดชบอร์ดไม่กี่หน้า Replica หลายตัวช่วยเมื่อคุณมีนักวิเคราะห์หลายคนหรือหลายเครื่องมือที่เข้าถึงข้อมูลตลอดวัน ถ้าผู้ใช้ของคุณอยู่ไกลจากภูมิภาคหลัก replica ประจำภูมิภาคช่วยลด latency แต่ก็เพิ่มจุดที่ต้องมอนิเตอร์

ถัดมาคือการเลือก synchronous หรือ asynchronous replication synchronous ให้ความสดดีที่สุดแต่สามารถทำให้การเขียนช้าลง ซึ่งทำลายจุดประสงค์ของหลายทีม Asynchronous เป็นตัวเลือกที่ใช้บ่อยสำหรับแดชบอร์ด ตราบใดที่ทุกคนยอมรับข้อมูลอาจหน่วงเล็กน้อย

2) สร้าง replica เหมือนเซิร์ฟเวอร์สำหรับรายงาน

replica ไม่ใช่สำเนาราคาถูกของ production งานรายงานมักต้องการ CPU มากขึ้น หน่วยความจำมากขึ้นสำหรับการจัดเรียง และดิสก์เร็วสำหรับการสแกน

นี่คือขั้นตอนปฏิบัติสำหรับ PostgreSQL read replicas สำหรับรายงาน:

  • ตัดสินใจจำนวน replica และว่าจะวางที่ไหน (ภูมิภาคเดียวกันหรือใกล้ผู้ใช้)
  • เลือก async vs sync ตามระดับความหน่วงที่แดชบอร์ดยอมรับได้
  • จัดสรรทรัพยากรสำหรับงานอ่านหนัก (CPU, RAM, และ disk IOPS สำคัญกว่าขนาดเก็บข้อมูล)
  • สร้างข้อมูลประจำตัวแบบอ่านอย่างเดียวแยกต่างหากสำหรับผู้ใช้และเครื่องมือรายงาน
  • นำคำสั่งแดชบอร์ดไปยัง replica (ตั้งค่าแอป, เครื่องมือ BI หรือบริการรายงานเล็กๆ ให้ใช้ connection ของ replica)

หลังจาก routing แล้ว ให้ทดสอบด้วยคำสั่งง่ายๆ: รันคำสั่งแดชบอร์ดที่หนักที่รู้จักและยืนยันว่าไม่ปรากฏใน activity ของฐานข้อมูลหลักอีกต่อไป

ถ้าคุณสร้างแอปด้วย AppMaster นี่มักหมายถึงการกำหนดการเชื่อมต่อฐานข้อมูลแยกสำหรับรายงานและใช้เฉพาะสำหรับ endpoints ของแดชบอร์ด เพื่อให้ checkout และฟลว์เชิงธุรกรรมอื่นๆ มีเส้นทางที่เร็วของตัวเอง

การควบคุมการเข้าถึงและความปลอดภัยสำหรับผู้ใช้รายงาน

replica ดีสำหรับแดชบอร์ด แต่ก็ยังต้องมีกรอบการป้องกัน ปฏิบัติต่อมันเหมือนทรัพยากรที่แชร์: ให้เครื่องมือรายงานเข้าถึงเท่าที่จำเป็น และจำกัดความเสียหายที่คำสั่งแย่ๆ อาจทำได้

เริ่มจากการสร้างผู้ใช้ฐานข้อมูลแยกสำหรับรายงาน หลีกเลี่ยงการใช้ credentials หลักของแอป แม้จะชี้ไปที่ replica ก็ตาม จะช่วยให้ตรวจสอบกิจกรรม เปลี่ยนรหัสผ่าน และควบคุมสิทธิ์ได้ง่ายขึ้น

นี่คือแนวทางง่ายๆ ที่เข้ากับทีมส่วนใหญ่:

-- Create a dedicated login
CREATE ROLE report_user LOGIN PASSWORD '...';

-- Allow read-only access to a schema
GRANT CONNECT ON DATABASE yourdb TO report_user;
GRANT USAGE ON SCHEMA public TO report_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO report_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO report_user;

-- Put safety limits on the role
ALTER ROLE report_user SET statement_timeout = '30s';
ALTER ROLE report_user SET idle_in_transaction_session_timeout = '15s';

ต่อมา ควบคุมการเกิด connection storm เครื่องมือและแดชบอร์ดมักเปิดการเชื่อมต่อหลายรายการ โดยเฉพาะเมื่อ widget หลายตัวรีเฟรชพร้อมกัน จำกัดการเชื่อมต่อรายงานที่ระดับฐานข้อมูลและที่ pooler แยกจากทราฟฟิกเชิงธุรกรรมของคุณ

รายการตรวจสอบเชิงปฏิบัติ:

  • ใช้ผู้ใช้แบบอ่านอย่างเดียว (ไม่มี INSERT/UPDATE/DELETE และไม่มีการเปลี่ยนแปลงสคีมา)
  • ตั้งค่า timeouts ต่อบทบาทเพื่อจัดการคำสั่งยาวและเซสชันเฉยๆ
  • จำกัด max connections สำหรับผู้ใช้รายงานให้อยู่ในจำนวนปลอดภัย
  • จำกัดการเข้าถึงเฉพาะสคีมาและตารางที่แดชบอร์ดต้องการ
  • ซ่อนหรือลบคอลัมน์ที่ละเอียดอ่อน (PII, ความลับ, โทเค็น) จากมุมมองรายงาน

ถ้าต้องแสดงข้อมูลลูกค้าบางส่วน อย่าไว้ใจว่า "คนจะระมัดระวัง" สร้างมุมมองรายงานที่ซ่อนหรือแฮชฟิลด์ละเอียดอ่อน หรือรักษาสคีมารายงานที่คัดกรอง เมื่อทีมสร้างแดชบอร์ดด้วย AppMaster ให้ใช้ connection string ของ replica และผู้ใช้รายงานที่กำหนดเฉพาะเพื่อให้แอปที่สร้างอ่านได้อย่างปลอดภัยโดยไม่แตะต้องการเขียนของ production

การควบคุมเหล่านี้ทำให้ PostgreSQL read replicas สำหรับการรายงานเร็ว คาดเดาได้ และยากต่อการใช้งานผิดพลาด

การมอนิเตอร์เพื่อไม่ให้แดชบอร์ดมีเรื่องเซอร์ไพรส์

แดชบอร์ดเดียวข้ามแพลตฟอร์ม
สร้างแดชบอร์ดบนมือถือและเว็บที่ดึงข้อมูลจากฐานข้อมูลรายงานเดียวกัน
Build in AppMaster

replica จะช่วยก็ต่อเมื่อมันทำงานได้คาดเดาได้ สองอย่างที่มักสร้างความประหลาดใจให้ทีมคือ replication lag ที่เงียบ (แดชบอร์ดผิด) และสไปก์ของทรัพยากรบน replica (แดชบอร์ดช้า) การมอนิเตอร์ควรจับทั้งสองอย่างก่อนผู้ใช้จะพบ

เริ่มจากการวัด lag และตกลงร่วมกันว่า "สดพอ" หมายถึงอะไร สำหรับแดชบอร์ดรายงานหลายแบบ 30 ถึง 120 วินาทีมักเพียงพอ สำหรับบางกรณี (เช่น สต็อกหรือการตรวจการฉ้อโกง) แม้ 5 วินาทีอาจมากไป เลือกตัวชี้วัดแล้วเตือนเมื่อเกิน

สัญญาณที่ควรดูสำหรับ PostgreSQL read replicas สำหรับการรายงาน:

  • replication lag (เวลาและไบต์) แจ้งเตือนเมื่อเกินเกณฑ์เป็นเวลานานกว่าหลายนาที ไม่ใช่สไปก์แค่ครั้งเดียว
  • สุขภาพ replica: CPU, แรงกดดันหน่วยความจำ, และการอ่านดิสก์ในชั่วโมงรายงานสูงสุด
  • การอิ่มตัวของการเชื่อมต่อบน replica (เซสชันแดชบอร์ดมากเกินไปอาจดูเหมือน "ฐานข้อมูลช้า")
  • คำสั่งช้าบน replica โดยใช้สถิติและล็อกของ replica เอง (อย่าสมมติว่า primary บอกทุกอย่าง)
  • Autovacuum และ bloat บน replica การอ่านจะเสื่อมเมื่อตารางหรือดัชนีบวม

การติดตามคำสั่งช้าควรให้ความสำคัญเป็นพิเศษ รูปแบบความล้มเหลวที่พบบ่อยคือแดชบอร์ดที่ทำงานดีในการทดสอบแต่กลายเป็น "เทศกาลสแกนทั้งตาราง" ใน production ให้แน่ใจว่า replica มีมอนิเตอร์แบบเดียวกับ primary รวมถึงคำสั่งยอดนิยมตามเวลารวมและตามเวลาเฉลี่ย

สุดท้าย ตัดสินใจล่วงหน้าว่าแอปจะทำอย่างไรเมื่อ replica ใช้งานไม่ได้หรือหน่วงเกินไป เลือกพฤติกรรมหนึ่งและนำไปใช้สม่ำเสมอ:

  • แสดงแบนเนอร์ว่า "ข้อมูลล่าช้า" เมื่อ lag เกินเกณฑ์
  • ปิดชั่วคราวชาร์ตหนักที่สุดและเก็บสรุปน้ำหนักเบาไว้
  • ย้อนกลับไปใช้ผลลัพธ์แคชสำหรับหน้าต่างเวลาคงที่ (เช่น 15 นาทีล่าสุด)
  • คืนค่าการอ่านที่สำคัญกลับไป primary เฉพาะบางหน้าจอ
  • ใส่แดชบอร์ดในโหมดบำรุงรักษาอ่านอย่างเดียวจนกว่า replica ฟื้น

ถ้าคุณสร้างแดชบอร์ดภายใน AppMaster ปฏิบัติต่อ replica เป็นแหล่งข้อมูลแยก: มอนิเตอร์แยก และออกแบบแดชบอร์ดให้ลดระดับอย่างเหมาะสมเมื่อความสดหรือประสิทธิภาพลดลง

ความผิดพลาดและกับดักที่พบบ่อย

ออกแบบสำหรับ near real time
ออกแบบแผงผู้ดูแลและ KPI ที่ทนต่อความหน่วงและยังตอบสนองดี
เริ่มต้น

replica ช่วยได้ แต่ไม่ใช่ปุ่มวิเศษที่ทำให้การรายงานฟรีทั้งหมด ปัญหา replica ส่วนใหญ่เกิดจากการปฏิบัติต่อมันเหมือนคลังข้อมูลวิเคราะห์ที่ไม่จำกัด แล้วประหลาดใจเมื่อแดชบอร์ดช้าหรือผิด

ข้อพลาดง่ายๆ ที่มองข้ามได้: replica ก็รับภาระเกินได้เช่นกัน การสแกนตารางกว้างๆ, join หนัก, หรือ "SELECT *" เพื่อส่งออกสามารถผลัก CPU และดิสก์จนเกิด timeout ถ้า replica ใช้ฮาร์ดแวร์เล็กกว่าหลัก (ปกติเพื่อลดค่าใช้จ่าย) การชะลอตัวจะปรากฏเร็วยิ่งขึ้น

กับดักที่เจ็บปวดที่สุดได้แก่:

  • ส่งหน้าจอเรียลไทม์ที่สำคัญไปยัง replica หากแดชบอร์ดใช้ยืนยันการเช็คเอาท์หรือแสดงสต็อกสด replication lag อาจทำให้ข้อมูลหาย
  • ให้เครื่องมือ BI เปิดการเชื่อมต่อมากเกินไป บางเครื่องมือรีเฟรชไทล์หลายอันพร้อมกัน และแต่ละไทล์อาจเปิดเซสชันของตัวเอง
  • สมมติว่าดัชนีเพียงพอ ดัชนีไม่สามารถแก้คำสั่งที่ดึงล้านแถว กลุ่มบนคีย์ผิด หรือ join ไม่มีการจำกัด รูปแบบคำถามและปริมาณข้อมูลมีผลมากกว่าดัชนีเพิ่มอีกตัว
  • ลืมว่า "เร็วครั้งเดียว" ไม่เท่ากับ "เร็วเสมอ" คำสั่งที่เร็วในตอนเช้าอาจช้าหลังจากข้อมูลโตขึ้น หรือเมื่อหลายคนรีเฟรชรายงานเดียวกัน
  • ไม่วางแผนพฤติกรรมกรณี failover ระหว่าง failover replica อาจถูกยกระดับหรือเปลี่ยน และลูกค้าอาจเจอข้อผิดพลาดอ่านอย่างเดียวหรือ endpoint เก่า

ตัวอย่างสมจริง: เครื่องมือ BI รีเฟรชหน้ารายงาน "คำสั่งวันนี้" ทุกนาที ถ้ามันรัน 5 คำสั่งหนักต่อการรีเฟรชและมีคน 20 คนเปิด นั่นคือ 100 ครั้งระเบิดคำสั่งหนักต่อนาที Primary อาจรอด แต่ replica อาจทรุด

ถ้าคุณสร้างแดชบอร์ดภายในแพลตฟอร์มอย่าง AppMaster ปฏิบัติต่อฐานข้อมูลรายงานเป็นเป้าหมายแยกพร้อมขีดจำกัดการเชื่อมต่อและกฎ "ความสดที่ต้องการ" เพื่อไม่ให้ผู้ใช้เผลอพึ่งพาข้อมูลที่หน่วง

รูปแบบการออกแบบที่ทำให้การรายงานเร็วขึ้นบน replica

replica ให้เวลาหายใจ แต่ไม่ได้ทำให้ทุกแดชบอร์ดเร็วโดยอัตโนมัติ ผลลัพธ์ดีที่สุดมาจากการปรับรูปแบบคำสั่งรายงานให้ทำงานน้อยลงและคาดเดาได้มากขึ้น รูปแบบเหล่านี้ทำงานได้ดีกับ PostgreSQL read replicas สำหรับการรายงานเพราะลดการสแกนหนักและการรวมซ้ำ

แยก "เลเยอร์รายงาน"

พิจารณาสคีมารายงานเฉพาะ (เช่น reporting) ที่มีมุมมองคงที่และตารางช่วยเหลือ วิธีนี้ทำให้เครื่องมือ BI และแดชบอร์ดไม่ไปโดนตารางธุรกรรมดิบโดยตรง และให้ที่เดียวในการปรับจูน มุมมองรายงานดีๆ ย่อมซ่อน join ที่ยุ่งเหยิงเพื่อให้คำสั่งแดชบอร์ดง่าย

พรีแอกกรีเกตสิ่งที่แพง

ถ้าแดชบอร์ดคำนวณยอดเดิมซ้ำตลอดวัน (รายได้รายวัน, คำสั่งตามสถานะ, สินค้าขายดี) หยุดคำนวณใหม่ทุกครั้ง สร้างตารางสรุปหรือ materialized view ที่เก็บตัวเลขเหล่านี้ไว้แล้ว

ตัวเลือกที่พบบ่อย:

  • การรวบรวมรายวันหรือรายชั่วโมง (ตามวันที่, ภูมิภาค, ช่องทาง)
  • ตาราง snapshot "ล่าสุด" (สต็อก, ยอดคงเหลือบัญชี)
  • ตาราง Top-N (สินค้าขายดี, ลูกค้าท็อป)
  • ตาราง fact ที่ denormalize คอลัมน์เพื่อการกรองที่เร็วขึ้น

รีเฟรชเมตริกหนักตามตารางเวลา

รีเฟรชการสรุปด้วยงานที่ตั้งเวลาไว้ โดยเฉพาะนอกชั่วโมงพีค ถ้าธุรกิจยอมรับการอัปเดตทุก 5 นาที คุณแลกความหน่วงเล็กน้อยกับแดชบอร์ดที่เร็วขึ้นมาก สำหรับชุดข้อมูลใหญ่ การอัปเดตเชิงเพิ่มทีละน้อย (เฉพาะแถวใหม่ตั้งแต่รันก่อนหน้า) มักถูกกว่าการรีเฟรชทั้งก้อน

แคชสิ่งที่ผู้ใช้คลิกบ่อย

ถ้า widget เดิมๆ ถูกขอซ้ำบ่อย ให้แคชผลลัพธ์ที่เลเยอร์แอปช่วงสั้นๆ (30 ถึง 120 วินาทีมักพอ) เช่น ไทล์ "ยอดขายวันนี้" แคชแยกตามบริษัทหรือสโตร์ ในเครื่องมืออย่าง AppMaster การแคชแบบนี้มักเพิ่มง่ายโดยใส่รอบๆ endpoint ของ API ที่ป้อนแดชบอร์ด

กฎง่ายๆ: ถ้าคำสั่งช้าและเป็นที่นิยม จะต้อง pre-aggregate หรือ cache หรือทั้งสอง

ตัวอย่างสมจริง: รายงานการขายโดยไม่ทำให้ checkout ช้าลง

ทำให้คำค้นรายงานคงที่และเสถียร
สร้างเลเยอร์รายงานที่มี endpoints ชัดเจน แทนคำสั่ง BI แบบ ad hoc
เริ่มตอนนี้

สมมติแอปอีคอมเมิร์ซขนาดเล็ก ฐานข้อมูลหลักจัดการล็อกอิน ตะกร้า การชำระเงิน และอัปเดตคำสั่งตลอดวัน ทีมต้องการแดชบอร์ดที่โชว์รายได้รายชั่วโมง สินค้าขายดี และการคืนเงิน

ก่อนเปลี่ยน แดชบอร์ดรันคำสั่งหนักบนฐานข้อมูลหลัก ใกล้สิ้นเดือน ใครสักคนเปิดชาร์ต "30 วันที่ผ่านมาแยกตามสินค้า" และมันสแกนตาราง orders จำนวนมาก การเช็คเอาท์เริ่มรู้สึกช้าเพราะคำสั่งรายงานแข่งทรัพยากร CPU, หน่วยความจำ และการอ่านดิสก์

การแก้ไขง่ายๆ: ย้ายการอ่านแดชบอร์ดไปยัง replica ด้วย PostgreSQL read replicas สำหรับการรายงาน primary ยังคงเขียนเร็ว ในขณะที่ replica ตอบคำสั่งอ่าน แดชบอร์ดชี้ไปที่ connection string ของ replica ไม่ใช่ primary

ทีมยังตั้งกฎความสดชัดเจนเพื่อให้ไม่มีใครคาดหวังตัวเลขเรียลไทม์:

  • แสดง "ข้อมูลอัปเดตก่อน X นาที" บนแดชบอร์ด
  • อนุญาตหน่วงได้สูงสุด 5 นาทีในชั่วโมงปกติ
  • ถ้า lag เกิน 10 นาที ให้สลับแดชบอร์ดเป็น "โหมดหน่วง" และหยุดชาร์ตหนักที่สุด
  • เก็บการเช็คเอาท์และอัปเดตคำสั่งไว้ที่ primary เสมอ

หลังการเปลี่ยน ผลลัพธ์ชัดเจน การเช็คเอาท์คงที่แม้ในช่วงสไปก์ของรายงาน และชาร์ตโหลดเร็วขึ้นเพราะไม่แข่งกับธุรกรรม

สิ่งที่ต้องสื่อให้ผู้ใช้ทราบตรงไปตรงมา: แดชบอร์ดเป็น "near real time" ไม่ใช่แหล่งความจริงสำหรับ 10 วินาทีล่าสุด หากใครต้องการจำนวนที่แม่นยำสำหรับการกระทบยอด ควรรันการส่งออกตามตารางหรือรายงานสิ้นวัน

ถ้าคุณสร้างแอปด้วยแพลตฟอร์มอย่าง AppMaster ให้ปฏิบัติต่อการรายงานเป็น connection อ่านอย่างเดียวตั้งแต่วันแรกเพื่อให้ฟลว์เชิงธุรกรรมคาดเดาได้

ตรวจเช็ครวดเร็วและขั้นตอนต่อไป

ก่อนจะชี้แดชบอร์ดไปยัง replica ให้ตรวจความสมเหตุสมผลเล็กน้อย การตั้งค่าและนิสัยไม่กี่อย่างป้องกันความประหลาดใจที่พบบ่อย: ตัวเลขหน่วง, timeout, และการเขียนโดยไม่ได้ตั้งใจ

นี่คือรายการตรวจสอบด่วนที่ควรตั้งค่าก่อนส่งทราฟฟิกไปยัง replica:

  • ทำให้การเชื่อมต่อรายงานเป็นอ่านอย่างเดียว (ใช้ผู้ใช้เฉพาะและบังคับธุรกรรมแบบอ่าน)
  • แยกการเชื่อมต่อรายงานออกจากทราฟฟิกของแอป (pool แยกและขีดจำกัดการเชื่อมต่อที่เหมาะสม)
  • ยืนยันว่า replica มีดัชนีที่แดชบอร์ดพึ่งพา (replica คัดลอกดัชนี แต่ตรวจสอบว่าคุณไม่ได้พลาดการเปลี่ยนแปลงล่าสุด)
  • ตั้ง statement และ lock timeout สำหรับคำสั่งรายงานเพื่อไม่ให้ชาร์ตแย่คำสั่งทั้งหมด
  • ตรวจสอบว่าแผนภูมิทนต่อความหน่วงเล็กน้อย (แสดง timestamp "as of" หรือปัดเป็นนาทีเมื่อจำเป็น)

เมื่อทราฟฟิกไหล ให้ปฏิบัติการมอนิเตอร์เป็นกิจวัตรสัปดาห์ละครั้ง ไม่ใช่การเต้นหนีไฟ เรื่องนี้สำคัญเป็นพิเศษสำหรับ PostgreSQL read replicas สำหรับการรายงานที่ "มันทำงานเมื่อวาน" อาจเปลี่ยนเร็วเมื่อปริมาณข้อมูลเพิ่ม

รายการตรวจสอบมอนิเตอร์รายสัปดาห์ (10 นาที):

  • replication lag: ดู lag ทั่วไปและสไปก์ที่แย่ที่สุดในชั่วโมงพีค
  • คำสั่งช้า: ติดตามผู้กระทำผิดชั้นนำตามเวลารวม ไม่ใช่แค่ครั้งเดียว
  • การเชื่อมต่อ: ตรวจสอบ max connections, การอิ่มตัวของ pool, และการเชื่อมต่อเฉยๆ ที่สะสม
  • ดิสก์และ CPU: replica อาจคอขวดที่ storage ในช่วงสแกนหนัก
  • คำสั่งล้มเหลว: มองหา timeout, คำสั่งที่ถูกยกเลิก, หรือข้อผิดพลาดสิทธิ์

ขั้นตอนต่อไปเกี่ยวกับกฎการ routing และแผนสำรอง ตัดสินใจว่าหน้าไหนอ่านจาก replica ได้เสมอ (แดชบอร์ด, การส่งออก, รายงานแอดมิน) และหน้าไหนต้องอยู่บน primary (สิ่งที่ต้องสดทันที) กำหนดว่าจะทำอย่างไรเมื่อ lag เกินขีดจำกัดของคุณ: แสดงคำเตือน, สลับการอ่านกลับ primary สำหรับบางหน้า, หรือปิดชาร์ตหนักชั่วคราว

ถ้าคุณสร้างแดชบอร์ดหรือเครื่องมือแอดมิน AppMaster อาจเป็นวิธีปฏิบัติที่ดีในการส่งมอบอย่างรวดเร็วพร้อมชี้หน้ารายงานไปยัง replica เพื่อให้แอปเชิงธุรกรรมหลักยังทำงานลื่นไหล

ง่ายต่อการเริ่มต้น
สร้างบางสิ่งที่ น่าทึ่ง

ทดลองกับ AppMaster ด้วยแผนฟรี
เมื่อคุณพร้อม คุณสามารถเลือกการสมัครที่เหมาะสมได้

เริ่ม
ใช้ PostgreSQL read replicas สำหรับการรายงาน: รักษาแดชบอร์ดให้เร็ว | AppMaster