tva
← บทความเชิงลึก

สร้างคลังข้อมูล Amazon ด้วย FastAPI และ TimescaleDB

SP-API ของ Amazon เปิดให้เข้าถึงข้อมูลการดำเนินงานจำนวนมาก ทั้งคำสั่งซื้อ สินค้าคงคลัง การชำระยอดเงิน และผลการดำเนินงานของแคตตาล็อก ส่วนข้อมูลโฆษณามาจาก Amazon Ads API ซึ่งเป็น API แยกต่างหาก แต่ข้อมูลจะมีประโยชน์ก็ต่อเมื่ออยู่ในรูปแบบที่สืบค้นได้ รายงานของ Amazon มีอายุจำกัด อยู่ภายใต้ขีดจำกัดอัตราการเรียกใช้ และไม่ได้ออกแบบมาเพื่อตอบคำถามการดำเนินงานที่สำคัญที่สุดสำหรับผู้ขายที่ดูแลธุรกิจหลายมาร์เก็ตเพลซ คุณดูได้ว่าเกิดอะไรขึ้น แต่ถามได้ยากว่ากำลังเกิดอะไรขึ้นพร้อมกันในทุกมาร์เก็ตเพลซ หรือแนวโน้มความต้องการย้อนหลังเก้าสิบวันของ ASIN หนึ่งในภูมิภาคการจัดส่งหนึ่งเป็นอย่างไร

บทความนี้อธิบายสถาปัตยกรรมคลังข้อมูล Amazon ที่เราใช้: FastAPI เป็นชั้น API, TimescaleDB เป็นที่เก็บข้อมูลอนุกรมเวลา และ Celery จัดการไปป์ไลน์รายงาน SP-API แบบอะซิงโครนัส เป้าหมายคือระบบที่เก็บข้อมูลที่เราดึงมาจาก API ต่าง ๆ ของ Amazon ในรูปแบบที่สืบค้นได้และคุณควบคุมเอง โดยมีโครงสร้างเพียงพอสำหรับการพยากรณ์ความต้องการและการวิเคราะห์การดำเนินงาน โดยไม่ต้องมีทีมวิศวกรรมข้อมูลมาดูแล

เหตุใดเครื่องมือของ Amazon เองจึงไม่เพียงพอ

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

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

แดชบอร์ด Business Reports ของ Amazon ให้ข้อมูลแนวโน้มแบบรวม แต่ความละเอียดและระยะเก็บรักษาถูกกำหนดโดยการตัดสินใจด้านผลิตภัณฑ์ของ Amazon ไม่ใช่ความต้องการวิเคราะห์ของคุณ หน้าจอโฆษณามีแบบจำลองข้อมูลของตัวเองที่เชื่อมกับข้อมูลการจัดส่งได้ไม่ง่าย ส่วนข้อมูลการชำระยอดเงินมาตามรอบสองสัปดาห์และต้องแยกข้อมูลอย่างซับซ้อนพอสมควรเพื่อกระทบยอดกับคำสั่งซื้อ

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

การเลือกเทคโนโลยี

เราเลือก TimescaleDB เป็นที่เก็บหลัก เพราะข้อมูลการดำเนินงานของ Amazon ส่วนใหญ่เป็นอนุกรมเวลาโดยธรรมชาติ คำสั่งซื้อมีเวลาประทับ สแนปช็อตสินค้าคงคลังแสดงสถานะ ณ จุดเวลา รอบชำระยอดเงินมีวันที่เริ่มและสิ้นสุด ค่าโฆษณาและจำนวนการแสดงผลสะสมตามเวลา TimescaleDB คือ PostgreSQL ที่เพิ่ม hypertable ทำให้การสืบค้นตามช่วงเวลาในข้อมูลขนาดใหญ่มีประสิทธิภาพกว่า PostgreSQL มาตรฐานอย่างมาก โดยยังรองรับ SQL เต็มรูปแบบ ไม่ต้องเรียนภาษาใหม่สำหรับสืบค้น และรูปแบบการดูแลไม่ต่างอย่างมีนัยสำคัญจากการติดตั้ง Postgres ทั่วไป

FastAPI เป็นชั้น API ระหว่าง Celery worker ที่ดึงข้อมูลจาก SP-API กับระบบภายในที่สืบค้นคลังข้อมูล ดูแลการยืนยันตัวตน การตรวจคำขอ และการแปลงการตอบกลับให้อยู่ในรูปแบบที่ส่งได้ โดยใช้โค้ดพื้นฐานซ้ำ ๆ น้อยมาก สำหรับบริการภายในที่ไม่ได้เปิดสู่อินเทอร์เน็ตสาธารณะ เอกสาร OpenAPI ที่ FastAPI สร้างอัตโนมัติมีประโยชน์เป็นพิเศษ เพราะให้ข้อกำหนดส่วนติดต่อที่สืบค้นได้ ทำให้เขียนระบบที่เรียกใช้ใหม่ได้ง่ายโดยไม่ต้องถอดแบบจำลองข้อมูลจากสคีมาฐานข้อมูล

Celery จัดการไปป์ไลน์รายงาน SP-API แบบอะซิงโครนัส การสร้างรายงาน SP-API เป็นอะซิงโครนัสโดยการออกแบบ: ขอรายงาน ตรวจสถานะเป็นระยะ ดาวน์โหลดเมื่อพร้อม และประมวลผลไฟล์ กระบวนการนี้เหมาะกับชุดงานต่อเนื่องของ Celery โดยมีงานเริ่มขอรายงาน งานตามรอบเพื่อตรวจสถานะ งานดาวน์โหลดและเก็บไฟล์ดิบ และงานแยกข้อมูลแล้วโหลดข้อมูลที่มีโครงสร้างเข้า TimescaleDB ส่วน Redis เป็นตัวกลางส่งงานและระบบเก็บผลลัพธ์ของ Celery

แบบจำลองข้อมูล

ตารางหลักสะท้อนกลุ่มข้อมูลหลักของ SP-API หลักการออกแบบคือแต่ละตารางควรตอบคำถามการดำเนินงานประเภทหนึ่งได้ โดยไม่ต้องเชื่อมข้อมูลจากรายงานหลายประเภท

คำสั่งซื้อ เป็น hypertable ที่แบ่งพาร์ทิชันตาม purchase_date แต่ละแถวแทนรายการสินค้าหนึ่งรายการในคำสั่งซื้อ ไม่ใช่คำสั่งซื้อทั้งรายการ เพราะการวิเคราะห์ระดับรายการสินค้า ตาม ASIN ช่องทางจัดการคำสั่งซื้อและจัดส่งสินค้า และมาร์เก็ตเพลซ เป็นระดับความละเอียดที่ใช้บ่อยที่สุด ค่ารวมระดับคำสั่งซื้อคำนวณจากข้อมูลระดับรายการสินค้า ตั้งช่วงพาร์ทิชันไว้ที่หนึ่งสัปดาห์ เพื่อให้การสืบค้นช่วงเวลาย้อนหลังแบบเลื่อนที่ใช้พยากรณ์ความต้องการทำงานได้ดี

สแนปช็อตสินค้าคงคลัง เก็บผลรายงานสินค้าคงคลัง ณ เวลาที่ดึงข้อมูล สินค้าคงคลัง FBA ไม่ใช่กระแสเหตุการณ์ แต่เป็นสถานะที่เปลี่ยนตลอดและประกอบกลับจากคำสั่งซื้อเพียงอย่างเดียวไม่ได้ทั้งหมด เพราะการคืนสินค้า การปรับยอด และการโอนมีผลต่อสินค้าคงคลังโดยไม่มีคำสั่งซื้อที่สอดคล้องกัน เราดึงสแนปช็อตวันละสองครั้งและเก็บเป็นระเบียน ณ จุดเวลา ฟังก์ชัน continuous aggregate ของ TimescaleDB คำนวณค่าเฉลี่ยรายวันและรายสัปดาห์แบบเลื่อนจากสแนปช็อตเหล่านี้ โดยไม่ต้องสแกนประวัติทั้งหมดในการสืบค้น

การชำระยอดเงิน เก็บรายงานการชำระยอดเงินที่แยกข้อมูลแล้ว โดยหนึ่งแถวแทนหนึ่งรายการ แบบจำลองข้อมูลการชำระยอดเงินเป็นหนึ่งในงานแยกข้อมูลที่ซับซ้อนที่สุดในระบบนิเวศ SP-API เพราะ Amazon ใช้รหัสประเภทธุรกรรมต่างกันตามมาร์เก็ตเพลซ และรายการค่าธรรมเนียมมีหลักตั้งชื่อที่ไม่สอดคล้องกันทั้งหมดระหว่างภูมิภาค เราดูแลตารางจับคู่ชื่อประเภทค่าธรรมเนียมจากแต่ละตลาดให้เป็นระบบหมวดหมู่ภายในเดียวกัน

แคตตาล็อก เก็บสแนปช็อตแคตตาล็อกสินค้า ทั้ง ASIN ชื่อ หมวดหมู่ และความสัมพันธ์ของรูปแบบย่อยของสินค้า โดยอัปเดตทุกสัปดาห์ ตารางนี้เป็นข้อมูลอ้างอิงสำหรับตารางอื่นเป็นหลัก และไม่ใช้ hypertable เพราะข้อมูลไม่มีลักษณะอนุกรมเวลาที่มีนัยสำคัญ

การใช้ TimescaleDB ในทางปฏิบัติ

Hypertable เป็นคุณสมบัติหลักของ TimescaleDB การสร้าง hypertable จากตาราง PostgreSQL มาตรฐานใช้คำสั่งเดียวเพื่อระบุคอลัมน์เวลาและช่วงพาร์ทิชัน จากนั้นคำสั่ง SQL มาตรฐานทำงานได้โดยไม่ต้องแก้ไข และตัววางแผนการสืบค้นของ TimescaleDB จะใช้ chunk exclusion โดยอัตโนมัติ เพื่อข้ามพาร์ทิชันที่อยู่นอกช่วงเวลาที่ค้น ทำให้การสืบค้นแบบกำหนดช่วงเวลารวดเร็วแม้ข้อมูลจะมีขนาดใหญ่

Continuous aggregate เป็นคุณสมบัติที่สองที่เราใช้มาก เป็น materialized view ที่ TimescaleDB อัปเดตเฉพาะส่วนที่เพิ่มขึ้นเมื่อมีข้อมูลใหม่เข้า hypertable สำหรับการพยากรณ์ความต้องการ เราดูแล continuous aggregate รายวันของยอดขายแยกตาม ASIN และมาร์เก็ตเพลซ แล้วนำมาคำนวณยอดขายรวมย้อนหลังแบบเลื่อน 7, 30 และ 90 วัน ค่ารวมรายวันนี้อัปเดตอัตโนมัติตามตารางที่กำหนด และการสืบค้นอ่านข้อมูลที่คำนวณไว้แล้วแทน hypertable ทั้งหมด ทำให้การวิเคราะห์บนแดชบอร์ดเร็วพอสำหรับการใช้งานแบบโต้ตอบ

CREATE MATERIALIZED VIEW daily_sales_by_asin
WITH (timescaledb.continuous) AS
SELECT
  time_bucket('1 day', purchase_date) AS day,
  asin,
  marketplace_id,
  SUM(quantity_ordered) AS units_sold,
  SUM(item_price_amount) AS revenue
FROM order_items
GROUP BY day, asin, marketplace_id;

มุมมองนี้รีเฟรชอัตโนมัติตามนโยบายเบื้องหลังของ TimescaleDB ซึ่งเราตั้งให้ทำงานทุกชั่วโมง ยอดรวมย้อนหลังแบบเลื่อน 90 วันที่ใช้พยากรณ์คำนวณด้วยคำสั่ง window function บน materialized view นี้ ไม่ใช่บนตารางรายการสินค้าดิบ

ไปป์ไลน์ Celery

ไปป์ไลน์รายงาน SP-API ทำงานเป็นชุดงาน Celery ตามตารางที่ Celery Beat จัดการ รายงานแต่ละประเภทมีตารางของตัวเอง: ดึงคำสั่งซื้อทุกชั่วโมง สินค้าคงคลังวันละสองครั้ง และการชำระยอดเงินตามรอบสองสัปดาห์ที่สอดคล้องกับรอบชำระยอดของ Amazon

ไปป์ไลน์ของรายงานทุกประเภทมีโครงสร้างเดียวกัน งานตามตารางเริ่มขอรายงานผ่าน SP-API และเก็บรหัสคำขอใน Redis งานตรวจสถานะรันทุกไม่กี่นาทีเพื่อตรวจผ่าน SP-API เมื่อรายงานพร้อมจะเข้าคิวงานดาวน์โหลด งานดาวน์โหลดดึงเอกสารรายงาน เก็บไฟล์ดิบลงดิสก์ และเข้าคิวงานประมวลผล งานประมวลผลแยกข้อมูลในไฟล์แล้วโหลดระเบียนที่มีโครงสร้างเข้า TimescaleDB

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

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

พื้นฐานสำหรับการพยากรณ์ความต้องการ

คลังข้อมูลไม่ได้พยากรณ์ความต้องการโดยตรง แต่ให้พื้นฐานข้อมูลที่ทำให้พยากรณ์ได้ ได้แก่ ข้อมูลยอดขายอนุกรมเวลาที่สะอาดในระดับ ASIN–มาร์เก็ตเพลซ–วัน พร้อมประวัติเพียงพอให้ระบุรูปแบบตามฤดูกาลและประมาณแนวโน้มที่มีความหมายทางสถิติ

Continuous aggregate รายวันที่อธิบายข้างต้นเป็นข้อมูลสำหรับคำนวณสัญญาณความต้องการย้อนหลังแบบเลื่อน 7, 30 และ 90 วัน สัญญาณเหล่านี้ป้อนให้แบบจำลองพยากรณ์อย่างง่าย ทั้งค่าเฉลี่ยเคลื่อนที่ถ่วงน้ำหนักและการคาดการณ์ต่อจากแนวโน้มเชิงเส้นสำหรับสินค้าที่มีความต้องการคงที่ พร้อมตัวคูณปรับด้วยมือสำหรับสินค้าที่มีฤดูกาลซึ่งทราบอยู่แล้ว แบบจำลองทำงานเป็นปลายทาง FastAPI ที่สืบค้น continuous aggregate และคืนค่าพยากรณ์แบบจุดพร้อมช่วงความเชื่อมั่น

เมื่อมีพื้นฐานข้อมูลแล้ว การพยากรณ์ที่ซับซ้อนกว่าก็ทำได้ง่ายขึ้น เราทดลองการปรับเรียบแบบเอ็กซ์โพเนนเชียล Holt-Winters สำหรับสินค้าที่มีวงจรฤดูกาลชัดเจน และการถดถอยอย่างง่ายกับสัญญาณภายนอก เช่น ค่าโฆษณาและการเปลี่ยนราคา สำหรับสินค้าที่ตัวแปรเหล่านี้มีผลต่อความต้องการจริง แต่ในทางปฏิบัติ สำหรับสินค้าส่วนใหญ่ วิธีที่ซับซ้อนเหล่านี้เพิ่มความแม่นยำจากค่าเฉลี่ยเคลื่อนที่ถ่วงน้ำหนักที่ปรับเหมาะสมแล้วได้ไม่มาก คุณภาพข้อมูลและความยาวประวัติมีผลมากกว่าความซับซ้อนของแบบจำลอง

สิ่งที่คลังข้อมูลช่วยให้ทำได้

ควรระบุความสามารถเฉพาะที่คลังข้อมูลทำให้เกิดขึ้น เพราะเป็นการเปลี่ยนสิ่งที่ทำได้ในการดำเนินงานอย่างมีนัยสำคัญ ไม่ใช่เพียงทำรายงานได้เร็วขึ้นเล็กน้อย

การวางแผนสินค้าคงคลังข้ามมาร์เก็ตเพลซทำได้ง่ายขึ้น เมื่อมีข้อมูลอัตราขายในระดับ ASIN–มาร์เก็ตเพลซ และสินค้าคงคลัง FBA ปัจจุบันจากตารางสแนปช็อต เราคำนวณจำนวนวันที่สินค้าคงคลังพอใช้สำหรับทุก SKU ในทุกมาร์เก็ตเพลซ และสร้างคำแนะนำสั่งเติมอัตโนมัติได้ แทนการตรวจด้วยมือทีละมาร์เก็ตเพลซ

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

การวิเคราะห์โฆษณาทำได้ในระดับ ASIN เมื่อเชื่อมข้อมูลโฆษณากับคำสั่งซื้อผ่านรหัสร่วม เราติดตามได้ว่าค่าโฆษณาและยอดขายแบบไม่เสียค่าโฆษณาเปลี่ยนแปลงไปด้วยกันอย่างไรตามเวลา หน้าจอโฆษณาของ Amazon ไม่ตอบคำถามนี้โดยตรง เพราะแสดงยอดขายที่เกิดจากโฆษณา แต่ไม่แสดงยอดขายแบบไม่เสียค่าโฆษณาในช่วงเวลาใกล้เคียงกัน ข้อมูลที่เชื่อมกันแสดงความสัมพันธ์ แต่การระบุว่าการเปลี่ยนแปลงอันดับค้นหาแบบไม่เสียค่าโฆษณาเกิดจากโฆษณา จะต้องมีข้อมูลอันดับและการเปรียบเทียบแบบควบคุมด้วย


บทความที่เกี่ยวข้อง

บทความที่เกี่ยวข้อง