Azure "App Service" - Django 和 SQLite

6
我有一个 Django 应用程序(具体来说是 Django-Rest)。当我运行本地站点的副本时,我的请求可以在 50-400ms 内处理。
接下来,我设法部署到了 Microsoft Azure 应用服务。现在,在我可以购买的最昂贵层级下,响应时间在 800-2000ms 范围内返回。
该应用程序对 SQLite 数据库进行简单查询。该数据库文件大小约为 30MB,最大表格为 12000 行。
需要指出的是,所有对数据库的访问都是只读的,因此不存在争用问题。
配置:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(PROJECT_ROOT, 'mydatabase.db'),
    }
}

web.config:

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="WSGI_ALT_VIRTUALENV_HANDLER" value="django.core.wsgi.get_wsgi_application()" />
    <add key="WSGI_ALT_VIRTUALENV_ACTIVATE_THIS" value="D:\home\site\wwwroot\env\Scripts\activate_this.py" />
    <add key="WSGI_HANDLER" value="ptvs_virtualenv_proxy.get_virtualenv_handler()" />
    <add key="PYTHONPATH" value="D:\home\site\wwwroot" />
    <add key="DJANGO_SETTINGS_MODULE" value="myapp.settings" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <!-- Required for websockets. -->
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
      <remove name="Python273_via_FastCGI" />
      <add name="Python FastCGI" path="handler.fcgi" verb="*" modules="FastCgiModule" scriptProcessor="D:\Python27\python.exe|D:\Python27\Scripts\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" />
    </handlers>
    <rewrite>
      <rules>
        <rule name="Static Files" stopProcessing="true">
          <conditions>
            <add input="true" pattern="false" />
          </conditions>
        </rule>
        <rule name="Configure Python" stopProcessing="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{REQUEST_URI}" pattern="^/static/.*" ignoreCase="true" negate="true" />
          </conditions>
          <action type="Rewrite" url="handler.fcgi/{R:1}" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Python版本为2.7。

我已经缩小了问题范围,发现是SQLite性能问题。静态文件和API索引页面返回时间约为60毫秒,而最重的查询返回时间约为2000毫秒。这是 Time Till First Byte,不是整个响应时间,我已排除了网络延迟(由于地理位置接近,网络延迟非常低)。这是在 P3(高级版)4核、7GB内存的 Azure 上运行。

在本地主机上运行时,索引页面的响应时间约为15毫秒,而在我的 Macbook 2.2 GHz Intel Core i7 16 GB 1600 MHz DDR3 上发送相同的请求的响应时间约为380毫秒。

应用程序已经“热”起来后,“热身”并不是问题(计时基于几次刷新)

更新: 我安装了Django Rest Toolbar以获取更多信息。

在Macbook Django DEV服务器上(纯Python?):

SQL time ~217ms
Total CPU time ~681ms

Resource    Value
User CPU time   662.771 msec
System CPU time 18.415 msec
Total CPU time  681.186 msec
Elapsed time    681.326 msec
Context switches    1 voluntary, 95 involuntary

在Azure应用服务中,使用IIS和FastCGI(如上所示的配置):
SQL time ~854ms
Total CPU time ~2282ms
No CPU extended breakdown available.

感谢任何见解!

如果你怀疑是sqlite引起的问题,可以查看调试工具栏中的SQL选项卡,看看有多少查询显示在那里,以及哪一个最慢。 - e4c5
然而,很明显你的总 CPU 时间是查询时间的 3 倍,因此你似乎在视图中做了一些繁重的工作。发一些代码如何? - e4c5
考虑到您的本地和Azure测试运行显示出类似的最优和最劣情况的多重性,以及您只有一个30MB的数据库文件,我的猜测是您的Azure主机只是一个更慢的CPU。看起来他们对某些规格进行了限制。 - Peter Brittain
@PeterBrittain 我认为你是正确的。如果你写在答案里,我可以接受。只是补充一下信息 - 这是 PaaS 而不是 IaaS,所以它并不是一个虚拟机。 - beiller
唯一我能想象的其他解决方案就是创建一个内存数据库并将整个内容加载到其中。请参阅https://www.sqlite.org/backup.html。 - Vinzenz
显示剩余5条评论
1个回答

0

鉴于您的本地和Azure测试运行显示出类似的最佳到最差情况的多重性,并且您只有一个30MB的数据库文件,我猜测您的Azure主机只是CPU速度较慢。

这得到了事实的支持,即它们对某些规格的VM进行限流。 这也是与AWS的比较中注意到的一点。 我想您的应用服务平台也是如此。


结果发现问题出在SQLite和I/O性能上。这很糟糕,因为他们的前端服务器是分布式的,并且通过一个缓慢的网络文件系统工作。转换到SQL Server是唯一的解决方案。 - beiller
大概是因为他们保证了更好的磁盘 IO,所以才会选择他们的 SQL 服务器产品。 - Peter Brittain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接