Integration & Messaging — SQS, SNS, Kinesis
SQS, SNS, Kinesis decoupling & messaging
01แนวคิด Decoupling และภาพรวม Integration Services
ในระบบกระจาย (distributed system) เราไม่อยากให้ service ต่างๆ เรียกกันแบบ synchronous ตรงๆ เพราะถ้า service ปลายทางช้าหรือล่ม จะลามมาทำให้ต้นทางพังตาม Decoupling คือการแยก application components ออกจากกันเพื่อให้แต่ละส่วน scale และล้มเหลวได้อย่างอิสระ AWS มี 3 บริการหลักสำหรับเรื่องนี้: SQS (queue), SNS (pub/sub), และ Kinesis (streaming)
- SQS (Simple Queue Service) — message queue model: producer ส่ง message เข้า queue, consumer ดึง (pull) ไปประมวลผลแล้วลบทิ้ง
- SNS (Simple Notification Service) — pub/sub model: publish ครั้งเดียว ส่งถึง subscribers หลายตัวพร้อมกัน (push)
- Kinesis — real-time big data streaming: ingest ข้อมูลปริมาณมหาศาล, อ่านซ้ำ/replay ได้ตาม retention
02SQS Core — Standard vs FIFO
SQS เป็น fully managed queue ที่ producer ใช้ SendMessage ส่ง message เข้า queue และ consumer ใช้ ReceiveMessage ดึงไปประมวลผล จากนั้นต้องเรียก DeleteMessage เพื่อยืนยันว่าประมวลผลเสร็จ (ถ้าไม่ลบ message จะกลับมาให้ดึงใหม่) SQS มี 2 ประเภทหลัก
| คุณสมบัติ | Standard | FIFO |
|---|---|---|
| Ordering | Best-effort | รับประกันตาม message group |
| Delivery | At-least-once (อาจซ้ำ) | Exactly-once (มี dedup) |
| Throughput | แทบไม่จำกัด | จำกัด (300/3000 msg/s, high-throughput mode สูงกว่า) |
| ชื่อ queue | ปกติ | ต้องลงท้าย .fifo |
03Visibility Timeout, Retention และ Delay Queue
เมื่อ consumer ดึง message ไป SQS จะซ่อน message นั้นชั่วคราวไม่ให้ consumer อื่นเห็น ระยะเวลานี้คือ visibility timeout (ค่า default 30 วินาที, ตั้งได้ 0 วินาที ถึง 12 ชั่วโมง) ถ้า consumer ประมวลผลเสร็จและลบ message ก่อนหมดเวลา ก็จบ แต่ถ้าหมดเวลาก่อน message จะกลับมา visible และอาจถูกประมวลผลซ้ำ
- ถ้าประมวลผลนานกว่า timeout ให้เรียก ChangeMessageVisibility เพื่อขยายเวลา
- Message retention — เก็บ message ใน queue ค่า default 4 วัน ปรับได้ตั้งแต่ 60 วินาที ถึง 14 วัน; เกินกว่านี้ message ถูกลบทิ้ง
- Delay queue / DelaySeconds — ซ่อน message ใหม่ตั้งแต่แรกก่อนให้ consumer เห็น สูงสุด 15 นาที (900 วินาที)
04DLQ, Redrive Policy และ Long vs Short Polling
Dead Letter Queue (DLQ) คือ queue สำรองที่รับ message ซึ่งประมวลผลล้มเหลวซ้ำหลายครั้ง โดยตั้ง redrive policy ที่ source queue กำหนด maxReceiveCount เมื่อ ReceiveCount ของ message เกินค่านี้ SQS จะย้าย message ไป DLQ เพื่อแยกออกมาวิเคราะห์ ภายหลังใช้ redrive feature ส่งกลับ source queue ได้
- DLQ ของ FIFO queue ต้องเป็น FIFO และ DLQ ของ Standard queue ต้องเป็น Standard
- ควรตั้ง retention ของ DLQ ให้นาน (เช่น 14 วัน) เพื่อมีเวลา debug
- Long polling — consumer รอจนมี message หรือครบ wait time (ReceiveMessageWaitTimeSeconds 1-20 วินาที, สูงสุด 20s) ลด empty responses และลด API cost
- Short polling — return ทันที (WaitTimeSeconds = 0) แม้ไม่มี message ทำให้ API call ถี่และเปลือง
{
"deadLetterTargetArn": "arn:aws:sqs:us-east-1:111122223333:MyDLQ",
"maxReceiveCount": 5
}05Message Size, Extended Client และ FIFO Dedup/Group
SQS message มีขนาดสูงสุด 256 KB ถ้าต้องส่ง payload ใหญ่กว่านั้น ใช้ SQS Extended Client Library (Java) ที่เก็บ payload จริงไว้ใน S3 แล้วส่งเฉพาะ reference/metadata ผ่าน queue (รองรับได้ถึงระดับ GB)
FIFO Deduplication และ Message Group
- MessageDeduplicationId — ระบุ id เพื่อ dedup; ภายใน deduplication interval 5 นาที message ที่มี id เดียวกันจะถูกมองว่าซ้ำและถูกทิ้ง
- Content-based deduplication — ทางเลือกที่ให้ SQS คำนวณ SHA-256 hash ของ body เป็น dedup id อัตโนมัติ
- MessageGroupId — จัดกลุ่ม message ที่ต้องเรียงลำดับร่วมกัน; group เดียวกันเรียงตามลำดับ, ต่าง group ประมวลผลขนานกันได้ (เพิ่ม parallelism)
aws sqs send-message \
--queue-url https://sqs.us-east-1.amazonaws.com/1111/orders.fifo \
--message-body '{"orderId":"A123"}' \
--message-group-id "customer-42" \
--message-deduplication-id "A123-create"06SNS — Topics, Subscriptions และ Fan-out
SNS เป็น pub/sub: producer publish message ไปยัง topic ครั้งเดียว แล้ว SNS push ไปยังทุก subscription ที่ subscribe กับ topic นั้น subscriber อาจเป็น SQS, Lambda, HTTP/S endpoint, email, SMS, mobile push หนึ่ง topic รองรับ subscriptions จำนวนมาก
Fan-out Pattern: SNS + SQS
แทนที่จะให้ producer ส่งตรงไปทุก queue เอง ให้ publish ไป SNS topic ครั้งเดียว แล้วให้หลาย SQS queue subscribe เข้ากับ topic แต่ละ queue จะได้สำเนา message ของตัวเอง ข้อดีคือ message persist อยู่ใน SQS (ไม่หายถ้า consumer ล่ม), retry/DLQ ได้, และเพิ่ม subscriber ใหม่ภายหลังได้โดยไม่แตะ producer
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "sns.amazonaws.com" },
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:1111:MyQueue",
"Condition": {
"ArnEquals": { "aws:SourceArn": "arn:aws:sns:us-east-1:1111:MyTopic" }
}
}]
}07SNS FIFO Topics และ Message Filtering
SNS FIFO topic ให้ทั้ง ordering และ deduplication เหมือน SQS FIFO ใช้ MessageGroupId และ deduplication id (หรือ content-based dedup) แต่มีข้อจำกัดสำคัญคือ subscribe ได้เฉพาะ SQS FIFO queue เท่านั้น (ไม่รองรับ Lambda/HTTP/email โดยตรง)
Message Filtering
แต่ละ subscription สามารถมี filter policy (JSON) เพื่อรับเฉพาะ message ที่ตรงเงื่อนไข โดย default ตรวจจาก message attributes (ตั้ง FilterPolicyScope เป็น MessageBody เพื่อตรวจ body ได้) ช่วยให้ใช้ topic เดียวแต่แยกการรับของแต่ละ subscriber แทนการสร้างหลาย topic
{
"order_status": ["placed", "shipped"],
"region": [{ "prefix": "ap-" }]
}08Kinesis Data Streams — Shards, Capacity, Consumers
Kinesis Data Streams ใช้ ingest streaming data ปริมาณมหาศาลแบบ real-time ข้อมูลถูกแบ่งเป็น shards producer ส่ง record พร้อม partition key ซึ่งถูก hash เพื่อกำหนด shard ปลายทาง record ที่มี partition key เดียวกันจะไปอยู่ shard เดียวกันและรักษา ordering ภายใน shard นั้น (เรียงด้วย sequence number ที่ Kinesis กำหนดให้)
- แต่ละ shard เขียนได้ 1 MB/s หรือ 1,000 records/s, อ่าน (classic) 2 MB/s แชร์กันทุก consumer
- เกิน limit จะเจอ ProvisionedThroughputExceededException แก้ด้วย partition key ที่กระจายดี และ/หรือ resharding
- Retention — default 24 ชั่วโมง, ขยายได้สูงสุด 365 วัน; consumer replay ข้อมูลได้
- Enhanced fan-out — consumer แต่ละตัวได้ dedicated 2 MB/s ต่อ shard ผ่าน HTTP/2 push (SubscribeToShard) ไม่ต้องแย่ง throughput กัน เหมาะกับ consumer หลายตัว latency ต่ำ
09Kinesis Data Firehose
Kinesis Data Firehose เป็น fully managed service สำหรับโหลด streaming data ไปยังปลายทางแบบ near-real-time (ไม่ใช่ real-time แท้) เพราะมี buffering ตาม buffer size หรือ buffer interval ไม่ต้องบริหาร shard และ ไม่เก็บข้อมูลถาวร (no storage/replay ต่างจาก Data Streams)
- Destinations: Amazon S3, Amazon Redshift (ผ่าน S3), Amazon OpenSearch, Splunk, และ HTTP endpoints/third-party
- รองรับ data transformation ด้วย Lambda และแปลงรูปแบบ (เช่น เป็น Parquet/ORC) ก่อนเขียนลง S3
- จ่ายตามปริมาณข้อมูลที่ส่ง (pay-as-you-go) ไม่มี provisioning capacity
| คุณสมบัติ | Data Streams | Data Firehose |
|---|---|---|
| ลักษณะ | Real-time, manage shards | Near-real-time, fully managed |
| Storage/Replay | เก็บตาม retention, replay ได้ | ไม่เก็บ, ส่งไป destination เลย |
| Consumer | custom (KCL/Lambda ฯลฯ) | destination ที่กำหนด (S3/Redshift/OpenSearch...) |
| Scaling | shard / on-demand | auto, ไม่มี shard |
10Ordering และตารางเปรียบเทียบ SQS vs SNS vs Kinesis
เรื่อง ordering เป็นจุดตัดสินใจสำคัญ: SQS FIFO เรียงตาม message group, SNS FIFO เรียงตาม message group (ต้องคู่กับ SQS FIFO), และ Kinesis เรียงภายใน shard ตาม partition key ส่วน SQS Standard และ SNS Standard ไม่รับประกันลำดับ
| มุมมอง | SQS | SNS | Kinesis Data Streams |
|---|---|---|---|
| รูปแบบ | Queue (pull/consume แล้วลบ) | Pub/Sub (push, fan-out) | Streaming (อ่านซ้ำได้) |
| Consumers | หลายตัวแชร์ queue, message ถูก 1 consumer | หลาย subscribers ได้สำเนา | หลาย consumers อ่าน record ชุดเดียวกัน |
| Persistence | ลบหลัง consume | ไม่เก็บ (push ทันที) | เก็บตาม retention (24h-365d) |
| Ordering | FIFO เท่านั้น | FIFO เท่านั้น | ภายใน shard ตาม partition key |
| Use case | Decouple/buffer งาน async | Notify many / fan-out | Big data streaming/analytics/replay |
คำถามทบทวน
ทดสอบความเข้าใจหัวข้อ Integration & Messaging — SQS, SNS, Kinesis
23 ข้อ · เลือกคำตอบเพื่อดูเฉลยและคำอธิบาย
1.แอปพลิเคชันส่ง message ไปยัง SQS Standard queue ทีมพบว่าบาง message ถูกประมวลผลซ้ำสองครั้ง สาเหตุที่เป็นไปได้มากที่สุดคืออะไร?
2.Consumer ดึง message จาก SQS มาประมวลผลแต่ใช้เวลานานกว่า visibility timeout ที่ตั้งไว้ จะเกิดอะไรขึ้น?
3.ต้องการให้ consumer ลด empty responses และลดจำนวน API call เมื่อ poll SQS ควรใช้วิธีใด?
4.ระบบต้องการให้ order processing ทำตามลำดับที่ลูกค้าส่งเข้ามาอย่างเคร่งครัด และไม่มี message ซ้ำ ควรใช้บริการใด?
5.FIFO queue ใช้พารามิเตอร์ใดเพื่อรับประกันว่า message ภายในกลุ่มเดียวกันจะถูกประมวลผลตามลำดับและกระจายโหลดข้ามหลายกลุ่มได้?
6.ต้องส่ง message ขนาด 1 MB ผ่าน SQS ควรทำอย่างไรเนื่องจาก SQS มีข้อจำกัดขนาด message?
7.DLQ (Dead Letter Queue) ใน SQS ทำงานอย่างไร?
8.ต้องการให้ message ที่เพิ่งส่งเข้า SQS ยังไม่ถูก consumer มองเห็นเป็นเวลา 30 วินาที ควรใช้ฟีเจอร์ใด?
9.สถาปัตยกรรมต้องการให้ event หนึ่งถูกส่งไปประมวลผลโดยหลายระบบพร้อมกัน (fan-out) แต่ละระบบมี queue ของตัวเองและไม่สูญหาย ควรออกแบบอย่างไร?
10.ในการทำ SNS + SQS fan-out ข้าม account ต้องตั้งค่าอะไรเพื่อให้ SNS ส่ง message ลง SQS ได้?
11.ต้องการให้ subscriber แต่ละตัวรับเฉพาะ message บางประเภทจาก SNS topic เดียวกัน (เช่น order ที่ state = placed เท่านั้น) ควรใช้ฟีเจอร์ใด?
12.Kinesis Data Streams ใช้สิ่งใดในการกำหนดว่า record จะถูกส่งไปยัง shard ใด และรับประกัน ordering ภายใน shard?
13.แอปมี consumer หลายตัวอ่านจาก Kinesis Data Stream เดียวกันและต้องการ throughput อ่านสูง 2 MB/s ต่อ consumer ต่อ shard โดยไม่แย่ง throughput กัน ควรใช้อะไร?
14.Kinesis Data Streams ในโหมด provisioned แต่ละ shard มี write throughput สูงสุดเท่าใด?
15.ทีมไม่อยากบริหารจัดการจำนวน shard เองและโหลดคาดเดายาก ควรเลือก capacity mode ใดของ Kinesis Data Streams?
16.Kinesis Data Firehose มีลักษณะการส่งข้อมูลแบบใด และส่งไปที่ใดได้บ้าง?
17.ความแตกต่างหลักด้านการเก็บข้อมูลระหว่าง Kinesis Data Streams กับ SQS คืออะไร?
18.FIFO queue ตั้งค่า content-based deduplication ไว้ ถ้าส่ง message ที่มีเนื้อหาเหมือนกันสองครั้งภายใน 5 นาที จะเกิดอะไรขึ้น?
19.เลือกข้อที่ถูกต้องเกี่ยวกับ message retention ของ SQS
20.กำลังออกแบบ pipeline ที่ต้องการ ingest streaming data จำนวนมหาศาล, รองรับ multiple consumers อ่านข้อมูลชุดเดียวกันได้, และต้อง replay ข้อมูลย้อนหลังได้ ควรเลือกบริการใด?
21.KCL (Kinesis Client Library) ช่วยจัดการอะไรให้ consumer application?
22.ข้อใดอธิบาย SNS FIFO topic ได้ถูกต้อง?
23.Producer เขียนข้อมูลเข้า shard เดิมเร็วเกินไปจนเจอ ProvisionedThroughputExceededException แนวทางแก้ที่เหมาะสมที่สุดคือ?