2013-01-22 3 views
7

우리는 django를 사용하여 mysql을위한 json webservice 프론트 엔드를 만들고있다. 우리는 아파치와 django가 EC2 인스턴스와 MySQL을 RDS 인스턴스에서 실행하고 있습니다. 우리는 아파치 벤치를 사용하여 벤치마킹 성능을 시작했으며 성능 수치가 매우 낮습니다. 또한 테스트를 실행하는 동안 apache/django 인스턴스가 매우 낮은로드에서 100 % cpu 사용률로 이동하고 MySQL 인스턴스가 2 % CPU 사용률을 초과하지 않음을 발견했습니다.django에서 인증 기능을 빠르게하는 방법이 있습니까?

것은 우리는이를 이해하고 문제를 격리하기 위해 노력하고, 그래서 우리는 몇 가지 AB를 시험했다 :

  1. 아파치에서 정적 HTML 페이지에 대한 요청 - ~ 2000 요청/초.
  2. django에서 작은 파이썬 함수를 실행하고 db interaction없이 ~ 1000 요청/초 요청.
  3. 우리의 django webservice 함수 중 하나를 실행하여 인증을 호출 한 다음 테이블에서 레코드 하나를 가져 오는 매우 간단한 쿼리를 수행하는 요청 - 초당 11 요청
  4. 3과 같지만 인증 호출에 주석 처리됨 - - 초당 95 회의 요청.

인증이 너무 느린 이유는 무엇입니까? DB에 데이터를 쓰고 있으며 십억 자리의 파이를 찾는거야?

우리는 URL을 추측 할 수있는 누구에게나 공개하고 싶지 않기 때문에이 함수에 인증을 요청하고 싶습니다. 여기 누군가가 인증이 느리고 누군가가 제안 할 수 있음을 알았습니까? 그것을 고치는 방법?

대단히 감사합니다!

+0

다음을 시도해보십시오. django-debug-toolbar를 다운로드하고 출력을 읽으십시오. 쿼리의 종류를 확인하십시오. django-profile을 실행하고 함수 실행 시간을 읽으십시오. 마지막으로, newrelic을 얻으십시오 ... 무료 버전이라도 view func 당 유용한 고장을 보여줍니다. 어떤 결과를 듣고 흥분! –

답변

7

저는 인증 및 보안 전문가가 아니지만 다음과 같은 이유와 성능 향상 방법에 대한 아이디어가 있습니다.

암호가 db에 저장되므로 저장소의 보안을 유지하기 위해 일반 텍스트 암호는 저장되지 않지만 해시는 대신 저장됩니다. 이렇게하면 입력 된 암호의 계산 된 해시를 db에 저장된 암호와 비교하여 사용자 로그인을 확인할 수 있습니다. 이렇게하면 보안이 강화되어 악의적 인 사람이 db 복사본을 얻게되면 일반 텍스트 암호를 해독 할 수있는 유일한 방법은 레인보우 테이블을 사용하거나 무차별 공격을 수행하는 것입니다.

이것은 흥미로운 부분입니다. 무어의 법칙에 따르면 컴퓨터가 기하 급수적으로 빨라지므로 계산 해시 함수는 시간면에서 훨씬 저렴 해졌으며 특히 md5 또는 sha1과 같은 빠른 해시 함수가 사용되었습니다. 이것은 빠른 해시 함수와 결합 된 모든 컴퓨팅 성능을 오늘날 사용할 수 있기 때문에 해커가 해시 된 암호를 상대적으로 쉽게 사용할 수 있기 때문에 문제가됩니다. 이 문제를 해결하기 위해 두 가지 작업을 수행 할 수 있습니다. 하나는 해시 함수를 여러 번 반복하는 것입니다 (해시의 출력은 해시로 다시 입력됩니다). 그러나 이것은 해시 함수의 복잡도를 상수만큼 증가시키기 때문에 그다지 효과적이지 않습니다. 이것이 실제 해시 함수를보다 복잡하고 계산 비용이 많이 드는 두 번째 방법이 선호되는 이유입니다. 보다 복잡한 함수를 사용하면 해시를 계산하는 데 더 많은 시간이 소요됩니다. 계산에 초가 걸리지 만 최종 사용자에게는 큰 문제가 아니지만 수백만 해시를 계산해야하기 때문에 무차별 대입 공격에 큰 영향을 미칩니다. 그래서 Django 1.4부터는 PBKDF2라는 매우 비싼 함수를 사용합니다.

답변을 다시 받으려면. 이 기능 때문에 인증을 사용하면 벤치 마크 번호가 급격히 내려 가고 CPU가 올라갑니다.

다음은 성능을 향상시킬 수있는 몇 가지 방법입니다.

  • Django 1.4부터는 기본 인증 기능 (docs)을 변경할 수 있습니다. 보안이별로 필요하지 않은 경우 기본 기능을 SHA1 또는 MD5로 변경할 수 있습니다. 성능은 향상되지만 보안은 훨씬 약할 것이라는 점을 기억하십시오. 개인적인 견해로는 보안은 중요하며 추가 시간의 가치가 있습니다. 그러나 응용 프로그램에서 보증하지 않으면 고려해야 할 사항입니다.
  • 세션을 사용하십시오. 값 비싼 해시 함수는 초기 로그인시에만 계산됩니다. 사용자가 로그인하면 해당 세션에 대한 세션이 만들어지고 세션 ID로 쿠키가 사용자에게 전송됩니다. 이후 요청시 사용자가 쿠키를 업로드하고 세션이 아직 만료되지 않은 경우 사용자는 자동으로 인증됩니다 (세션 데이터에 서명 된 이후 보안에 대해 걱정하지 마십시오). 요점은 검증 세션이 값 비싼 해시 함수를 계산하는 것보다 계산적으로 덜 비싸다는 것입니다. 나는 ab 테스트에서 당신이 세션 쿠키를 보내지 않았다고 생각합니다. 세션 쿠키를 보내고 테스트를 수행하고 세션 쿠키가 어떻게 수행되는지보십시오. JSON API를 작성한 이후로 쿠키를 보내는 것이 실제로 옵션이 아닌 경우 세션 백엔드를 수정하여 쿠키 대신 세션 GET 매개 변수를 통해 세션 데이터를 수락 할 수 있습니다. 그러나 그 일을하는 것이 보안에 미치는 영향은 확실하지 않습니다.
  • nginx로 전환하십시오. 나는 배치 전문가가 아니지만 제 경험에서 nginx는 Apache에 비해 장고에 훨씬 빠르고 친숙합니다. 내가 특별히 관심을 가질만한 장점 중 하나는 nginx가 여러 작업자 프로세스를 가질 수 있고 장고 프로세스에 대한 요청을 처리하기 위해 proxy_pass를 사용할 수 있다는 점입니다. 여러 개의 작업자 프로세스가 있다면 proxy_pass를 통해 각 작업자가 별도의 장고 프로세스를 가리킬 수 있습니다. 그러면 효과적으로 다중 프로세스가 장고에 추가됩니다. 또 다른 대안은 gevent WSGI 서버와 같은 것을 사용하면 Django 프로세스에서 풀을 만들어 성능을 향상시킬 수 있다는 것입니다. CPU로드가 이미 100 %에 이르렀으므로 이들 중 하나라도 성능이 크게 향상 될지는 모르지만 조사 할 항목이 될 수 있습니다.
+0

우수 답변, 감사합니다. – HansG600

관련 문제