← Semua pembelajaran / AWS untuk AI Engineer
Fase 1 · Serverless & Integrasi

Amazon SQS

SQS adalah cara paling sederhana membuat sistem tahan terhadap lonjakan dan kegagalan. Untuk beban kerja LLM, ia juga rem alami terhadap rate limit.

Intisari

  • Producer menaruh pesan, consumer mengambil. Keduanya tidak perlu hidup bersamaan.
  • Standard: throughput hampir tak terbatas, urutan tidak dijamin, bisa terkirim lebih dari sekali. FIFO: urut dan sekali-saja, dengan batas throughput.
  • Visibility timeout harus lebih besar dari waktu proses terlama — kalau tidak, pesan diproses ganda.
  • Dead-letter queue menampung pesan yang gagal berkali-kali. Pasang sejak awal, bukan setelah insiden.
  • Lambda + SQS: Lambda yang melakukan polling dan menghapus pesan otomatis kalau handler sukses.

Kenapa antrean, khususnya untuk LLM

Tiga masalah yang muncul begitu aplikasi GenAI-mu dipakai sungguhan, dan semuanya dijawab antrean:

MasalahBagaimana antrean menjawabnya
Ingest 5.000 dokumen > 15 menitSatu pesan per dokumen; tiap Lambda cukup mengurus satu
Bedrock membalas ThrottlingExceptionPesan kembali ke antrean dan dicoba lagi nanti, bukan hilang
Lonjakan trafik mendadakAntrean menyerapnya; consumer bekerja dengan laju yang kamu kendalikan

Standard vs FIFO

StandardFIFO
UrutanUsaha terbaikDijamin per message group
PengirimanMinimal sekali (bisa dobel)Tepat sekali
ThroughputPraktis tak terbatasTerbatas (lebih tinggi dengan batching)
Nama antreanBebasWajib berakhiran .fifo

"Minimal sekali" itu bukan teori. Pada antrean Standard, handler-mu akan menerima pesan yang sama dua kali suatu hari. Kalau handler itu memanggil Bedrock, kamu membayar token dua kali dan bisa menyimpan hasil ganda. Rancang idempoten: turunkan kunci dari messageId atau dari isi pesan, dan cek dulu sebelum bekerja.

Visibility timeout — sumber bug paling umum

Saat consumer mengambil pesan, pesan itu tidak dihapus; ia hanya disembunyikan selama visibility timeout. Kalau consumer selesai dan menghapusnya, tamat. Kalau tidak — pesan muncul lagi dan diproses ulang.

Ambil pesan ──▶ [tersembunyi selama N detik] ──▶ muncul lagi kalau belum dihapus
                         │
                         └─ handler selesai → pesan dihapus → selesai

Aturannya sederhana: visibility timeout > timeout fungsi consumer. Panduan umum untuk Lambda: setel sekitar enam kali timeout fungsi. Kalau terbalik, pemanggilan Bedrock yang lambat akan memicu duplikat — dan tampak seperti "bug acak yang cuma muncul saat ramai".

Menghubungkan ke Lambda

import json

def handler(event, context):
    for record in event["Records"]:          # bisa lebih dari satu pesan per pemanggilan
        pesan = json.loads(record["body"])
        proses(pesan)
    # Kalau handler selesai tanpa exception, seluruh batch dihapus dari antrean.
    # Kalau exception, SELURUH batch kembali — termasuk yang sudah sukses.

Komentar terakhir itu penting. Untuk menghindari mengulang pekerjaan yang sudah berhasil, aktifkan partial batch response: laporkan hanya ID yang gagal.

def handler(event, context):
    gagal = []
    for record in event["Records"]:
        try:
            proses(json.loads(record["body"]))
        except Exception:
            gagal.append({"itemIdentifier": record["messageId"]})
    return {"batchItemFailures": gagal}      # butuh ReportBatchItemFailures aktif

Dead-letter queue

Pesan yang gagal terus akan berputar selamanya dan membakar biaya. DLQ menghentikannya: setelah maxReceiveCount percobaan, pesan dipindahkan ke antrean terpisah untuk diperiksa manusia.

Pasang DLQ pada setiap antrean produksi, dan pasang alarm CloudWatch pada ApproximateNumberOfMessagesVisible di DLQ. Antrean DLQ yang tidak pernah dilihat sama saja dengan tidak punya DLQ.

Latihan: buat antrean ingest-dokumen dengan DLQ (maxReceiveCount 3), hubungkan ke Lambda yang sengaja melempar exception untuk pesan berisi {"gagal": true}. Kirim dua pesan — satu normal, satu gagal — lalu buktikan pesan gagal berakhir di DLQ setelah tiga percobaan sementara yang normal selesai.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.