Django Bellek Kullanımının Azaltılması. Düşük asılı meyve?


136

Bellek kullanımım zamanla artıyor ve Django'yu yeniden başlatmak kullanıcılar için iyi değil.

Bellek kullanımını profillemeye nasıl devam edeceğimden emin değilim ancak ölçüme nasıl başlayacağınıza dair bazı ipuçları yararlı olacaktır.

Büyük kazançlar elde edebilecek bazı basit adımlar olduğunu hissediyorum. 'Hata ayıklama'nın' Yanlış 'olarak ayarlandığından emin olunması bariz bir biggie.

Herkes başkalarına önerebilir mi? Düşük trafik alan sitelerde önbelleğe alma ne kadar gelişme gösterir?

Bu durumda Apache 2.x altında mod_python ile çalışıyorum. Mod_wsgi'nin biraz daha yalın olduğunu duydum ama kazançların önemli olacağını bilmedikçe bu aşamada geçiş yapmak zor olurdu.

Edit: Şimdiye kadarki ipuçları için teşekkürler. Hafızayı neyin kullandığını nasıl öneriyorsunuz? Python bellek profili oluşturmaya yönelik kılavuzlar var mı?

Ayrıca belirtildiği gibi mod_wsgi'ye geçmeyi zorlaştıracak birkaç şey var, bu yüzden bu yönde ileriye doğru çiftçilik yapmadan önce beklediğim kazanımlar hakkında biraz fikir sahibi olmak istiyorum.

Edit: Carl burada okumaya değer biraz daha ayrıntılı bir cevap gönderdi: Django Dağıtım: Apache'nin Tepegöz Kesme

Edit: Graham Dumpleton'ın makalesi MPM ve mod_wsgi ile ilgili şeyler bulduğum en iyisidir. Kimsenin uygulamanın bellek kullanımında hata ayıklama konusunda herhangi bir bilgi sağlayamayacağından hayal kırıklığına uğradım.

Son Düzenleme: Peki, Webache ile bunu Apache'nin derlenmesine yardımcı olup olamayacağını görmek için tartışıyordum ve bu konudaki sözleri:

"Bir MPM İşçi + mod_wsgi kurulumuna geçerek çok fazla fayda sağlayacağınızı gerçekten sanmıyorum. 20 MB civarında tasarruf sağlayabileceğinizi tahmin ediyorum, ancak muhtemelen bundan daha fazlasını değil."

Yani! Bu beni orijinal soruma geri getiriyor (ki hala hiçbir şey akıllı değilim). Sorunların nerede yattığını belirlemeye nasıl başlanır? Nerede optimize etmeniz gerektiğini görmek için test yapmadan optimize etmediğiniz iyi bilinen bir maksimdir, ancak Python bellek kullanımını ölçme konusunda çok az öğretici ve Django'ya özgü hiçbir şey yoktur.

Herkesin yardımları için teşekkürler ama bence bu soru hala açık!

Başka bir son düzenleme ;-)

Bunu django kullanıcıları listesinde sordum ve çok yararlı cevaplar aldım

Dürüst olmak gerekirse son güncelleme!

Bu yeni çıktı. Şimdiye kadarki en iyi çözüm olabilir: Pympler ile Django nesne boyutunu ve bellek kullanımını belirleme

Yanıtlar:


50

Verilere genel referanslar almadığınızdan emin olun. Bu, python çöp toplayıcısının belleği serbest bırakmasını önler.

Kullanma mod_python. Apache'nin içine bir tercüman yükler. Apache kullanmanız gerekiyorsa mod_wsgibunun yerine kullanın. Geçiş yapmak zor değil. Bu çok kolay. djangomod_wsgi için yapılandırılması beyin ölülerinden çok daha kolaydır mod_python.

Apache'yi gereksinimlerinizden kaldırabiliyorsanız, bu bellek için daha iyi olacaktır. spawningpython web uygulamalarını çalıştırmanın yeni hızlı ölçeklenebilir yolu gibi görünüyor.

EDIT : mod_wsgi geçiş nasıl zor olabilir görmüyorum . Çok kolay bir iş olmalı. Lütfen anahtarla ilgili yaşadığınız sorunu ayrıntılarıyla açıklayın.


4
@Josh: Yalnızca apache özelliklerini kullanmıyorsanız apache'nin şişkinliği ve bellek kullanımı aptalca. Bu sadece gereksiz bir katman.
nosklo

3
Django hala mod_python'u destekliyor çünkü mod_wsgi hala oldukça yeni ve muhafazakar olmak istiyorlar. Ancak Django topluluğunu takip ederseniz insanların mod_wsgi en masse'ye geçtiklerini göreceksiniz. Önerilen seçenek olması uzun sürmez.
Carl Meyer

1
@Tiago: Zaten apache ile SSL kullanan çok sayıda apache sanal barındırıcınız varsa apache iyidir. Bu durumda mod_wsgi kullanın. Yeniden başlıyorsanız yumurtlama kullanın. ASLA mod_python kullanmayın.
nosklo

1
Teşekkürler, nosklo. Ben yumurtlama bir göz alıyorum .. hiçbiri belgelere çok az gibi görünüyor .. Ben blog yazılarında buldum bazı talimatları izlemeye çalışacağım ve nerede alabilirim bakın.
Tiago

1
Hmm, birisi Django kullanmaya yeni başladığı için mod_wsgi kullanmam gerektiğini aklımda tutacağım.
Powerlord

28

Mod_wsgi altında çalışıyorsanız ve WSGI uyumlu olduğu için muhtemelen yumurtlama yapıyorsanız, bellek kullanımınıza bakmak için Dozer'ı kullanabilirsiniz .

Mod_wsgi altında bunu WSGI betiğinizin altına ekleyin:

from dozer import Dozer
application = Dozer(application)

Ardından , tüm bellek ayırmalarınızın bir listesini görmek için tarayıcınızı http: // domain / _dozer / index adresine yönlendirin.

Ayrıca mod_wsgi için destek sesimi de ekleyeceğim. Mod_python'a göre performans ve bellek kullanımı açısından fark yaratır. Graham Dumpleton'ın mod_wsgi desteği hem aktif geliştirme hem de posta listesindeki kişilerin kurulumlarını optimize etmelerine yardımcı olma konusunda olağanüstü. Curse.com'dan David Cramer, bu yüksek trafik sitesinde mod_wsgi'ye geçtikten sonra cpu ve bellek kullanımındaki önemli azalmayı gösteren bazı grafikler yayınladı (ki şimdi ne yazık ki bulamıyorum). Django geliştiricilerinin birçoğu değişti. Cidden, bu bir beyinsiz :)


Bu durumda yakında bir kişinin statik dosyalara erişen django kullanıcıları için çerez tabanlı kimlik doğrulamasını nasıl alacağını soran bir soru yayınlayacağım ...
Andy Baker

15

Bunlar farkında olduğum Python bellek profili oluşturma çözümleri (Django ile ilgili değil):

Feragatname: İkincisinde bir hissem var.

Bireysel projenin belgeleri size Python uygulamalarının bellek davranışını analiz etmek için bu araçları nasıl kullanacağınız hakkında bir fikir vermelidir.

Aşağıda bazı yararlı işaretler veren hoş bir "savaş hikayesi" yer almaktadır:


5

Ayrıca, bilinen sızıntıları kullanmadığınızı kontrol edin. MySQLdb'nin unicode kullanımındaki hata nedeniyle Django ile çok büyük miktarda bellek sızdırdığı bilinmektedir. Bunun dışında, Django Hata Ayıklama Araç Çubuğu domuzları izlemenize yardımcı olabilir.


amix.dk/blog/viewEntry/19420 , dozer'in MySQLdb'nin bellek sızdırdığını göstermek için kullanıldığını gösterir. MySQLdb 1.2.3c1 ve sonraki sürümleri bunu düzeltir.
msanders

Nasıl django-debug-toolbaryardımcı olabilirim ?
Wtower

4

Büyük veri nesnelerine genel referanslar bulundurmamanın yanı sıra, mümkün olan her yerde büyük veri kümelerini belleğe yüklemekten kaçının.

Arka plan modunda mod_wsgi'ye geçin ve önbellek yerine Apache'nin işçi mpm'sini kullanın. Bu ikinci adım, daha az bellek ek yükü ile daha fazla eşzamanlı kullanıcıya hizmet vermenizi sağlayabilir.


Ayrıca Carl'ın cevabına da bakınız: stackoverflow.com/questions/488864/…
Andy Baker

Ayrıca - birkaç mesajda okudum gerçek kazanç mod_wsgi kullanmak yerine işçi MPM geçiş olduğunu görünüyor ...
Andy Baker

4

Webfaction aslında django bellek kullanımını azaltmak için bazı ipuçları vardır .

Önemli noktalar:

  • Hata ayıklamanın false olarak ayarlandığından emin olun (bunu zaten biliyorsunuz).
  • Apache yapılandırmanızda "ServerLimit" kullanın
  • Bellekte büyük nesnelerin yüklü olmadığından emin olun
  • Statik içeriği ayrı bir işlemde veya sunucuda sunmayı düşünün.
  • Apache yapılandırmanızda "MaxRequestsPerChild" kullanın
  • Ne kadar bellek kullandığınızı öğrenin ve anlayın

2
Teşekkürler, bunları zaten okumuştum. 3 ve 6 rakamları. Biraz daha ayrıntı bekliyordum! ;-)
Andy Baker

3

Mod_wsgi için başka bir artı: direktifinizde bir maximum-requestsparametre ayarlayın WSGIDaemonProcessve mod_wsgi arka plan sürecini sık sık yeniden başlatır. Django ve uygulama kodunuzu belleğe yükleyeceğinden, yeni bir işlem ilk kez başlatıldığında yavaş sayfa yükleme dışında kullanıcı için görünür bir etki olmamalıdır.

Ama bile yapmak kullanıcılara kesme hizmetine gerek kalmadan, çok büyük girmesini süreç boyutunu tutmalı bellek sızıntılarını var.


1
Burada benzer bir şeyden bahsediliyor: mail-archive.com/django-users@googlegroups.com/msg84698.html maksimum istek yerine yalnızca etkinlik dışı kalma zaman aşımı kullandılar.
Tomas Andrle

3

Mod_wsgi için kullandığım komut dosyası (wsgi.py olarak adlandırılır ve django projemden köke koyar):

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()

Projem.settings öğelerini ve yolu gerektiği gibi ayarlayın. Mod_wsgi varsayılan olarak yazdırmayı engellediğinden tüm çıktıları / dev / null'a yönlendiriyorum. Bunun yerine günlüğe kaydetmeyi kullanın.

Apache için:

<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>

Umarım bu en azından mod_wsgi'yi kurmanıza yardımcı olur, böylece bir fark yaratıp yaratmadığını görebilirsiniz.


1

Önbellekler: temizlendiklerinden emin olun. Bir şeyin önbelleğe inmesi kolaydır, ancak önbellek referansı nedeniyle asla GC'd olmaz.

Swig'd kodu: Herhangi bir bellek yönetiminin doğru bir şekilde yapıldığından emin olun, özellikle üçüncü taraf kütüphanelerinde python'da bunları kaçırmak gerçekten kolay

İzleme: Yapabiliyorsanız, bellek kullanımı ve isabetler hakkında veri alın. Genellikle belirli bir istek türü ile bellek kullanımı arasında bir korelasyon görürsünüz.


1

Django'da büyük site haritalarıyla (10.000 öğe) bir hatayı tökezledik. Görünüşe göre Django, site haritasını oluştururken hepsini belleğe yüklemeye çalışıyor: http://code.djangoproject.com/ticket/11572 - Google, siteyi ziyaret ettiğinde apache işlemini etkili bir şekilde öldürür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.