Menjadualkan Pelbagai Program dalam Satu Klik โ Mengatasi Had 15 Minit AWS Lambda
Pengendali saluran FAST menjadualkan program sebulan dan menekan Deploy sekali. Di sebalik satu klik itu, beratus-ratus program menjadi ribuan tindakan jadual MediaLive yang perlu sampai ke AWS secara berurutan, semuanya dalam had pelaksanaan lima belas minit Lambda โ dan sebarang kegagalan di tengah-tengah akan meninggalkan saluran langsung dengan kekosongan. Berikut adalah cara kami menjadikan deployment satu klik bagi senarai main yang besar boleh dipercayai, dan mengapa langkah seterusnya adalah runtime yang berbeza, bukan Lambda yang lebih besar.
Gambaran keseluruhan ringkas
| Aspek | Butiran |
|---|---|
| Runtime | AWS Lambda (single invocation), 615s backend timeout |
| Sasaran output | MediaLive BatchUpdateScheduleCommand |
| Batching | Sehingga 200 tindakan MediaLive setiap permintaan โ ~25 program dalam praktikal |
| Tindakan setiap program | ~7โ8 (input switch + 4 watermark setiap rendition + 2 SCTE-35), lebih banyak dengan selingan iklan |
| Fallback | Percubaan semula setiap program jika terdapat penolakan batch |
| Diperhatikan | 195 program di-deploy dalam ~44 saat (ukuran tempatan) |
| Sasaran yang didokumentasikan | 360 program dalam โค90 saat |
| Laluan Scale-out | Step Functions chunking untuk senarai main >1 bulan โ dirancang, belum dihantar |
Cabaran
Deployment senarai main bukan proses menulis โ ia adalah orkestrasi. Untuk setiap program yang dijadualkan oleh pengendali, MediaLive perlu tahu dengan tepat bila untuk menukar input, bila untuk menghidupkan watermark untuk setiap rendition, bila untuk memasukkan titik isyarat SCTE-35, dan bila untuk menyelitkan iklan. Tekanan struktur adalah:
- Jumlah tindakan adalah berganda, bukan tambahan. Setiap program mengeluarkan ~7โ8 tindakan sebelum selingan iklan โ satu input switch, empat pengaktifan watermark (satu setiap rendition kerana StaticImageOutputActivate menggunakan koordinat output-pixel), dan dua penanda SCTE-35. Selingan iklan menambah tiga tindakan lagi setiap satu. Satu bulan dengan 360 program adalah kira-kira 2,800 tindakan pada wayar.
- MediaLive menguatkuasakan urutan setiap saluran. Tindakan jadual adalah berjangka masa dan merujuk antara satu sama lain; anda tidak boleh melakukan penulisan secara selari ke saluran yang sama tanpa API menolaknya sebagai konflik.
- AWS Lambda mempunyai had keras 15 minit. Bukan had lembut, bukan konfigurasi. Orkestrator mesti selesai dalam tempoh itu atau saluran akan berakhir dalam keadaan separuh deploy.
- Kegagalan separa tidak boleh diterima secara operasi. Jika program 174 dari 360 gagal dan membatalkan pelaksanaan, pengendali tidak mempunyai pandangan diff tentang apa yang berjaya dan apa yang tidak. Saluran akan disiarkan dengan kekosongan; penonton melihat slate di mana mereka menjangkakan kandungan.
- Versi pertama menghantar satu BatchUpdateSchedule setiap program dengan selang 200ms antara program. Itu adalah ~2.5 saat waktu sebenar setiap program. Pada 360 program, anda sudah melepasi had Lambda sebelum MediaLive melakukan sebarang kerja sebenar.
Maka, tugasnya bukan untuk menulis dengan lebih pantas. Ia adalah untuk menulis lebih sedikit kali, bertahan dari kegagalan separa, dan kekal dalam satu invocation โ tanpa kehilangan jaminan urutan yang dituntut oleh MediaLive.
Mengapa Pendekatan Sedia Ada Gagal
Penyelesaian yang jelas semuanya gagal atas sebab-sebab yang bersifat struktur, bukan masalah penyesuaian.
- "Hanya tingkatkan timeout Lambda." Tidak boleh. Lima belas minit adalah had keras yang dikenakan oleh AWS untuk pelaksanaan Lambda; ia bukan kawalan dalam konsol. Walaupun ia boleh, kos setiap program meningkat dengan katalog โ membeli lebih banyak wall time hanya menangguhkan had seterusnya.
- "Beralih ke ECS Fargate atau EC2." Kami mempertimbangkannya dan menolaknya. Container yang berjalan lama bermakna kami memiliki runtime: pemeriksaan kesihatan, autoscaling, pertimbangan cold-start vs. warm-pool, skop IAM, dan giliran on-call untuk perkhidmatan yang berjalan secara berlonjakan. Lambda memberikan kami pengasingan setiap invocation dan kos terbiar sifar untuk beban kerja yang sememangnya bersifat lonjakan. Kami tidak bersedia melepaskan itu untuk membetulkan satu kesesakan.
- "Selarikan penulisan MediaLive." MediaLive menyiriakan kemas kini jadual setiap saluran. Panggilan BatchUpdateSchedule yang serentak terhadap saluran yang sama bersaing pada garis masa tindakan dan ditolak. Satu-satunya parallelism yang sah adalah dalam satu batch, bukan merentasi batch.
- "Biarkan ia ranap dan biarkan pengendali cuba semula." Ini adalah pilihan terburuk. Apabila deployment tergendala pada program N, saluran berada dalam keadaan yang tidak dapat dijelaskan oleh sesiapa dari UI. Pengendali tidak mendapat diff; mereka mendapat kotak hitam dan saluran langsung dengan kekosongan. Sistem sama ada perlu mendaratkan semuanya atau mendaratkan hasil separa dengan status setiap program yang boleh diambil tindakan oleh pengendali.
Lever yang kami ada hanyalah bentuk kerja itu sendiri: penulisan yang lebih sedikit, lebih besar, dilaksanakan secara bersiri, dengan fallback yang merosot kepada granulariti tahap baris hanya apabila batch ditolak.
Penyelesaian Kami
Alihkan kos keluar dari Lambda sebelum gelung bermula, gabungkan penulisan MediaLive di dalam gelung, dan turunkan kepada penyerahan setiap program hanya apabila batch gagal. Tiga idea, dalam susunan itu โ dan keputusan yang disengajakan bahawa had 15 minit adalah baik untuk saiz katalog yang sebenarnya kami deploy hari ini. Apabila senarai main melebihi satu invocation, jawapannya bukan Lambda yang lebih besar; ia adalah runtime yang berbeza.

Seni Bina
- Backend NestJS (schedule.service.ts) โ pre-warms deployment: satu perjalanan ulang-alik Mongo untuk semua video unik, satu untuk semua penanda iklan, kemudian ffprobe selari merentasi URL video unik dengan hasil cache untuk gelung pengayaan.
- Orkestrator Lambda (fastChannel-lambda-fun/index.js) โ mengendalikan gelung batching, throttle setiap batch, fallback setiap program, dan pembersihan yatim.
- MediaLive BatchUpdateScheduleCommand โ satu-satunya permukaan tulis. Setiap tindakan โ input switch, watermark, SCTE-35, ad splice โ mengalir melaluinya.
- MongoDB โ sumber kebenaran untuk program, video, dan penanda iklan; tidak pernah ditanya di dalam gelung dalaman.
- scheduleResults map โ status scheduled / error setiap program dikembalikan ke backend supaya pengendali mendapat diff, bukan stack trace.
Keputusan Kejuruteraan Utama
1. Panaskan awal perkara yang perlahan sebelum gelung berjalan. Kod asal melakukan carian Mongo setiap jadual dan panggilan ffprobe setiap jadual di dalam gelung pengayaan โ N+1 klasik yang dibayar dua kali. Backend semasa melakukan bulk-fetch setiap video unik dan penanda iklan dalam satu perjalanan ulang-alik setiap satu, kemudian menjalankan ffprobe secara selari merentasi URL unik dan menyimpan hasilnya dalam cache resolusi. Gelung dalaman menjadi cache hit. Latency ffprobe dibayar sekali setiap URL unik, bukan secara bersiri dalam gelung.
2. Gabungkan penulisan MediaLive ke dalam batch ~25. Di dalam orkestrator, tindakan terkumpul menjadi satu BatchUpdateScheduleCommand sehingga 200 tindakan beratur atau program terakhir dicapai. Memandangkan setiap program menghasilkan ~7โ8 tindakan, batch secara semula jadi mengandungi sekitar 25 program setiap satu. Had 200 tindakan dipilih secara konservatif untuk kekal jauh di bawah had payload setiap permintaan MediaLive dan mengurangkan peluang batch ditolak kerana saiznya โ cukup besar untuk mengamortisasi kos rangkaian, cukup kecil untuk menjadikan fallback setiap program (keputusan seterusnya) murah apabila ia perlu dijalankan. Satu perjalanan ulang-alik rangkaian menggantikan dua puluh lima. Throttle 200ms yang sebelum ini berada di antara setiap program kini berada di antara setiap batch.
3. Batching untuk kelajuan, fallback untuk ketepatan. Menggabungkan hanya selamat jika satu program yang buruk tidak merosakkan dua puluh empat yang lain dalam batchnya. Apabila submitProgramBatch mengeluarkan ralat, catch akan memanggil retryBatchAsIndividuals, yang menghantar semula setiap program dalam batch yang gagal sebagai BatchUpdateScheduleCommand tersendiri, merekodkan status: 'scheduled' atau status: 'error' setiap program, berehat 200ms antara percubaan, dan menetapkan semula garis masa tindakan selepas setiap kejayaan separa. Laluan pantas adalah dibatch. Laluan pemulihan adalah granular. Pengendali mendapat diff setiap program dalam apa jua keadaan.
4. Sapu yatim piatu pada akhir, jangan halang mereka di tengah-tengah perjalanan. sweepIncompleteProgramGroups berjalan sekali pada akhir deployment dan membuang mana-mana kumpulan tindakan yang tidak mencapai keadaan terminal bersih. Kami sengaja tidak cuba mengekalkan saluran konsisten secara dalaman semasa gelung โ itu akan bermakna laluan rollback yang sendiri perlu muat dalam bajet 15 minit. Pembersihan adalah satu sapuan, bukan transaksi.
5. Jangan kembangkan Lambda; gantikannya apabila katalog berkembang. Untuk semua yang kami deploy hari ini, laluan single-invocation selesai dengan baik dalam bajet. Scale-out yang jujur adalah Step Functions chunking โ bahagikan senarai main, jalankan chunk sebagai mesin keadaan selari, pasang semula. Itu adalah laluan untuk senarai main >1 bulan dan 6 bulan. Ia direka, bukan deploy. Menggelarnya langkah seterusnya lebih berguna daripada berpura-pura ia sudah berjalan.
Keputusan
- Dalam ujian dalaman, deployment 195 program selesai dalam ~44 saat โ menurun dari baseline berbilang minit, satu program pada satu masa.
- Sasaran yang didokumentasikan untuk senarai main 360 program (~1 bulan) adalah โค90 saat, selesa di dalam timeout backend 615 saat dan had Lambda 15 minit.
- Satu program yang buruk dalam satu batch tidak lagi membatalkan 24 program yang lain. Pengendali mendapat peta status setiap program dari setiap deployment.
- Bahagian perlahan permintaan โ carian Mongo dan ffprobe โ dibayar sekali setiap sumber unik, bukan sekali setiap entri jadual.
- Had 15 minit berhenti menjadi faktor pembatas untuk saiz katalog yang sebenarnya kami hantar. Apabila ia menjadi satu lagi, Step Functions chunking adalah jawapannya, bukan Lambda yang lebih besar.
Tindanan Teknologi: AWS Lambda ยท AWS MediaLive ยท NestJS ยท MongoDB ยท Node 18 ยท ffprobe ยท TypeScript ยท AWS SDK v3

