Mengurangi Penggunaan Memori Django. Buah gantung rendah?

137

Penggunaan memori saya meningkat seiring waktu dan memulai ulang Django bukanlah hal yang baik bagi pengguna.

Saya tidak yakin bagaimana cara membuat profil penggunaan memori tetapi beberapa tip tentang cara memulai pengukuran akan berguna.

Saya merasa ada beberapa langkah sederhana yang bisa menghasilkan keuntungan besar. Memastikan 'debug' disetel ke 'False' adalah masalah besar yang jelas.

Adakah yang bisa menyarankan orang lain? Seberapa besar peningkatan yang dapat dilakukan caching di situs dengan lalu lintas rendah?

Dalam hal ini saya menggunakan Apache 2.x dengan mod_python. Saya pernah mendengar mod_wsgi sedikit lebih ramping tetapi akan sulit untuk beralih pada tahap ini kecuali saya tahu keuntungannya akan signifikan.

Edit: Terima kasih atas tipnya sejauh ini. Ada saran bagaimana menemukan apa yang menggunakan memori? Apakah ada panduan untuk profil memori Python?

Juga seperti yang disebutkan, ada beberapa hal yang akan membuat sulit untuk beralih ke mod_wsgi, jadi saya ingin mengetahui beberapa keuntungan yang bisa saya harapkan sebelum melangkah maju ke arah itu.

Sunting: Carl mem-posting balasan yang sedikit lebih rinci di sini yang layak dibaca: Penyebaran Django: Pemotongan Overhead Apache

Sunting: Artikel Graham Dumpleton adalah yang terbaik yang pernah saya temukan di MPM dan hal-hal terkait mod_wsgi. Saya agak kecewa karena tidak ada yang bisa memberikan info tentang debugging penggunaan memori di aplikasi itu sendiri.

Sunting Terakhir: Saya telah mendiskusikan ini dengan Webfaction untuk melihat apakah mereka dapat membantu dengan mengkompilasi ulang Apache dan ini adalah kata-kata mereka tentang masalah ini:

"Saya benar-benar tidak berpikir bahwa Anda akan mendapatkan banyak manfaat dengan beralih ke penyiapan MPM Worker + mod_wsgi. Saya memperkirakan bahwa Anda mungkin dapat menghemat sekitar 20MB, tetapi mungkin tidak lebih dari itu."

Begitu! Ini membawa saya kembali ke pertanyaan awal saya (yang masih belum saya ketahui). Bagaimana cara seseorang mengidentifikasi di mana letak masalahnya? Ini adalah pepatah terkenal bahwa Anda tidak mengoptimalkan tanpa pengujian untuk melihat di mana Anda perlu mengoptimalkan tetapi ada sangat sedikit tutorial tentang mengukur penggunaan memori Python dan tidak ada sama sekali yang khusus untuk Django.

Terima kasih atas bantuan semua orang tetapi saya pikir pertanyaan ini masih terbuka!

Pengeditan terakhir lainnya ;-)

Saya menanyakan hal ini pada daftar pengguna-django dan mendapat beberapa jawaban yang sangat membantu

Sejujurnya pembaruan terakhir yang pernah ada!

Ini baru saja dirilis. Mungkin merupakan solusi terbaik: Membuat profil ukuran objek Django dan penggunaan memori dengan Pympler

Andy Baker
sumber

Jawaban:

50

Pastikan Anda tidak menyimpan referensi global ke data. Itu mencegah pengumpul sampah python melepaskan memori.

Jangan gunakan mod_python. Ini memuat penerjemah di dalam apache. Jika Anda perlu menggunakan apache, gunakan mod_wsgisebagai gantinya. Tidaklah sulit untuk beralih. Ini sangat mudah. mod_wsgiadalah cara yang lebih mudah untuk dikonfigurasi untuk Django daripada mati otak mod_python.

Jika Anda dapat menghapus apache dari kebutuhan Anda, itu akan lebih baik untuk memori Anda. spawningtampaknya menjadi cara cepat baru yang dapat diskalakan untuk menjalankan aplikasi web python.

EDIT : Saya tidak melihat bagaimana beralih ke mod_wsgi bisa " rumit ". Ini seharusnya menjadi tugas yang sangat mudah. Harap jelaskan masalah yang Anda alami dengan sakelar.

nosklo.dll
sumber
4
@Josh: pembengkakan apache dan penggunaan memori itu bodoh jika Anda tidak menggunakan fitur khusus apache. Itu hanya lapisan yang tidak perlu.
nosklo
3
Django masih mendukung mod_python karena mod_wsgi masih cukup baru, dan mereka ingin konservatif. Tetapi jika Anda mengikuti komunitas Django Anda akan melihat orang-orang berpindah ke mod_wsgi secara massal. Tidak perlu waktu lama sebelum itu menjadi opsi yang disarankan.
Carl Meyer
1
@Tiago: apache bagus bila Anda memiliki banyak host virtual apache yang sudah ada, menggunakan SSL dengan apache, dll. Dalam hal ini, gunakan mod_wsgi. Jika Anda memulai dari awal, gunakan pemijahan. JANGAN PERNAH menggunakan mod_python.
nosklo
1
Terima kasih, nosklo. Saya sedang melihat pemijahan .. tampaknya memiliki sedikit atau tidak ada dokumentasi .. Saya akan mencoba mengikuti beberapa petunjuk yang saya temukan di posting blog dan melihat di mana saya bisa mendapatkannya.
Tiago
1
Hmm, sebagai seseorang yang baru mulai menggunakan Django, saya akan mengingat bahwa saya harus menggunakan mod_wsgi.
Powerlord
28

Jika Anda menjalankan mod_wsgi, dan mungkin muncul karena kompatibel dengan WSGI, Anda dapat menggunakan Dozer untuk melihat penggunaan memori Anda.

Di bawah mod_wsgi tambahkan saja ini di bagian bawah skrip WSGI Anda:

from dozer import Dozer
application = Dozer(application)

Kemudian arahkan browser Anda ke http: // domain / _dozer / index untuk melihat daftar semua alokasi memori Anda.

Saya juga hanya akan menambahkan suara dukungan saya untuk mod_wsgi. Itu membuat perbedaan dunia dalam hal kinerja dan penggunaan memori melalui mod_python. Dukungan Graham Dumpleton untuk mod_wsgi luar biasa, baik dalam hal pengembangan aktif maupun dalam membantu orang-orang di milis untuk mengoptimalkan penginstalan mereka. David Cramer di curse.com telah memposting beberapa grafik (yang sayangnya tidak dapat saya temukan sekarang) yang menunjukkan pengurangan drastis dalam penggunaan cpu dan memori setelah mereka beralih ke mod_wsgi di situs dengan lalu lintas tinggi itu. Beberapa dari django dev telah berpindah. Serius, ini no-brainer :)

Van Gale
sumber
Dalam hal ini saya akan segera memposting pertanyaan yang menanyakan bagaimana seseorang mendapatkan otentikasi berbasis cookie untuk pengguna django yang mengakses file statis ...
Andy Baker
15

Ini adalah solusi profiler memori Python yang saya ketahui (tidak terkait dengan Django):

Penafian: Saya memiliki andil dalam yang terakhir.

Dokumentasi proyek individu akan memberi Anda gambaran tentang bagaimana menggunakan alat-alat ini untuk menganalisis perilaku memori dari aplikasi Python.

Berikut ini adalah "kisah perang" bagus yang juga memberikan beberapa petunjuk berguna:

Pankrat
sumber
5

Selain itu, periksa apakah Anda tidak menggunakan salah satu leaker yang diketahui. MySQLdb diketahui membocorkan sejumlah besar memori dengan Django karena bug dalam penanganan unicode. Selain itu, Django Debug Toolbar mungkin membantu Anda melacak babi.

zgoda.dll
sumber
amix.dk/blog/viewEntry/19420 menunjukkan dozer digunakan untuk menunjukkan bahwa MySQLdb membocorkan memori. MySQLdb 1.2.3c1 dan yang lebih baru memperbaiki ini.
msanders
Bagaimana bisa django-debug-toolbarmembantu?
Wtower
4

Selain tidak menyimpan referensi global ke objek data besar, cobalah untuk menghindari memuat set data besar ke dalam memori sama sekali jika memungkinkan.

Beralih ke mod_wsgi dalam mode daemon, dan gunakan mpm pekerja Apache sebagai ganti prefork. Langkah terakhir ini memungkinkan Anda melayani lebih banyak pengguna secara bersamaan dengan lebih sedikit overhead memori.

Carl Meyer
sumber
Juga lihat jawaban Carl di sini: stackoverflow.com/questions/488864/…
Andy Baker
Juga - dalam beberapa posting yang saya baca, tampaknya keuntungan sebenarnya adalah beralih ke MPM pekerja daripada menggunakan mod_wsgi ...
Andy Baker
4

Webfaction sebenarnya memiliki beberapa tip untuk menjaga penggunaan memori django tetap rendah.

Poin utama:

  • Pastikan debug disetel ke false (Anda sudah tahu itu).
  • Gunakan "ServerLimit" di konfigurasi apache Anda
  • Pastikan tidak ada objek besar yang dimuat ke dalam memori
  • Pertimbangkan untuk menyajikan konten statis dalam proses atau server terpisah.
  • Gunakan "MaxRequestsPerChild" di konfigurasi apache Anda
  • Cari tahu dan pahami berapa banyak memori yang Anda gunakan
Jason Baker
sumber
2
Terima kasih, saya sudah membacanya. Ini nomor 3 dan 6 Saya berharap untuk sedikit lebih detail! ;-)
Andy Baker
3

Kelebihan lainnya untuk mod_wsgi: setel maximum-requestsparameter dalam WSGIDaemonProcessdirektif Anda dan mod_wsgi akan sering mengulang proses daemon. Seharusnya tidak ada efek yang terlihat untuk pengguna, selain dari pemuatan halaman yang lambat saat pertama kali proses baru dilakukan, karena itu akan memuat Django dan kode aplikasi Anda ke dalam memori.

Tetapi bahkan jika Anda lakukan memiliki kebocoran memori, yang harus menjaga ukuran proses dari mendapatkan terlalu besar, tanpa harus mengganggu layanan kepada pengguna Anda.

AdamKG
sumber
1
Hal serupa disebutkan di sini: mail-archive.com/[email protected]/msg84698.html hanya mereka menggunakan waktu-waktu-habis alih-alih permintaan-maksimum.
Tomas Andrle
3

Berikut ini skrip yang saya gunakan untuk mod_wsgi (disebut wsgi.py, dan dimasukkan ke dalam root dari proyek django saya):

import os
import sys
import django.core.handlers.wsgi

from os import path

sys.stdout = open('/dev/null', 'a+')
sys.stderr = open('/dev/null', 'a+')

sys.path.append(path.join(path.dirname(__file__), '..'))

os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
application = django.core.handlers.wsgi.WSGIHandler()

Sesuaikan myproject.settings dan jalur sesuai kebutuhan. Saya mengarahkan semua output ke / dev / null karena mod_wsgi secara default mencegah pencetakan. Gunakan logging sebagai gantinya.

Untuk apache:

<VirtualHost *>
   ServerName myhost.com

   ErrorLog /var/log/apache2/error-myhost.log
   CustomLog /var/log/apache2/access-myhost.log common

   DocumentRoot "/var/www"

   WSGIScriptAlias / /path/to/my/wsgi.py

</VirtualHost>

Mudah-mudahan ini setidaknya membantu Anda mengatur mod_wsgi sehingga Anda dapat melihat apakah ada perbedaan.

Staale
sumber
1

Cache: pastikan mereka sedang dibilas. Mudah bagi sesuatu untuk dimasukkan ke dalam cache, tetapi tidak pernah di-GC karena referensi cache.

Kode Swig'd: Pastikan semua manajemen memori dilakukan dengan benar, sangat mudah untuk melewatkan ini di python, terutama dengan perpustakaan pihak ketiga

Pemantauan: Jika bisa, dapatkan data tentang penggunaan memori dan klik. Biasanya Anda akan melihat korelasi antara jenis permintaan tertentu dan penggunaan memori.

Richard Levasseur
sumber
1

Kami menemukan bug di Django dengan peta situs besar (10.000 item). Sepertinya Django sedang mencoba untuk memuat semuanya dalam memori saat membuat peta situs: http://code.djangoproject.com/ticket/11572 - secara efektif mematikan proses apache ketika Google mengunjungi situs tersebut.

Emil Stenström
sumber