24 คะแนน โดย GN⁺ 2025-05-05 | 7 ความคิดเห็น | แชร์ทาง WhatsApp
  • เพื่อแก้โจทย์ ความต้องการสร้าง PDF จำนวนมหาศาลในอุตสาหกรรมการเงิน มีการสร้างตัวอย่างสถาปัตยกรรมแบบ serverless บนพื้นฐาน Rust และ Typst
  • ใช้ AWS Lambda, SQS, S3 และ API Gateway โดยตั้งเป้าหมายการเรนเดอร์ที่ 1,667 ไฟล์/วินาที และปรับปรุงประสิทธิภาพด้วยการทำงานขนานและการแคช
  • เพื่อแก้คอขวดของวิธีเดิมอย่าง Puppeteer และ LaTeX จึงใช้ Typst renderer แบบ lightweight และไลบรารี Papermake
  • ด้วย template caching, world caching และการประมวลผลแบบ batch ของ SQS ทำให้ ลดเวลาเฉลี่ยต่อรายการเหลือ 35ms และลดต้นทุนเหลือเพียง 0.35 ยูโร
  • ยังนำเสนอประเด็นที่ต้องพิจารณาเพิ่มเติมสำหรับการใช้งานจริง เช่น monitoring, การลงลายมือชื่อ/การเข้ารหัส และการ deploy หลาย region

Making millions in minutes, why?

  • ในอุตสาหกรรมการเงิน มีความต้องการให้ สร้างเอกสารยืนยันธุรกรรมและเอกสารภาษีหลายแสนถึงหลายล้านฉบับ ภายในไม่กี่นาที
  • หากล่าช้า อาจมี ความเสี่ยงถูกหน่วยงานกำกับดูแล เช่น BaFin ปรับ
  • เป้าหมายคือ สร้าง PDF 1 ล้านไฟล์ภายใน 10 นาที ซึ่งต้องทำได้ 1,667 ไฟล์ต่อวินาที และใช้เวลาประมาณ 0.6ms ต่อ PDF

Architecture Decisions

  • ใช้ สถาปัตยกรรม serverless บนพื้นฐาน Rust, AWS Lambda, SQS, S3 และ API Gateway
  • องค์ประกอบแต่ละส่วน:
    • API Gateway: รับคำขอจากภายนอก
    • SQS: คิวสำหรับงานเรนเดอร์ PDF
    • Lambda function: ประมวลผลคำขอและเรนเดอร์ PDF
    • S3: เก็บ template และไฟล์ PDF ที่ได้

New Rendering Technology

  • เครื่องมือสร้าง PDF แบบเดิมทำงานช้า:
    • Puppeteer: 1~2 วินาที
    • Crystal Reports: 750~900ms
    • LaTeX: 500~800ms
  • Typst ตัวใหม่ทำงานได้เร็ว และให้ข้อความแจ้งข้อผิดพลาดของเอกสารได้ดี
  • มีการพัฒนา ไลบรารี Papermake บน Typst เพื่อรองรับการเรนเดอร์ตามข้อมูล

Creating the template

  • โครงสร้าง template ของ Papermake ประกอบด้วย frontmatter + Typst markup
  • แทรกข้อมูลด้วยตัวแปรในรูปแบบ #data.customer.name เป็นต้น
  • template ตัวอย่างคือเอกสารยืนยันธุรกรรมของ MoneyBank ซึ่งมีข้อมูลลูกค้าและรายละเอียดธุรกรรม

Implementing our two lambda functions

  • Lambda function สองตัวถูกเขียนด้วย Rust
    • Request Handler: รับคำขอจาก API Gateway แล้วส่งงานเรนเดอร์ไปยัง SQS
    • Renderer: รับงานจาก SQS สร้าง PDF และอัปโหลดไปยัง S3
  • Rust มี cold start แทบไม่มี และคอมไพล์เป็น native จึงทำงานได้เร็ว
  • ใช้ Typst + Papermake เพื่อสร้าง PDF แล้วบันทึกผลลัพธ์ลง S3

Terraform definition

  • โครงสร้างพื้นฐานทั้งหมดถูกทำเป็น IaC ด้วย Terraform เพื่อเพิ่มประสิทธิภาพในการจัดการ
  • resource หลัก:
    • S3: ที่เก็บ template และผลลัพธ์
    • SQS: คิวงาน
    • Lambda function: request handler และ renderer
    • API Gateway: endpoint HTTP POST /render
  • Lambda function ทำงานบน Amazon Linux 2023, สถาปัตยกรรม arm64

Performance Tuning

1. Lambda Concurrency

  • หากต้องการประมวลผล PDF 1,667 ไฟล์ต่อวินาที ต้องมี การ invoke พร้อมกันอย่างน้อย 60 ครั้งขึ้นไป
  • ใช้ นโยบาย Auto Scaling เพื่อขยายจำนวนอินสแตนซ์ของ Lambda แบบไดนามิกตามความลึกของคิว SQS

2. Caching

  • งานอย่าง คำขอไปยัง S3, การ parse template และการ compile Typst world ถูกแคชเป็น shared resource เพื่อเพิ่มความเร็วในการประมวลผล
  • ใช้ OnceCell และ RwLock เพื่อให้ได้ความเร็วระดับ 35ms ในสถานะ hot start

3. Batching

  • ใช้ ความสามารถในการประมวลผลแบบ batch ของ SQS เพื่อลด network overhead และเพิ่มประสิทธิภาพ
  • จัดกลุ่มข้อมูลตาม template เพื่อ หลีกเลี่ยงการโหลด template ซ้ำ

Results

  • อ้างอิงจากสภาพแวดล้อม Lambda แบบขนาน 10 ตัว:
    • เวลาในการประมวลผล: 11 วินาที
    • throughput ต่อวินาที: 91 ไฟล์
  • แม้จะยังไม่ถึงเป้าหมาย แต่ ถ้าเพิ่มระดับ parallelism ก็มีโอกาสไปถึงได้
  • ความเร็วในการเรนเดอร์: เฉลี่ย 34ms (หลังใช้การแคช)

Cost calculation

  • อิงตามราคาของ Lambda:
    • คำขอ 1 ล้านรายการมีต้นทุนรวม 0.35 ยูโร
    • ค่าคอมพิวต์: 0.15 ยูโร
    • ค่าเรียกใช้งาน: 0.20 ยูโร
  • การทดสอบส่วนใหญ่ทำได้ภายใน free tier และมีความคุ้มค่าสูงมาก

Next Steps

  • กำลังรอการปลดข้อจำกัดจำนวนการเรียกใช้งานพร้อมกันของ AWS เพื่อ ทดสอบการเรนเดอร์จริง 1 ล้านไฟล์
  • ประเด็นที่ต้องพิจารณาเมื่อใช้งานจริง:
    • การ route คิวตาม template ID
    • การตรวจจับความขัดข้องและ logic การ retry
    • การ deploy หลาย region
    • การจัดการลายมือชื่ออิเล็กทรอนิกส์และการเข้ารหัส เป็นต้น

บทสรุป

  • โปรเจกต์นี้เป็น ตัวอย่างการสร้าง pipeline สำหรับสร้าง PDF ประสิทธิภาพสูงด้วย Rust และ Typst
  • โค้ดทั้งหมด: papermake-aws GitHub
  • เอนจินเรนเดอร์: Typst, ไลบรารีเรนเดอร์: Papermake

7 ความคิดเห็น

 
crypto 2025-05-12

typst เป็นซอฟต์แวร์ที่เคยถูกแนะนำมาหลายครั้ง แต่ไม่เคยนึกว่าจะใช้ทำงานแบบนี้ได้

LaTeX: ถ้ารันด้วย Docker Image จะไม่ได้ความเร็วระดับเดียวกับ typst
Google Docs: น่าแปลกที่แก้ไขได้ไม่ยืดหยุ่นอย่างที่คิด

เมื่อพิจารณาสองข้อนี้แล้ว ก็ถือเป็นตัวเลือกใหม่ครับ

 
bluekai17 2025-05-08

ว้าว ยอดมากเลย

 
jk34011 2025-05-07

สเกลนี่ไม่ธรรมดาจริง ๆ

 
fortune 2025-05-06

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

ก็แอบสงสัยเหมือนกันว่าทำไมถึงต้องมีความต้องการแบบนี้ครับ ฮ่าๆ

 
savvykang 2025-05-05

คำนวณโดยใช้หน่วยมาตรฐานอย่างสม่ำเสมอ

เป้าหมาย: 1,666.7 รายการ/วินาที
ประมวลผลแบบขนานด้วย Lambda 10 ตัว: 29.4 รายการ/วินาที, หากสเกลเอาต์เป็น Lambda 570 ตัวก็สามารถบรรลุเป้าหมายได้

เครื่องมือสร้าง PDF แบบเดิม (เดี่ยว):

  • Puppeteer: 0.5~1 รายการ/วินาที
  • Crystal Reports: 1.1~1.3 รายการ/วินาที
  • LaTeX: 1.2~2 รายการ/วินาที
 
t7vonn 2025-05-05

เจ๋งดีนะ