Z biegiem czasu moje zużycie pamięci rośnie, a ponowne uruchamianie Django nie jest miłe dla użytkowników.
Nie jestem pewien, jak zająć się profilowaniem użycia pamięci, ale przydatne byłyby kilka wskazówek, jak rozpocząć pomiar.
Mam wrażenie, że jest kilka prostych kroków, które mogą przynieść duże korzyści. Zapewnienie ustawienia „debugowania” na „Fałsz” jest oczywistym problemem.
Czy ktoś może zasugerować innym? Jak dużo ulepszyłoby buforowanie w witrynach o małym ruchu?
W tym przypadku pracuję pod Apache 2.x z mod_python. Słyszałem, że mod_wsgi jest nieco szczuplejszy, ale trudno byłoby go zmienić na tym etapie, chyba że wiem, że korzyści byłyby znaczące.
Edycja: Dzięki za dotychczasowe wskazówki. Jakieś sugestie, jak odkryć, co zużywa pamięć? Czy są jakieś przewodniki po profilowaniu pamięci w języku Python?
Jak wspomniano, jest kilka rzeczy, które utrudnią przejście na mod_wsgi, więc chciałbym mieć pojęcie o korzyściach, których mogę się spodziewać, zanim zacznę orać w tym kierunku.
Edycja: Carl zamieścił tutaj nieco bardziej szczegółową odpowiedź, którą warto przeczytać: Django Deployment: Cutting Apache's Overhead
Edycja: artykuł Grahama Dumpletona jest najlepszym, jaki znalazłem w sprawach związanych z MPM i mod_wsgi. Jestem raczej rozczarowany, że nikt nie mógł podać żadnych informacji na temat debugowania użycia pamięci w samej aplikacji.
Ostateczna edycja : Cóż, omawiałem to z Webfaction, aby sprawdzić, czy mogą pomóc w ponownej kompilacji Apache, a to jest ich słowo w tej sprawie:
„Naprawdę nie sądzę, abyś odniósł wiele korzyści, przełączając się na konfigurację MPM Worker + mod_wsgi. Szacuję, że możesz zaoszczędzić około 20 MB, ale prawdopodobnie niewiele więcej niż to”.
Więc! To prowadzi mnie z powrotem do mojego pierwotnego pytania (o którym nadal nie jestem mądrzejszy). Jak należy zidentyfikować, gdzie leżą problemy? Jest to dobrze znana maksyma, że nie optymalizuje się bez testowania, aby zobaczyć, gdzie trzeba ją zoptymalizować, ale jest bardzo niewiele tutoriali na temat pomiaru wykorzystania pamięci w Pythonie i nie ma ich w ogóle specyficznych dla Django.
Dziękuję wszystkim za pomoc, ale myślę, że to pytanie jest nadal otwarte!
Kolejna ostatnia edycja ;-)
Zapytałem o to na liście użytkowników django i otrzymałem kilka bardzo pomocnych odpowiedzi
Szczerze mówiąc, ostatnia aktualizacja w historii!
To właśnie zostało wydane. To może być najlepsze jak dotąd rozwiązanie: Profilowanie rozmiaru obiektu Django i użycia pamięci za pomocą Pymplera
źródło
Jeśli używasz pod mod_wsgi i przypuszczalnie tarła, ponieważ jest zgodny WSGI można używać Dozer spojrzeć na zużycie pamięci.
Pod mod_wsgi po prostu dodaj to na dole swojego skryptu WSGI:
Następnie skieruj swoją przeglądarkę na http: // domain / _dozer / index, aby zobaczyć listę wszystkich przydziałów pamięci.
Dodam też tylko głos poparcia dla mod_wsgi. To robi ogromną różnicę pod względem wydajności i zużycia pamięci w porównaniu z mod_python. Wsparcie Grahama Dumpletona dla mod_wsgi jest wyjątkowe, zarówno pod względem aktywnego rozwoju, jak i pomocy osobom z listy mailingowej w optymalizacji ich instalacji. David Cramer z curse.com opublikował kilka wykresów (których niestety nie mogę znaleźć) pokazujących drastyczne zmniejszenie zużycia procesora i pamięci po przejściu na mod_wsgi w tej witrynie o dużym ruchu. Kilku deweloperów django się zmieniło. Poważnie, to oczywiste :)
źródło
Oto znane mi rozwiązania profilera pamięci w Pythonie (nie związane z Django):
Python Memory Validator (komercyjny)Zastrzeżenie: mam udział w tym drugim.
Dokumentacja projektu powinna dać wyobrażenie o tym, jak używać tych narzędzi do analizy zachowania pamięci aplikacji Python.
Poniżej znajduje się fajna „historia wojenna”, która zawiera również przydatne wskazówki:
źródło
Dodatkowo sprawdź, czy nie używasz żadnego ze znanych wycieków. Wiadomo, że MySQLdb wycieka ogromne ilości pamięci wraz z Django z powodu błędu w obsłudze Unicode. Poza tym Django Debug Toolbar może pomóc w śledzeniu świń.
źródło
django-debug-toolbar
pomóc?Oprócz unikania globalnych odwołań do dużych obiektów danych, staraj się w ogóle unikać ładowania dużych zestawów danych do pamięci, gdy tylko jest to możliwe.
Przełącz się na mod_wsgi w trybie demona i użyj mpm pracownika Apache zamiast prefork. Ten ostatni krok umożliwia obsługę większej liczby jednoczesnych użytkowników przy znacznie mniejszym obciążeniu pamięci.
źródło
Witryna internetowa faktycznie ma kilka wskazówek dotyczących ograniczania zużycia pamięci przez django.
Główne punkty:
źródło
Kolejny plus dla mod_wsgi: ustaw
maximum-requests
parametr w swojejWSGIDaemonProcess
dyrektywie, a mod_wsgi będzie co jakiś czas restartować proces demona. Dla użytkownika nie powinno być żadnych widocznych efektów, poza powolnym ładowaniem strony przy pierwszym uruchomieniu nowego procesu, ponieważ ładuje on Django i kod aplikacji do pamięci.Ale nawet jeśli zrobić ma wycieków pamięci, które powinny utrzymać wielkość procesową się zbyt duże, bez konieczności przerwania usługi dla użytkowników.
źródło
Oto skrypt, którego używam dla mod_wsgi (o nazwie wsgi.py i umieszczam w katalogu głównym mojego projektu django):
Dostosuj ustawienia myproject.settings i ścieżkę według potrzeb. Przekierowuję wszystkie dane wyjściowe do / dev / null, ponieważ mod_wsgi domyślnie zapobiega drukowaniu. Zamiast tego użyj logowania.
Dla Apache:
Mam nadzieję, że powinno to przynajmniej pomóc w skonfigurowaniu mod_wsgi, abyś mógł zobaczyć, czy to robi różnicę.
źródło
Skrytki: upewnij się, że są opróżniane. Łatwo jest coś wylądować w pamięci podręcznej, ale nigdy nie zostanie przypisane do GC z powodu odwołania do pamięci podręcznej.
Kod Swig'd: Upewnij się, że zarządzanie pamięcią jest wykonywane poprawnie, bardzo łatwo jest przeoczyć je w Pythonie, szczególnie w przypadku bibliotek innych firm
Monitorowanie: jeśli możesz, uzyskaj dane o wykorzystaniu pamięci i trafieniach. Zwykle zobaczysz korelację między określonym typem żądania a zużyciem pamięci.
źródło
Natknęliśmy się na błąd w Django z dużymi mapami witryn (10.000 pozycji). Wygląda na to, że Django próbuje załadować je wszystkie do pamięci podczas generowania mapy witryny: http://code.djangoproject.com/ticket/11572 - skutecznie zabija proces apache, gdy Google odwiedza witrynę.
źródło