- เพื่อแก้โจทย์ ความต้องการสร้าง 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 ความคิดเห็น
typstเป็นซอฟต์แวร์ที่เคยถูกแนะนำมาหลายครั้ง แต่ไม่เคยนึกว่าจะใช้ทำงานแบบนี้ได้LaTeX: ถ้ารันด้วย Docker Image จะไม่ได้ความเร็วระดับเดียวกับ
typstGoogle Docs: น่าแปลกที่แก้ไขได้ไม่ยืดหยุ่นอย่างที่คิด
เมื่อพิจารณาสองข้อนี้แล้ว ก็ถือเป็นตัวเลือกใหม่ครับ
ว้าว ยอดมากเลย
สเกลนี่ไม่ธรรมดาจริง ๆ
ในอุตสาหกรรมการเงิน มีความต้องการให้สร้างเอกสารยืนยันธุรกรรมนับล้านรายการและเอกสารที่เกี่ยวข้องกับภาษีให้เสร็จภายในไม่กี่นาที
หากล่าช้า ก็มีความเสี่ยงที่จะถูกหน่วยงานกำกับดูแลอย่าง BaFin ปรับ
ก็แอบสงสัยเหมือนกันว่าทำไมถึงต้องมีความต้องการแบบนี้ครับ ฮ่าๆ
คำนวณโดยใช้หน่วยมาตรฐานอย่างสม่ำเสมอ
เป้าหมาย: 1,666.7 รายการ/วินาที
ประมวลผลแบบขนานด้วย Lambda 10 ตัว: 29.4 รายการ/วินาที, หากสเกลเอาต์เป็น Lambda 570 ตัวก็สามารถบรรลุเป้าหมายได้
เครื่องมือสร้าง PDF แบบเดิม (เดี่ยว):
เจ๋งดีนะ