SQS for Asynchronous Tasks and Why It Matters

สำหรับคนที่สงสัยว่า asynchronous task คืออะไร? ว่ากันง่ายๆ เลย มันคืองานที่ไม่จำเป็นต้องทำ ณ เวลานั้น หรือคืองานที่ถูกรันไม่พร้อมกับ process หลัก ส่วน asynchronous task queue ก็คือการที่เรามี queue เพื่อจัดการงานเหล่านั้น มีคอนเซปง่ายๆ ประมาณว่า ถ้าเรามีงานอยู่งานหนึ่ง แต่เราไม่มีเวลาทำเลย เราจะฝากเพื่อนร่วมงานให้ช่วยทำแทนเรา! ในที่นี้เพื่อนเราก็คือ queue ของเรานั่นเอง แลดูเป็นคนขี้เกียจเนอะ 🙂

ทำไม Asynchronous Task Queue ถึงสำคัญ?

เวลาที่เราพัฒนาเว็บแอพพลิเคชั่นขึ้นมาสักระบบหนึ่ง มักจะมีงานต่างๆ เช่น ส่งอีเมล ดึงข้อมูลใหญ่ๆ จากฐานข้อมูลมาคำนวณค่าต่างๆ สร้างรายงานเกี่ยวกับการเงิน ส่งข้อมูลผ่าน API ไปยังระบบอื่นๆ บางเว็บแอพพลิเคชั่นอาจจะมีการทำ image processing หนักๆ อีกด้วย งานเหล่านี้ถ้าเราเอามา process อยู่ภายในระบบเดียวและเป็นแบบ synchronous จะทำให้เครื่องเซิฟเวอร์ของเราโหลดหนักมาก และถ้าฐานลูกค้าเราใหญ่ขึ้นระบบเราอาจจะล่มได้ถ้าไม่มีการจัดการที่ดี ดังนั้นจะดีกว่าไหมถ้าเราแยก process เหล่านั้นออกมาจากเซิฟเวอร์หลัก แล้วก็ค่อยๆ จัดการงานเหล่านั้น? ด้านล่างนี้เป็นเหตุผลหลักๆ ว่าทำไม asynchronous taks queue ถึงสำคัญ รูปที่ 1 ด้านล่างนี้เป็นรูปแสดงการทำงานคร่าวๆ ของ asynchronous taks queue (ต่อจากนี้จะขอเขียนสั้นๆ ว่า queue นะครับ)

Asynchronous Processing with Queue

รูปที่ 1: การทำงานคร่าวๆ ของ asynchronous taks queue

การขยายขีดความสามารถ (Scalability)

แน่นอนว่าเรื่องนี้สมควรเป็นเรื่องหลักและเรื่องแรกในยุคปัจจุบัน การทำเว็บแอพพลิเคชั่นถ้าเราไม่คำนึงถึง scalability ในระยะยาวระบบของเราจะไม่สามารถรองรับผู้เข้าใช้งานได้อีก อาจจะได้ แต่อาจจะต้องเสียค่าใช้จ่ายเพิ่มขึ้นมากอย่างไม่จำเป็น การที่เรามี queue อยู่ ทำให้เราสามารถกระจายงานต่างๆ ไปให้เครื่องเซิฟเวอร์อื่นๆ ช่วยกัน process ได้ เช่นถ้าเราทำระบบ image processing เราอาจจะมีเซิฟเวอร์สำหรับ front-end เครื่องเดียว มี queue 1 queue และมีเครื่องสำหรับ process image อยู่ 2 เครื่อง ถ้าเมื่อไหร่ก็ตามเรามีงานเข้ามาเยอะขึ้น เราก็สามารถสปินเครื่องสำหรับ process image เพิ่มขึ้นมาได้ โดยไม่มีผลกระทบอะไรกับเซิฟเวอร์ที่เป็น front-end เลย สังเกตว่าเครื่อง front-end ของเราทำงานน้อยมาก มีหน้าที่แค่ส่งงานเข้า queue

ความน่าเชื่อถือ (Reliability)

เรื่องความน่าเชื่อถือก็เป็นเรื่องที่จำเป็นที่ต้องคิดถึงในยุคนี้ เพราะว่าไม่มีระบบไหน หรือเครื่องเซิฟเวอร์ไหนมี uptime 100% แน่นอน บางทีเครื่องที่เราต่อไปอาจจะล่มได้ทำให้ข้อมูลที่เราส่งไปเกิดความล่าช้า การที่เรานำ queue มาใช้สามารถทำให้เรา retry กี่ครั้งก็ได้ ว่างานนั้นๆ จะถูกทำให้เสร็จจริง แน่นอนว่าการ retry นี้เป็นการทำงานอยู่ใน background process ผู้ใช้งานจะไม่เห็นสิ่งต่างๆ ที่ทำงานอยู่ในระหว่างการเข้าใช้ระบบของเรา

ความเร็ว (Speed)

เมื่อระบบของเราใหญ่ขึ้น สิ่งที่จะเกิดขึ้นมาเรื่อยๆ คือการเชื่อมต่อกันระหว่างระบบต่างๆ และระบบต่างๆ มันก็ไม่ได้มีเซิฟเวอร์ตั้งอยู่ใกล้ๆ เรา ดังนั้นการส่งข้อมูลจะต้องเกิด latency แน่นอน ถ้าเราไม่แยกส่วนนี้ออกมา process แยก อาจจะทำให้เครื่องที่เป็น front-end ทำงานช้า ยิ่งถ้ามีผู้ใช้เยอะๆ เข้ามาใช้งานในเวลาเดียวกันด้วยแล้ว ระบบของเราก็จะมี UX แย่ๆ ผู้ใช้ก็จะค่อยๆ หายไป

ยกตัวอย่างการส่งอีเมลหาลูกค้าจำนวนล้านคน ถ้าเรารวม process ไว้ที่เดียว เราต้องวนลูปไล่ส่งอีเมลให้กับลูกค้าล้านคนเลย อีกทั้งยังต้องมั่นใจด้วยว่าอีเมลที่เราจะส่ง มันส่งออกไปจริง ถ้าใช้ queue และแยก process ออกไป เราไม่จำเป็นต้องมากังวลเรื่องอะไรแบบนี้อีก 🙂

ที่ Pronto เราทำอย่างไร?

เราใช้ Amazon SQS เป็น queue สำหรับเอาไว้ให้เครื่องต่างๆ มาดึงงานออกไป process เรามีการใช้ในหลายรูปแบบทั้ง

  • การส่งอีเมลแจ้งลูกค้า
  • การสร้างรายงาน Insights จากเว็บของลูกค้า
  • การดึงค่า ranking ของ keywords ที่ใช้ในการ search
  • การสร้าง Google Analytics filters ให้กับลูกค้า
  • การส่งข้อมูลเข้า Elasticsearch หลังจากที่สร้างรายงาน
  • การแก้ข้อมูลบางอย่างที่อาจจะต้องรอให้ระบบอื่นทำเสร็จก่อน
  • และอื่นๆ อีก

SQS นั้นเป็น managed distributed queues มีการรับประกันว่าทุกงานจะต้องถูกทำ ระบบมีความปลอดภัยเนื่องจาก AWS มี PCI compliance อยู่ และสามารถ scale ได้ ซึ่งเราไม่จำเป็นต้องไปดูแลอะไรเลย มีหน้าที่แค่ส่งงานเข้าไปและดึงงานออกมาทำ เรื่องราคา? โดยเฉลี่ยแล้วทีม Pronto เราส่งงานเข้า queue เป็นหลักล้านงานต่อปี และมั่นใจว่าจะเพิ่มขึ้นต่อไปเรื่อยๆ ค่าใช้จ่ายตามรูปที่ 2 เป็นของปีที่แล้ว นี่เรียกได้ว่าแทบจะใช้ฟรีเลยทีเดียว ราคาถูกมากๆ 😀

SQS Cost over Last Year

รูปที่ 2: ค่าใช้จ่าย SQS เมื่อปีที่ผ่านมา

เรื่องความง่าย? เราใช้แค่ 3 APIs ตามนี้ ก็สามารถนำ queue ไปใช้ได้แล้ว

  • SendMessage - ส่ง message เข้า queue
  • ReceiveMessage - ดึง message จาก queue มา process
  • DeleteMessage - ลบ message ทิ้งจาก queue

ก็สามารถใช้ SQS ได้แล้ว! ถ้าสนใจลองอ่านเพิ่มเติมได้ที่ Amazon SQS Developer Guide


Kan Ouivirach

Kan Ouivirach

Lead Software Architect

Being interested in Agile software development, I joined an Agile team at Pronto Tools as a Research & Development Architect (as Lead Software Architect now). I am an enthusiastic architect who not only has a scientific mindset, but also a practical approach to software solutions.