2013-01-22 12 views
7

Używamy django, aby utworzyć interfejs serwisowy json dla mysql. Mamy apache i django działające na instancji EC2 i MySQL działające na instancji RDS. Rozpoczęliśmy testy wydajności przy użyciu ławki apache i uzyskaliśmy kilka naprawdę słabych wyników. Zauważyliśmy również, że podczas uruchamiania testów nasza instancja apache/django przechodzi do 100% użycia procesora przy bardzo niskim obciążeniu, a instancja MySQL nigdy nie przekracza 2% wykorzystania procesora.Czy istnieje sposób na przyspieszenie funkcji uwierzytelniania w django?

Próbujemy zrozumieć to i wyizolować problem, więc zrobiliśmy kilka testów AB:

  1. Wniosek o statyczną stronę HTML z apache - ~ 2000 zapytań/sekundę.
  2. Żądanie, które wykonuje małą funkcję python w django i brak interakcji db - ~ 1000 żądań/sekundę.
  3. Żądanie, które wykonuje jedną z naszych funkcji serwisu django, która wywołuje uwierzytelnienie, a następnie wykonuje bardzo proste zapytanie, aby pobrać jeden rekord z tabeli - 11 żądań/sekundę
  4. To samo co 3, ale skomentował połączenie do uwierzytelnienia - - 95 wniosków/sekundę.

Dlaczego uwierzytelnianie jest takie powolne? Czy zapisuje dane do bazy danych, znajdując miliard cyfr pi, co?

Chcielibyśmy zachować uwierzytelnianie w tych funkcjach, ponieważ nie chcemy, aby były otwarte dla każdego, kto może odgadnąć adres URL, itp. Czy ktoś tutaj zauważył, że uwierzytelnienie jest powolne i czy ktoś może zasugerować sposób na zaradzenie?

Dziękuję bardzo!

+0

Wypróbuj kilka rzeczy: pobierz django-debug-toolbar i odczytaj wynik. Zobacz, jakiego rodzaju zapytania wykonuje. Wypróbuj django-profile i przeczytaj czasy wykonywania funkcji. Wreszcie, uzyskaj newrelic ... nawet darmowa wersja pokaże Ci przydatne podziały na widok func. Podekscytowany, aby usłyszeć niektóre wyniki! –

Odpowiedz

7

Nie jestem ekspertem od uwierzytelniania i bezpieczeństwa, ale poniżej przedstawiono kilka pomysłów, dlaczego tak się dzieje i ewentualnie w jaki sposób można nieco zwiększyć wydajność.

Ponieważ hasła są przechowywane w bazie danych, aby ich przechowywanie było bezpieczne, hasło w postaci zwykłego tekstu nie są przechowywane, ale zamiast tego przechowywane są ich skróty. W ten sposób można jeszcze sprawdzić poprawność logowania użytkownika, porównując obliczony skrót z wpisanego hasła z tym przechowywanym w bazie danych. Zwiększa to bezpieczeństwo, więc jeśli złośliwa strona otrzyma kopię bazy danych, jedynym sposobem dekodowania haseł w postaci zwykłego tekstu jest użycie tablic tęczowych lub wykonanie ataku brute-force.

Tutaj sprawy stają się interesujące. Zgodnie z Prawem Moore'a, komputery stają się coraz szybciej wykładniczo szybsze, dlatego obliczanie funkcji skrótu staje się znacznie tańsze pod względem czasu, zwłaszcza szybkie funkcje skrótu, takie jak md5 lub sha1. Stanowi to problem, ponieważ dysponując całą dostępną mocą obliczeniową w połączeniu z szybkimi funkcjami skrótu, hakerzy mogą stosunkowo brutalnie mieszać hasła. Aby temu zaradzić, można zrobić dwie rzeczy. Jeden to pętla funkcji mieszania wiele razy (wyjście z hasha jest ponownie wprowadzane do mieszania). Nie jest to jednak bardzo skuteczne, ponieważ zwiększa tylko złożoność funkcji mieszającej o stałą. Dlatego preferowane jest drugie podejście, które sprawia, że ​​rzeczywista funkcja skrótu jest bardziej złożona i kosztowna pod względem obliczeniowym. Mając bardziej złożoną funkcję, obliczenie skrótu zajmuje więcej czasu. Nawet jeśli obliczenie zajmuje sekundę, nie jest to wielka sprawa dla użytkowników końcowych, ale jest to wielka sprawa dla ataków typu brute force, ponieważ trzeba wyliczyć miliony skrótów. Dlatego zaczynając od Django 1.4, wykorzystuje on dość kosztowną pod względem obliczeniowym funkcję o nazwie PBKDF2.

Aby wrócić do odpowiedzi. To z powodu tej funkcji, po włączeniu uwierzytelniania numer kontrolny drastycznie spada, a procesor rośnie.

Oto kilka sposobów na zwiększenie wydajności.

  • Począwszy od Django 1.4, można zmienić domyślną funkcję uwierzytelniania (docs). Jeśli nie potrzebujesz większego bezpieczeństwa, możesz zmienić domyślną funkcję SHA1 lub MD5. To powinno zwiększyć wydajność, ale pamiętaj, że bezpieczeństwo będzie znacznie słabsze. Moja osobista opinia jest taka, że ​​bezpieczeństwo jest ważne i warte dodatkowego czasu, ale jeśli nie jest to uzasadnione w twojej aplikacji, jest to coś, co możesz chcieć rozważyć.
  • Skorzystaj z sesji. Kosztowna funkcja skrótu jest obliczana tylko przy pierwszym logowaniu. Gdy użytkownik się zaloguje, sesja jest tworzona dla tej sesji i plik cookie jest wysyłany do użytkownika z identyfikatorem sesji. Następnie przy kolejnych żądaniach użytkownik przesyła plik cookie, a jeśli sesja jeszcze nie wygasła, użytkownik jest automatycznie uwierzytelniany (nie martw się o bezpieczeństwo od podpisania danych sesji ...). Chodzi o to, że sesja weryfikująca jest O wiele mniej kosztowna pod względem obliczeniowym niż obliczenie kosztownej funkcji skrótu. Sądzę, że w testach ab nie wysłałeś pliku cookie sesji. Spróbuj wykonać kilka testów z dodatkiem wysyłania pliku cookie sesji i zobacz, jak działa. Jeśli wysyłanie plików cookie nie jest tak naprawdę opcją, ponieważ tworzysz interfejs API JSON, możesz zmodyfikować backend sesji, aby zaakceptować dane sesji za pomocą parametru GET sesji zamiast pliku cookie. Nie wiem jednak, jakie są tego konsekwencje dla bezpieczeństwa.
  • Przełącz na nginx. Nie jestem ekspertem od wdrażania, ale z mojego doświadczenia wynika, że ​​nginx jest znacznie szybszy i bardziej przyjazny dla Django w porównaniu do Apache. Jedną z zalet, które moim zdaniem mogą być szczególnie interesujące, jest możliwość posiadania wielu procesów roboczych i możliwość używania proxy_pass do przekazywania żądań procesom (procesom) Django. Jeśli będziesz mieć wiele procesów roboczych, możesz wskazać każdemu pracownikowi osobny proces Django przez proxy_pass, który skutecznie doda proces wieloprocesowy do Django. Inną alternatywą jest to, że jeśli używasz czegoś takiego jak gevent serwera WSGI, możesz utworzyć pulę w procesie Django, co również może zwiększyć wydajność. Nie jestem pewien, czy któryś z nich znacznie zwiększy wydajność, ponieważ obciążenie procesora wynosi już 100%, ale może być czymś, na co warto zwrócić uwagę.
+0

Doskonała odpowiedź, dzięki. – HansG600

Powiązane problemy