如何提高在高CPU时间下的DRF性能?

12 浏览
0 Comments

如何提高在高CPU时间下的DRF性能?

我有一个使用DRF的REST API,并且在有100个对象和1个用户请求(我在测试)时已经看到了性能下降。当请求更复杂的查询时,我每次得到以下CPU的结果,始终在5-10秒之间:\n

资源    值
用户CPU时间  5987.089毫秒
系统CPU时间  463.929毫秒
总CPU时间   6451.018毫秒
经过时间    6800.938毫秒
上下文切换    9自愿,773非自愿

\n但是SQL查询始终保持在100毫秒以下。\n更简单的查询显示类似的行为,CPU时间约为1秒,查询时间约为20毫秒。\n到目前为止,我尝试了以下方法:\n

    \n

  • 我使用了select_related()和prefetch_related(),这确实提高了查询时间,但没有改善CPU时间
  • \n

  • 我使用Imagekit在S3实例上生成图片。我删除了整个规范进行测试,但影响不大
  • \n

  • 我运行了一个方法字段来获取特定用户的数据。删除后只有轻微的影响
  • \n

\n


\n我检查了后端的日志文件,没有发现任何特定的问题...\n后端是Nginx - supervisord - gunicorn - postgresql - django 1.8.1\n


\n以下是序列化器和视图的代码:\n

class ParticipationOrganizationSerializer(ModelSerializer):
    organization = OrganizationSerializer(required=False, read_only=True, )
    bookmark = SerializerMethodField(
        required=False,
        read_only=True,
    )
    location_map = LocationMapSerializer(
        required=False,
        read_only=True,
    )
    class Meta:
        model = Participation
        fields = (
            'id',
            'slug',
            'organization',
            'location_map',
            'map_code',
            'partner',
            'looking_for',
            'complex_profile',
            'bookmark',
            'confirmed',
        )
        read_only_fields = (
            'id',
            'slug',
            'organization',
            'location_map',
            'map_code',
            'partner',
            'bookmark',
            'confirmed',
        )
    def get_bookmark(self, obj):
        request = self.context.get('request', None)
        if request is not None:
            if(request.user.is_authenticated()):
                # print(obj.bookmarks.filter(author=request.user).count())
                try:
                    bookmark = obj.bookmarks.get(author=request.user)
                    # bookmark = Bookmark.objects.get(
                    #     author=request.user,
                    #     participation=obj,
                    # )
                    return BookmarkSerializer(bookmark).data
                except Bookmark.DoesNotExist:
                    # We have nothing yet
                    return None
                except Bookmark.MultipleObjectsReturned:
                    # This should not happen, but in case it does, delete all
                    # the bookmarks for safety reasons.
                    Bookmark.objects.filter(
                        author=request.user,
                        participation=obj,
                    ).delete()
                    return None
        return None
class ParticipationOrganizationViewSet(ReadOnlyModelViewSet):
    """
    A readonly ViewSet for viewing participations of a certain event.
    """
    serializer_class = ParticipationOrganizationSerializer
    queryset = Participation.objects.all().select_related(
        'location_map',
        'organization',
        'organization__logo_image',
    ).prefetch_related(
        'bookmarks',
    )
    lookup_field = 'slug'
    def get_queryset(self):
        event_slug = self.kwargs['event_slug']
        # Filter for the current event
        # Filter to show only the confirmed participations
        participations = Participation.objects.filter(
            event__slug=event_slug,
            confirmed=True
        ).select_related(
            'location_map',
            'organization',
            'organization__logo_image',
        ).prefetch_related(
            'bookmarks',
        )
        # Filter on partners? This is a parameter passed on in the url
        partners = self.request.query_params.get('partners', None)
        if(partners == "true"):
            participations = participations.filter(partner=True)
        return participations
    def get_serializer_class(self):
        if self.action == 'list':
            return ParticipationOrganizationListSerializer
        if self.action == 'retrieve':
            return ParticipationOrganizationSerializer
        return ParticipationOrganizationListSerializer

\n非常感谢任何帮助!\n


\n更新\n我将数据转储到本地机器上,观察到类似的时间。我想这排除了整个生产环境设置(nginx,gunicorn)的问题?\n


\n更新2\n以下是性能分析器的结果。\n另外,通过以下方式取得了一些提速进展:\n

    \n

  1. 简化了我的序列化器
  2. \n

  3. 使用curl进行测试,并关闭调试工具栏
  4. \n

\n

\n    ncalls  tottime percall cumtime percall filename:lineno(function)\n    0   0   0   profile:0(profiler)     \n    1   0   0   3.441   3.441   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/views.py:442(dispatch)\n    1   0   0   3.441   3.441   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/viewsets.py:69(view)\n    1   0   0   3.441   3.441   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/django/views/decorators/csrf.py:57(wrapped_view)\n    1   0   0   3.44    3.44    /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/mixins.py:39(list)\n    1   0   0   3.438   3.438   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/serializers.py:605(to_representation)\n    1   0   0   3.438   3.438   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/serializers.py:225(data)\n    1   0   0   3.438   3.438   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/serializers.py:672(data)\n    344/114 0.015   0   3.318   0.029   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/serializers.py:454(to_representation)\n    805 0.01    0   2.936   0.004   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/fields.py:1368(to_representation)\n    2767    0.013   0   2.567   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py:166(send)\n    2070    0.002   0   2.52    0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/registry.py:52(existence_required_receiver)\n    2070    0.005   0   2.518   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/registry.py:55(_receive)\n    2070    0.004   0   2.513   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/utils.py:147(call_strategy_method)\n    2070    0.002   0   2.508   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/strategies.py:14(on_existence_required)\n    2070    0.005   0   2.506   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:86(generate)\n    2070    0.002   0   2.501   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/backends.py:109(generate)\n    2070    0.003   0   2.499   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/backends.py:94(generate_now)\n    2070    0.01    0   2.496   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/backends.py:65(get_state)\n    690 0.001   0   2.292   0.003   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:148(__nonzero__)\n    690 0.005   0   2.291   0.003   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:124(__bool__)\n    2070    0.007   0   2.276   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/backends.py:112(_exists)\n    2070    0.01    0   2.269   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/backends.py:72(get_file)\n    4140    0.004   0   2.14    0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/storages/backends/s3boto.py:282(entries)\n    1633    0.003   0   2.135   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/storages/backends/s3boto.py:288()\n    1633    0.001   0   2.129   0.001   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/bucketlistresultset.py:24(bucket_lister)\n    2   0   0   2.128   1.064   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/bucket.py:390(_get_all)\n    2   0   0   2.128   1.064   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/bucket.py:426(get_all_keys)\n    1331    0.003   0   1.288   0.001   /usr/lib/python2.7/ssl.py:335(recv)\n    1331    1.285   0.001   1.285   0.001   /usr/lib/python2.7/ssl.py:254(read)\n    2   0   0   0.983   0.491   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/connection.py:886(_mexe)\n    2   0   0   0.983   0.491   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/connection.py:643(make_request)\n    2   0   0   0.983   0.491   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/connection.py:1062(make_request)\n    2   0.004   0.002   0.896   0.448   /usr/lib/python2.7/httplib.py:585(_read_chunked)\n    2   0   0   0.896   0.448   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/connection.py:393(read)\n    2   0   0   0.896   0.448   /usr/lib/python2.7/httplib.py:540(read)\n    166 0.002   0   0.777   0.005   /usr/lib/python2.7/httplib.py:643(_safe_read)\n    166 0.005   0   0.775   0.005   /usr/lib/python2.7/socket.py:336(read)\n    2   0   0   0.568   0.284   /usr/lib/python2.7/httplib.py:793(send)\n    2   0   0   0.568   0.284   /usr/lib/python2.7/httplib.py:998(_send_request)\n    2   0   0   0.568   0.284   /usr/lib/python2.7/httplib.py:820(_send_output)\n    2   0   0   0.568   0.284   /usr/lib/python2.7/httplib.py:977(request)\n    2   0   0   0.568   0.284   /usr/lib/python2.7/httplib.py:962(endheaders)\n    1   0   0   0.567   0.567   /usr/lib/python2.7/httplib.py:1174(connect)\n    1380    0.001   0   0.547   0   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:82(url)\n    1380    0.007   0   0.546   0   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:72(_storage_attr)\n    105 0.009   0   0.528   0.005   /usr/lib/python2.7/socket.py:406(readline)\n    2   0.223   0.223   0.335   0.335   /usr/lib/python2.7/socket.py:537(create_connection)\n    2865    0.012   0   0.334   0   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/rest_framework/fields.py:399(get_attribute)\n    1   0.001   0.001   0.328   0.328   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/specs/__init__.py:10(__init__)\n    1   0.001   0.001   0.327   0.327   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/specs/__init__.py:30(_process_source)\n    1   0.001   0.001   0.204   0.204   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/specs/__init__.py:51(_generate)\n    1   0   0   0.103   0.103   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:221(url)\n    1   0   0   0.1 0.1 /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/backends.py:48(url)\n    2   0   0   0.088   0.044   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/key.py:726(url)\n    2   0.001   0   0.088   0.044   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/key.py:1068(_get_url)\n    2   0   0   0.087   0.044   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/boto/s3/key.py:1002(_get_cloudfront_url)\n    1610    0.005   0   0.314   0   /home/my_app/.virtualenvs/my_app/src/django-s3-folder-storage/s3_folder_storage/s3.py:13(url)\n    1610    0.012   0   0.309   0   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/storages/backends/s3boto.py:457(url)\n    690 0.005   0   0.292   0   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/models/fields/utils.py:10(__get__)\n    690 0.007   0   0.251   0   /home/my_app/.virtualenvs/my_app/local/lib/python2.7/site-packages/imagekit/cachefiles/__init__.py:20(__init__)\n    2   0   0   0.248   0.124   \n    >>>> 以下省略,对性能影响较小的调用\n

0