Есть ли способ ускорить функцию аутентификации в django?

Мы используем django для создания интерфейса json webservice для mysql. У нас есть apache и django, работающие на экземпляре EC2 и MySQL, работающем на экземпляре RDS. Мы начали тестирование производительности с помощью сканера apache и получили очень низкие показатели производительности. Мы также заметили, что при выполнении тестов наш экземпляр apache / django переходит на 100% -ное использование процессора при очень низкой нагрузке, и экземпляр MySQL никогда не получает более 2% -ного использования процессора.

Мы пытаемся понять это и изолировать проблему, поэтому мы сделали несколько тестов ab:

  1. Запрос статической html-страницы от apache – ~ 2000 запросов / секунду.
  2. Запрос, выполняющий небольшую функцию python в django, и не взаимодействие db – ~ 1000 запросов / секунду.
  3. Запрос, который выполняет одну из наших функций dsango webservice, которая вызывает аутентификацию, а затем делает очень простой запрос для извлечения одной записи из таблицы – 11 запросов / секунду
  4. То же, что и 3, но прокомментировал вызов аутентификации – 95 запросов / секунду.

Почему аутентификация настолько медленная? Он пишет данные в db, нахожу миллиард цифр pi, что?

Мы хотели бы, чтобы вызов аутентифицировался в этих функциях, потому что мы не хотим оставлять их открытыми для всех, кто может угадать URL-адрес и т. Д. Кто-нибудь здесь заметил, что аутентификация идет медленно, и может ли кто-нибудь предложить способ исправления Это?

Большое спасибо!

Я не эксперт в области аутентификации и безопасности, но ниже приведены некоторые идеи относительно того, почему это может произойти, и, возможно, как вы можете увеличить производительность.

Поскольку пароли хранятся в db, чтобы защитить их хранилище, пароль незашифрованного текста не сохраняется, но вместо этого сохраняется их хэш. Таким образом, вы все равно можете подтвердить регистрацию пользователя, сравнив вычисленный хеш с введенным паролем на тот, который хранится в db. Это повышает безопасность, так что, если злонамеренная сторона получит копию db, единственный способ декодировать пароли открытого текста – либо использовать радужные таблицы, либо совершать грубую атаку.

Здесь все становится интересным. Согласно Закону Мура, компьютеры становятся экспоненциально быстрее, поэтому вычислительные хэш-функции становятся намного дешевле с точки зрения времени, особенно быстрых хеш-функций, таких как md5 или sha1. Это создает проблему, потому что, имея всю вычислительную мощность, доступную сегодня, в сочетании с быстрыми функциями хэша, хакеры могут грубо заставлять хэшировать пароли относительно легко. Для борьбы с этим можно сделать две вещи. Один из них позволяет циклически зацикливать хеш-функцию (вывод хеша возвращается в хэш). Это, однако, не очень эффективно, потому что это только увеличивает сложность хеш-функции на константу. Поэтому предпочтительным является второй подход, который заключается в том, чтобы сделать фактическую хеш-функцию более сложной и вычислительно дорогостоящей. Имея более сложную функцию, для вычисления хеша требуется больше времени. Даже если для вычисления требуется секунда, для конечных пользователей это не очень важно, но для атаки с грубой силой это очень важно, потому что нужно вычислить миллионы хэшей. Поэтому, начиная с Django 1.4, он использует довольно дорогостоящую вычислительную функцию PBKDF2.

Вернемся к вашему ответу. Именно из-за этой функции, когда вы включаете аутентификацию, ваш контрольный номер резко падает, и ваш процессор растет.

Вот несколько способов повысить производительность.

  • Начиная с Django 1.4, вы можете изменить функцию проверки подлинности по умолчанию ( docs ). Если вам не нужна большая безопасность, вы можете изменить функцию по умолчанию как SHA1 или MD5. Это должно увеличить производительность, однако имейте в виду, что безопасность будет намного слабее. Мое личное мнение заключается в том, что безопасность важна и стоит дополнительного времени, но если это не оправдано в вашем приложении, это то, что вы, возможно, захотите рассмотреть.
  • Используйте сеансы. Дорогая хэш-функция вычисляется только при первоначальном входе в систему. Когда пользователь входит в систему, для этого сеанса создается сеанс, и cookie отправляет пользователю идентификатор сеанса. Затем в последующих запросах пользователь загружает файл cookie, и если сеанс еще не истек, пользователь автоматически аутентифицируется (не беспокойтесь о безопасности, поскольку данные сеанса подписаны …). Дело в том, что проверка сеанса намного меньше вычислительно дорого по сравнению с вычислением дорогостоящей хэш-функции. Я предполагаю, что в тестах ab вы не отправляли cookie сеанса. Попробуйте выполнить некоторые тесты с добавлением отправки файла cookie сеанса и посмотреть, как он выполняется. Если отправка файлов cookie на самом деле не является вариантом, поскольку вы создаете JSON API, то вы можете модифицировать сессионный интерфейс, чтобы принимать данные сеанса через параметр GET сеанса вместо cookie. Не уверен, однако, что такое последствия безопасности для этого.
  • Переключитесь на nginx. Я не эксперт в области развертывания, но по моему опыту nginx намного быстрее и дружелюбнее к Django по сравнению с Apache. Одним из преимуществ, которые, по моему мнению, могут быть особенно интересны для вас, является способность nginx иметь несколько рабочих процессов и возможность использовать proxy_pass для подачи запросов на процесс Django. Если у вас будет несколько рабочих процессов, вы можете указать каждого рабочего на отдельный процесс Django через proxy_pass, который эффективно добавит многопроцессорность в Django. Другая альтернатива – если вы используете что-то вроде gevent WSGI-сервера, вы можете создать пул в процессе Django, который также может повысить производительность. Не уверен, что любой из них значительно увеличит вашу производительность, так как загрузка вашего процессора уже на 100%, но может быть что-то задуматься.