Amalan Terbaik untuk Penggunaan semula Container AWS Lambda

Mengoptimumkan Permulaan Hangat Ketika Menghubungkan AWS Lambda ke Layanan Lain

AWS Lambda menyediakan skalabilitas yang tinggi kerana tidak mempunyai pelayan dan tidak mempunyai kerakyatan, yang membolehkan banyak salinan fungsi lambda dipancarkan dengan segera (seperti diterangkan di sini). Walau bagaimanapun, semasa menulis kod aplikasi, anda mungkin ingin mengakses beberapa data yang dikehendaki. Ini bermakna menyambung ke datastore seperti contoh RDS atau S3. Walau bagaimanapun, menyambung ke perkhidmatan lain dari AWS Lambda menambah masa ke kod fungsi anda. Mungkin juga ada kesan sampingan dari skalabilitas tinggi seperti mencapai bilangan maksimum sambungan yang dibenarkan kepada contoh RDS. Satu pilihan untuk mengatasi masalah ini adalah dengan menggunakan semula bekas dalam AWS Lambda untuk meneruskan sambungan dan mengurangkan waktu berjalan lambda.

Terdapat beberapa gambar rajah yang berguna di sini untuk menerangkan kitar hayat permintaan lambda.

Berikut ini berlaku semasa permulaan sejuk, apabila fungsi anda dipanggil untuk kali pertama atau selepas tempoh tidak aktif:

  • Kod dan ketergantungan dimuat turun.
  • Satu bekas baru dimulakan.
  • Runtime itu bootstrapped.

Tindakan terakhir adalah untuk memulakan kod anda, yang berlaku setiap kali fungsi lambda dipanggil. Sekiranya bekas digunakan semula untuk membuat panggilan lambda, kita boleh melangkaui kod awal. Ini dipanggil permulaan yang hangat, dan ini adalah langkah yang kita dapat mengoptimumkan apabila menyambung ke perkhidmatan lain dengan menentukan sambungan di luar skop kaedah pengendali.

Menyambung ke Perkhidmatan AWS Lain dari Lambda

Contoh: Sambungkan ke contoh RDS, ikon AWS bersumber dari sini

Kami mempunyai contoh asas dan biasa untuk dijalankan - kami mahu menyambung ke sumber bekas untuk mendapatkan data pengayaan. Dalam contoh ini, beban JSON masuk dengan ID dan fungsi Lambda menghubungkan kepada contoh RDS yang menjalankan PostgreSQL untuk mencari nama ID yang sepadan supaya kami dapat mengembalikan muatan diperkaya. Oleh kerana fungsi lambda menyambung kepada RDS, yang tinggal di VPC, fungsi lambda sekarang perlu hidup dalam subnet peribadi juga. Ini menambah beberapa langkah untuk permulaan yang sejuk - antaramuka rangkaian elastik VPC (ENI) perlu dilampirkan (seperti yang dinyatakan dalam blog Jeremy Daly, ini menambah masa untuk memulakan sejuk anda).

Nota: kami boleh mengelak daripada menggunakan VPC jika kami menggunakan storan kunci / nilai dengan DynamoDB dan bukannya RDS.

Saya akan mengetuai dua penyelesaian untuk tugas ini, yang pertama ialah penyelesaian 'naif' saya, sedangkan penyelesaian kedua mengoptimumkan untuk masa mula yang hangat dengan menggunakan semula sambungan untuk doa berikutnya. Kemudian kami akan membandingkan prestasi setiap penyelesaian.

Pilihan 1 - Sambungkan ke RDS Dalam Pengendali

Contoh kod ini menunjukkan bagaimana saya mungkin mendekati tugas ini - sambungan pangkalan data adalah dalam kaedah pengendali. Terdapat pertanyaan pilih mudah untuk mengambil nama ID sebelum mengembalikan muatan, yang kini termasuk nama.

Mari kita lihat bagaimana pilihan ini dilakukan semasa ujian kecil dengan letupan 2000 invocations dengan persimpangan 20. Tempoh minimum ialah 18 ms dengan purata 51ms dan hanya melebihi 1 kali maksimum (tempoh permulaan sejuk).

Tempoh Lambda

Grafik di bawah menunjukkan bahawa terdapat bilangan maksimum lapan sambungan ke pangkalan data.

Bilangan sambungan ke pangkalan data RDS dalam tetingkap 5 minit.

Pilihan 2 - Gunakan Sambungan Global

Pilihan kedua adalah untuk menentukan sambungan sebagai global di luar kaedah pengendali. Kemudian di dalam pegangnya, kami menambah cek untuk melihat apakah sambungan ada, dan hanya sambungkan jika tidak. Ini bermakna sambungan hanya dibuat sekali setiap bekas. Menetapkan sambungan dengan cara ini dengan keadaan bersyarat bermakna kita tidak perlu membuat sambungan jika tidak diperlukan oleh logik kod.

Kami tidak lagi menutup sambungan ke pangkalan data, jadi sambungan tetap untuk panggilan seterusnya. Penggunaan semula sambungan dengan ketara mengurangkan durasi permulaan yang panas - tempoh purata adalah kira-kira 3 kali lebih cepat dan minimum adalah 1 ms daripada 18 ms.

Lambda Durations

Menyambung ke contoh RDS adalah tugas yang memakan masa, dan tidak perlu menyambung untuk setiap penyerahan yang bermanfaat untuk prestasi. Apabila menyambung ke pangkalan data untuk pertanyaan pangkalan data mudah kita mencapai kiraan sambungan pangkalan data maksimum sebanyak 20, yang sepadan dengan tahap kesukaran (kami membuat 20 doa serentak x 100 kali). Apabila pecah letupan berhenti, sambungan secara perlahan-lahan ditutup.

Sekarang AWS telah meningkatkan elaun jangka masa lambda hingga 15 minit, ini bermakna sambungan pangkalan data boleh bertahan lebih lama dan anda mungkin berada dalam bahaya untuk mencapai nombor sambungan max RDS. Sambungan max lalai boleh ditimpa dalam tetapan kumpulan parameter RDS, walaupun meningkatkan bilangan sambungan maksimum boleh menyebabkan masalah dengan peruntukan memori. Contoh yang lebih kecil boleh mempunyai nilai max_connections lalai kurang daripada 100. Berhati-hati dengan had ini, dan hanya tambah logik aplikasi untuk menyambung ke pangkalan data apabila diperlukan.

Menggunakan Sambungan Global untuk Tugas Lain

Lambda Menyambung ke S3

Satu tugas biasa yang mungkin perlu kita lakukan dengan Lambda adalah untuk mengakses data dari S3. Coretan kod di bawah adalah AWS yang disediakan Pelan Tindakan Python Lambda - yang boleh anda navigasi dengan log masuk ke konsol AWS dan klik di sini. Anda dapat melihat dalam kod bahawa klien S3 sepenuhnya ditakrifkan di luar pengendali apabila kontena diasaskan, sedangkan untuk contoh RDS sambungan global telah ditetapkan di dalam pengendali. Kedua-dua pendekatan ini akan menetapkan pembolehubah global yang membolehkan mereka tersedia untuk membuat panggilan seterusnya.

kod snippet lambda s3-get-object snippet https://console.aws.amazon.com/lambda/home?region=us-east-1#/create/new?bp=s3-get-object-python

Pembolehubah Decrypting Environment

Konsol lambda memberikan anda pilihan menyulitkan pembolehubah persekitaran anda untuk keselamatan tambahan. Coretan kod berikut adalah AWS yang disediakan contoh Java skrip pembantu untuk menafsirkan pembolehubah persekitaran daripada fungsi Lambda. Anda boleh menavigasi ke coretan kod dengan mengikuti tutorial ini (khususnya langkah 6). Kerana DECRYPTED_KEY didefinisikan sebagai kelas global, fungsi decryptKey () dan logik hanya dipanggil sekali per lambda bekas. Oleh itu, kita akan melihat peningkatan yang signifikan dalam tempoh permulaan yang panas.

https://console.aws.amazon.com/lambda/home?region=us-east-1#/functions dan https://docs.aws.amazon.com/lambda/latest/dg/tutorial-env_console.html

Menggunakan Variabel Global dalam Penyelesaian Fauna Lain

Pendekatan ini tidak dipisahkan kepada AWS Lambda. Kaedah menggunakan sambungan global boleh digunakan untuk fungsi server tanpa pembekal awan yang lain juga. Halaman petua dan helah Fungsi Google Cloud memberi penjelasan yang baik untuk pembolehubah yang tidak malas (apabila pemboleh ubah sentiasa diasaskan di luar kaedah pengendali) berbanding pemboleh ubah malas (pembolehubah global hanya ditetapkan apabila diperlukan) pembolehubah global.

Amalan Terbaik Lain

Berikut adalah beberapa amalan terbaik lain yang perlu diingat.

Ujian

Menggunakan FaaS memudahkan penggunaan seni bina mikroservis. Dan mempunyai fungsi-fungsi kecil dan diskret yang tersendiri berjalan seiring dengan ujian unit yang berkesan. Untuk membantu ujian unit anda:

  • Ingat untuk tidak memasukkan dependensi ujian dari pakej lambda.
  • Logikan berasingan dari kaedah pengendali, seperti yang anda lakukan dengan kaedah utama program.

Ketergantungan dan Saiz Pakej

Mengurangkan saiz pakej penempatan bermakna memuat turun kod lebih cepat pada permulaan dan oleh itu akan meningkatkan masa mula sejuk anda. Keluarkan perpustakaan yang tidak digunakan dan kod mati untuk mengurangkan saiz fail ZIP. AWS SDK disediakan untuk runtime Python dan JavaScript jadi tidak perlu memasukkannya ke dalam pakej penempatan anda.

Jika Node.js adalah runtime Lambda pilihan anda, anda boleh memohon pengecilan dan uglification untuk mengurangkan saiz kod fungsi anda dan meminimumkan saiz pakej penggunaan anda. Beberapa tetapi tidak semua aspek minification dan uglification boleh digunakan untuk runtime lain, misalnya. anda tidak boleh mengalih keluar ruang kosong dari kod python tetapi anda boleh memadam komen dan memendekkan nama variabel.

Menetapkan Memori

Eksperimen untuk mencari jumlah ingatan optimum untuk Fungsi Lambda. Anda membayar peruntukan memori, jadi menggandakan memori bermakna anda perlu membayar dua kali ganda setiap milisaat; tetapi mengira meningkatkan kapasiti dengan memori yang diperuntukkan supaya ia berpotensi mengurangkan masa berjalan hingga kurang daripada separuh daripada apa yang berlaku. Terdapat beberapa alat yang berguna untuk memilih tetapan ingatan optimum untuk anda seperti ini.

Untuk menyimpulkan…

Satu perkara yang harus dipertimbangkan adalah sama ada menggunakan kaedah penggunaan semula sambungan diperlukan. Jika fungsi lambda anda hanya digunakan secara tidak sengaja, seperti sekali sehari, maka anda tidak akan mendapat manfaat daripada mengoptimumkan untuk permulaan panas. Seringkali terdapat pertukaran untuk mengoptimumkan prestasi berbanding kebolehbacaan kod anda - istilah "uglification" bercakap untuk dirinya sendiri! Di samping itu, menambahkan pemboleh ubah global ke kod anda untuk menggunakan semula sambungan ke perkhidmatan lain berpotensi membuat kod anda lebih sukar untuk dikesan. Dua soalan datang ke fikiran:

  • Adakah ahli pasukan baru memahami kod anda?
  • Adakah anda dan pasukan anda dapat debug kod pada masa akan datang?

Tetapi kemungkinan anda telah memilih Lambda untuk skala dan ingin prestasi tinggi dan kos rendah, jadi cari keseimbangan yang sesuai dengan keperluan pasukan anda.

Pendapat ini adalah pengarang. Kecuali jika dinyatakan sebaliknya dalam jawatan ini, Capital One tidak bergabung dengannya, ataupun ia disahkan oleh mana-mana syarikat yang disebutkan. Semua tanda dagangan dan harta intelektual lain yang digunakan atau dipaparkan adalah pemilikan pemilik masing-masing. Artikel ini adalah © 2019 Capital One.