Python 有没有办法加快django中的身份验证功能?

Python 有没有办法加快django中的身份验证功能?,python,mysql,django,performance,apache,Python,Mysql,Django,Performance,Apache,我们正在使用django为mysql制作一个json Web服务前端。我们在EC2实例上运行apache和django,在RDS实例上运行MySQL。我们已经开始使用ApacheBench进行性能基准测试,但得到了一些非常糟糕的性能数据。我们还注意到,在运行测试时,我们的apache/django实例在非常低的负载下达到100%的cpu使用率,而MySQL实例的cpu使用率从未超过2% 我们试图弄明白这一点并隔离问题,因此我们进行了几次ab测试: 来自apache的静态html页面请求--~20

我们正在使用django为mysql制作一个json Web服务前端。我们在EC2实例上运行apache和django,在RDS实例上运行MySQL。我们已经开始使用ApacheBench进行性能基准测试,但得到了一些非常糟糕的性能数据。我们还注意到,在运行测试时,我们的apache/django实例在非常低的负载下达到100%的cpu使用率,而MySQL实例的cpu使用率从未超过2%

我们试图弄明白这一点并隔离问题,因此我们进行了几次ab测试:

  • 来自apache的静态html页面请求--~2000个请求/秒
  • 一个在django中执行一个小python函数的请求,并且没有db交互--1000个请求/秒
  • 一个请求,它执行我们的django webservice函数之一,该函数调用authenticate,然后执行一个非常简单的查询以从表中获取一条记录——11个请求/秒
  • 与3相同,但注释了对身份验证的调用--95个请求/秒
  • 为什么认证这么慢?它是在向数据库写入数据,找到10亿位数的pi,什么

    我们希望在这些函数中保持对身份验证的调用,因为我们不想让任何能够猜到url的人打开它们。这里有没有人注意到身份验证很慢,有人能建议一种补救方法


    多谢各位

    我不是身份验证和安全方面的专家,但以下是一些关于为什么会发生这种情况以及如何在一定程度上提高性能的想法

    由于密码存储在数据库中,为了使其存储安全,不存储明文密码,而是存储其哈希。通过这种方式,您仍然可以通过将键入的密码中计算出的哈希值与数据库中存储的哈希值进行比较来验证用户登录。这提高了安全性,因此,如果恶意方将获得db的副本,则解码明文密码的唯一方法是使用rainbow表或进行暴力攻击

    这就是事情变得有趣的地方。根据摩尔定律,计算机的速度正呈指数级增长,因此计算哈希函数在时间上变得更便宜,特别是像md5或sha1这样的快速哈希函数。这带来了一个问题,因为现在所有可用的计算能力与快速散列函数相结合,黑客可以相对轻松地强行破解散列密码。要解决这一问题,可以做两件事。一种方法是多次循环散列函数(散列的输出反馈到散列中)。然而,这并不是很有效,因为它只会将哈希函数的复杂度增加一个常量。这就是为什么首选第二种方法,即使实际的哈希函数更复杂,计算成本更高。函数越复杂,计算散列所需的时间就越多。即使计算只需一秒钟,对最终用户来说也不是什么大不了的事,但对暴力攻击来说却是件大事,因为必须计算数百万个哈希。这就是为什么从Django 1.4开始,它使用了一个非常昂贵的计算函数PBKDF2

    回到你的答案上来。正是由于这个功能,当您启用身份验证时,您的基准编号会急剧下降,CPU也会上升

    以下是一些可以提高性能的方法

    • 从Django 1.4开始,您可以更改默认的身份验证函数()。如果不需要太多安全性,可以将默认函数更改为SHA1或MD5。这应该会提高性能,但是请记住,安全性将大大减弱。我个人的观点是安全是重要的,值得额外的时间,但是如果在你的应用程序中没有保证,这是你可能要考虑的。
    • 使用会话。昂贵的哈希函数仅在初始登录时计算。用户登录后,将为该会话创建一个会话,并向用户发送一个带有会话id的cookie。然后,在后续请求中,用户将上载一个cookie,如果会话尚未过期,则会自动对用户进行身份验证(由于会话数据已签名,因此不必担心安全性…)。关键是,与计算昂贵的哈希函数相比,验证会话的计算成本要低得多。我猜在ab测试中,您没有发送会话cookie。尝试通过发送会话cookie来进行一些测试,看看它是如何执行的。如果发送cookie不是一个真正的选项,因为您正在制作JSON API,那么您可以修改会话后端,通过会话GET参数而不是cookie来接受会话数据。但不确定这样做的安全后果是什么
    • 切换到nginx。我不是部署方面的专家,但根据我的经验,nginx比Apache更快,对Django更友好。我认为您可能特别感兴趣的一个优势是nginx具有多个工作进程的能力,以及使用代理传递请求到Django进程的能力。如果您将有多个工作进程,那么您可以通过proxy_pass将每个工作进程指向一个单独的Django进程,这将有效地向Django添加多进程。另一种选择是,如果您使用像gevent WSGI server这样的东西,您可以在Django进程中创建一个池,这也可能会提高性能。由于CPU负载已经达到100%,所以不确定这些是否会大幅提高您的性能,但这可能是需要研究的问题

    尝试几件事:下载django调试工具栏并读取输出。看看它在做什么样的查询。尝试django配置文件并读取函数执行时间。最后,获取newrelic。。。即使是免费版本也会显示每个视图功能的有用细分。很高兴听到一些结果!