Mengoptimalkan aplikasi Python untuk Cloud Run

Panduan ini menjelaskan pengoptimalan untuk layanan Cloud Run yang ditulis dalam bahasa pemrograman Python, beserta informasi latar belakang untuk membantu Anda memahami konsekuensi yang diperlukan dalam beberapa pengoptimalan. Informasi di halaman ini melengkapi tips pengoptimalan umum, yang juga berlaku untuk Python.

Banyak praktik terbaik dan pengoptimalan dalam aplikasi berbasis web Python tradisional ini berkisar pada:

  • Menangani permintaan serentak (baik I/O yang berbasis thread maupun yang tidak memblokir)
  • Mengurangi latensi respons menggunakan penggabungan koneksi dan mengelompokkan fungsi yang tidak penting. Misalnya, mengirim trace dan metrik ke tugas latar belakang.

Mengoptimalkan image container

Dengan mengoptimalkan image container, Anda dapat mengurangi waktu pemuatan dan startup. Anda dapat mengoptimalkan image dengan:

  • Hanya memasukkan hal yang diperlukan aplikasi Anda ke dalam container saat runtime
  • Mengoptimalkan server WSGI

Hanya masukkan hal yang diperlukan aplikasi Anda ke dalam container

Pertimbangkan komponen mana yang disertakan dalam container, dan apakah komponen tersebut diperlukan untuk eksekusi layanan. Ada beberapa cara untuk meminimalkan image container:

  • Gunakan image dasar yang lebih kecil
  • Memindahkan file besar ke luar penampung

Gunakan image dasar yang lebih kecil

Docker Hub menyediakan sejumlah image dasar Python resmi yang dapat Anda gunakan, jika Anda memilih untuk tidak menginstal Python dari sumber dalam container. Mereka didasarkan pada sistem operasi Debian.

Jika Anda menggunakan image python Docker Hub, pertimbangkan untuk menggunakan versi slim. Gambar ini berukuran lebih kecil karena tidak disertai dengan sejumlah paket yang akan digunakan untuk membuat roda, misalnya, yang mungkin tidak perlu Anda lakukan pada aplikasi Anda. Misalnya, image python dilengkapi dengan compiler GNU C, praprosesor, dan utilitas inti.

Untuk mengidentifikasi sepuluh paket terbesar dalam image dasar, Anda dapat menjalankan perintah berikut:

DOCKER_IMAGE=python # or python:slim
docker run --rm ${DOCKER_IMAGE} dpkg-query -Wf '${Installed-Size}\t${Package}\t${Description}\n' | sort -n | tail -n10 | column -t -s $'\t'

Karena jumlah paket level rendah lebih sedikit, gambar berbasis slim juga menawarkan lebih sedikit permukaan serangan untuk potensi kerentanan. Perhatikan, gambar ini mungkin tidak menyertakan elemen yang diperlukan untuk membuat roda dari sumber.

Anda dapat menambahkan kembali paket tertentu dengan menambahkan baris RUN apt install ke Dockerfile Anda. Lihat selengkapnya tentang cara menggunakan Paket Sistem di Cloud Run.

Ada juga opsi untuk container berbasis non-Debian. Opsi python:alpine dapat menghasilkan container yang jauh lebih kecil, tetapi banyak paket Python mungkin tidak memiliki roda yang telah dikompilasi sebelumnya dan mendukung sistem berbasis alpine. Dukungan meningkat (lihat PEP-656), tetapi terus bervariasi. Anda juga dapat mempertimbangkan penggunaan distroless base image, yang tidak berisi pengelola paket, shell, atau program lainnya.

Memindahkan file besar ke luar penampung

File besar, seperti aset media, dll., tidak perlu disertakan dalam penampung dasar.

Google Cloud menawarkan beberapa opsi hosting, seperti Cloud Storage, untuk menyimpan item berukuran besar ini. Pindahkan aset besar ke layanan ini, lalu rujuk aset tersebut dari aplikasi Anda pada waktu proses.

Mengoptimalkan server WSGI

Python telah menstandarkan cara aplikasi berinteraksi dengan server web melalui penerapan standar WSGI, PEP-3333. Salah satu server WSGI yang lebih umum adalah gunicorn, yang digunakan di banyak contoh dokumentasi.

Mengoptimalkan gunicorn

Tambahkan CMD berikut ke Dockerfile untuk mengoptimalkan pemanggilan gunicorn:

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

Jika Anda mempertimbangkan untuk mengubah setelan ini, sesuaikan jumlah pekerja dan thread per aplikasi. Misalnya, coba gunakan jumlah pekerja yang sama dengan core yang tersedia dan pastikan ada peningkatan performa, lalu sesuaikan jumlah thread. Menetapkan terlalu banyak pekerja atau thread dapat berdampak negatif, seperti latensi cold start yang lebih lama, memori yang lebih terpakai, permintaan yang lebih kecil per detik, dll.

Menambahkan setelan --preload dapat membantu untuk:

  • Mengidentifikasi bug runtime yang serius pada waktu deployment
  • Menyimpan resource memori

Anda harus mempertimbangkan pramuat aplikasi Anda sebelum menambahkan ini.

Server WSGI lainnya

Anda tidak dibatasi pada penggunaan gunicorn untuk menjalankan Python dalam container. Anda dapat menggunakan server web WSGI atau ASGI apa pun, selama container memproses port HTTP $PORT, sesuai dengan kontrak runtime Container.

Alternatif umum mencakup uwsgi, uvicorn, dan waitress.

Misalnya, pada file bernama main.py yang berisi objek app, pemanggilan berikut akan memulai server WSGI:

# uwsgi: pip install pyuwsgi
uwsgi --http :$PORT -s /tmp/app.sock --manage-script-name --mount /app=main:app

# uvicorn: pip install uvicorn
uvicorn --port $PORT --host 0.0.0.0 main:app

# waitress: pip install waitress
waitress-serve --port $PORT main:app

Ini dapat ditambahkan sebagai baris CMD exec di Dockerfile, atau sebagai entri web: di Procfile saat menggunakan buildpack Google Cloud.

Optimalkan aplikasi

Dalam kode layanan Cloud Run, Anda juga dapat mengoptimalkan waktu startup dan penggunaan memori yang lebih cepat.

Mengurangi thread

Anda dapat mengoptimalkan memori dengan mengurangi jumlah thread, yaitu dengan cara menggunakan strategi reaktif yang tidak memblokir dan menghindari aktivitas latar belakang. Selain itu, hindari penulisan ke sistem file, seperti yang disebutkan di halaman tips umum.

Jika Anda ingin mendukung aktivitas latar belakang dalam layanan Cloud Run, tetapkan CPU layanan Cloud Run ke selalu dialokasikan sehingga Anda dapat menjalankan aktivitas latar belakang di luar permintaan dan tetap memiliki akses CPU.

Mengurangi tugas startup

Aplikasi berbasis web Python dapat memiliki banyak tugas yang harus diselesaikan selama startup, misalnya, pramuat data, menyiapkan cache, membuat kumpulan koneksi, dll. Tugas-tugas ini, jika dijalankan secara berurutan, dapat berjalan lambat. Namun, jika ingin menjalankannya secara paralel, Anda harus meningkatkan jumlah core CPU.

Cloud Run saat ini mengirimkan permintaan pengguna sungguhan untuk memicu instance cold start. Pengguna yang memiliki permintaan yang ditetapkan ke instance yang baru dimulai mungkin akan mengalami penundaan yang lama. Cloud Run saat ini tidak memiliki pemeriksaan "kesiapan" untuk menghindari pengiriman permintaan ke aplikasi yang belum dibaca.

Langkah selanjutnya

Untuk tips lainnya, lihat