Проблема
Как мы знаем, хеширование паролей (например, с помощью bcrypt или argon2) — это относительно медленная операция, связанная с использованием ЦП. В моем случае я использую bcrypt.
- Хеширование занимает заметное время на каждый запрос.
- Оно блокирует выполнение (зависит от процессора).
- При высокой нагрузке (много одновременных запросов на вход) это становится узким местом.
- Bcrypt в Python реализован на языке C, поэтому он может работать в параллельных потоках.
- В асинхронных приложениях операции блокировки должны быть выгружены в пул потоков.
Я пытался разгрузить хеширование используя:
Код: Выделить всё
await asyncio.to_thread(bcrypt.hashpw, password, salt)
Код: Выделить всё
loop.run_in_executor(...)
- пропускная способность не масштабируется должным образом
- увеличение размера пула потоков существенно не повышает производительность
- ЦП, похоже, становится узким местом
- Увеличение количества воркеров (процессов) дает заметное улучшение производительности
- Увеличение количества потоков (через исполнителя) не дает такого же эффекта
- Похоже, что я ограничен поведением ЦП и/или GIL
Как эта проблема обычно решается в высоконагруженных веб-приложениях Python?
В частности:
- Является ли использование ThreadPoolExecutor правильным подходом для bcrypt/argon2 в асинхронных приложениях?
- Ожидается ли это? что масштабирование в основном достигается за счет нескольких рабочих процессов (процессов), а не потоков?
- Существуют ли общие архитектурные шаблоны, такие как:
- выделенная служба аутентификации
- фоновые рабочие процессы
- ограничение скорости входа в систему конечные точки
- Есть ли лучшие альтернативы bcrypt для сценариев с высокой нагрузкой (например, настройка argon2)?
Я пытаюсь понять, что считается лучшей практикой для обработки хеширования паролей в асинхронном Python с высокой нагрузкой приложения.
Любые реальные подходы или архитектурные шаблоны будут высоко оценены.
Подробнее: https://stackoverflow.com/questions/799 ... locking-an
Мобильная версия