Jak wcześniej pisałem, przenosiłem stronę ze standardowego Django na GAE. Mocno uważałem, by aplikacja była wydajna, więc zastosowałem liczniki, cache stron, komentarze jak elementy podrzędne, ale i tak dałem się złapać na pewne przyzwyczajenie ze standardowego Django...
W oryginalnym Django stosowałem context_processor pobierający listę komentarzy i tagów, bo było to wygodne rozwiązanie. Co istotne, procesor tylko ustawiał obiekty QuerySet, więc nie było hitów do bazy i system cache mogłem wprowadzić w samym szablonie bez jakiegoś dużego uszczerbku na wydajności, uzyskując prostotę rozwiązania.
W wersji GAE w większości sytuacji stosuje się jednak metodę fetch(), która jest wykonywana od razu i co ważne nie tworzy cache'a wyników, czyli to samo fetch() wykonane dwukrotnie dla tego samego zapytania dwukrotnie pobierze dane z DataStore. Oczywiście w tej sytuacji mój nietypowy system cache poszedł do kosza, bo co z tego, że miałem cache w szablonie, skoro procesor jest wykonywany wcześniej (i to przy każdym zapytaniu!), więc zawsze pobierze dane!
To już duża nieefektywność, ale uszłaby mojemu wzrokowi (nie mam jak porównać czasów wykonania), gdyby nie fakt, że RSS zabierał kilkukrotnie więcej czasu niż zwykłe żądania. Zacząłem szukać przyczyny. Okazało się, że generator RSS używa wewnętrznie RequestContext kilkukrotnie dla każdego generowanego wpisu RSS, więc zamiast 10 zapytań (ostatnich 10 wpisów), do DataStore szło minimum 10 + 3 * 10 * 3, czyli był to 600% narzut na najbardziej czasochłonnym zasobie GAE :) W standardowym Django, gdzie tylko było generowane QuerySet, problem pozostawał niezauważony. Ze zdwojoną siłą dal o sobie znać dopiero w GAE.
Wnioski
- Zawsze pamiętaj, że
fetch(10)to nie[:10](GAE ma opóźniony system pobierania, ale nie umożliwia on łatwego ograniczenia liczby wyników). - Cache powinien działać na poziome
context_processor, jeśli tylko jest podejrzenie, że będzie kosztowny. - A najlepiej w ogóle zrezygnować z niego, jeśli jest stosowany tylko na części stron WWW (RSS w ogóle go nie potrzebował, a z racji swej specyfiki najbardziej zjadł zasoby).
- Trzeba się czasem wyzbyć pewnych założeń optymalizacyjnych zapewnianych przez Django, bo w GAE może ich po prostu nie być!
Pozostał już tylko jeden problem, o którym pisałem wcześniej. Spory czas uruchamiania interpretera z Django 1.0 jako ZIP + GAE Helper + aplikacja. To akurat mogłaby rozwiązać większa popularność stronki... ;)
0 comments:
Post a Comment