什么是缓存“a”的最佳实践;家庭饲料“;或一个;新闻提要“;在Django

什么是缓存“a”的最佳实践;家庭饲料“;或一个;新闻提要“;在Django,django,caching,django-cache,Django,Caching,Django Cache,我使用Django作为移动前端的API。我只是来回发送JSON。我已经为主提要创建了一个端点。每个用户都有一个唯一的家庭订阅源,这取决于他们跟随的人。用户发布一张照片,然后将该照片推送到所有追随者的主页。到目前为止,非常简单和直接 我的几个同事建议我应该实现某种缓存层,但问题是,这不仅仅是一个静态的常规站点。每个视图都是动态的,取决于访问它的用户 例如,home feed是按描述时间顺序(从最近到旧)发布在平台上的照片列表 home feed视图非常基本。每个用户在Redis中都有一个“home

我使用Django作为移动前端的API。我只是来回发送JSON。我已经为主提要创建了一个端点。每个用户都有一个唯一的家庭订阅源,这取决于他们跟随的人。用户发布一张照片,然后将该照片推送到所有追随者的主页。到目前为止,非常简单和直接

我的几个同事建议我应该实现某种缓存层,但问题是,这不仅仅是一个静态的常规站点。每个视图都是动态的,取决于访问它的用户

例如,home feed是按描述时间顺序(从最近到旧)发布在平台上的照片列表

home feed视图非常基本。每个用户在Redis中都有一个“homefeed:user\u id:%s”列表,其中包含照片对象的主键。我通过Redis调用并获取请求。用户的homefeed列表,然后使用该列表查询数据库中的以下对象:

homefeed_pk_list = redis_server.lrange('homefeed:user_id:%s' % request.user.pk, 0, 100)

# Home feed queryset
queryset = Photo.objects.filter(pk__in = homefeed_pk_list)
response_data= []
for photo in queryset:
       # Code to return back JSON data
return HttpResponse(json.dumps(response_data), content_type="application/json")    

很简单。现在我的问题是,在这种情况下,缓存的最佳实践应该是什么?我可以单独缓存每个序列化的照片对象,并将到期时间设置为24小时,因为一些照片对象位于多个提要中(用户。如果缓存中不存在对象,我将点击数据库。您认为这种方法如何?

为了获得最佳性能,您可以实现类似的功能,其摘要类似于:缓存对象、这些对象的缓存列表、包含该列表的缓存生成页面(也就是说,不要只缓存完成的结果,要一直向下缓存)

但是,以您的示例为例,我可以从以下内容开始:

import hashlib

from django.core.cache import cache
from django.http import HttpResponse

from whereever import redis_server


def feed(request):
    """
    Returns a JSON response containing Photo data.
    """
    # Get the list of PKs from Redis
    photo_pks = redis_server.lrange(
        'homefeed:user_id:%d' % request.user.pk,
        0,
        100
    )

    # Make a SHA1 hash of the PKs (cache key)
    cach_key = hashlib.sha1(unicode(photo_pks)).hexdigest()

    # Get the existing cache
    content = cache.get(cach_key)

    if content is None:
        # Make a queryset of Photos using the PK list
        queryset = Photo.objects.filter(pk__in=photo_pks)

        # Use .values() to get a list of dicts (the response data)
        content = json.dumps(
            queryset.values('pk', 'url', 'spam', 'eggs')
        )

        # Cache the response string for 24 hours
        cache.set(cach_key, content, 60 * 60 * 24)

    return HttpResponse(content, content_type='application/json')

结果是,响应内容将被缓存24小时,或者直到Redis中的PK列表(可能在别处设置,并在添加新照片时更新,等等)因为缓存密钥是使用PK列表的哈希来做的。

我的答案最终是有帮助的吗?谢谢你的快速响应@ Orkuaski。Sh1哈希的要点是生成唯一的随机密钥名称吗?从长度不可预测的较长字符串(我将PK列表转换为字符串)转换为固定长度的e-ish字符串。在列表更改之前,PK的SHA1始终不变。这允许在列表更改之前使用缓存(导致不同的SHA1)。通常,缓存越深,缓存超时越长(例如,您可能会将主页缓存30分钟,因为您知道在数千个请求中,每30分钟只有1个请求会导致查询等。@noa(续)较低级别的缓存(缓存单个照片的属性等)如果每隔半小时左右才请求一次,则可能受益于24小时超时,以确保它有一个有用的寿命(1小时将导致缓存在被删除之前只被读取几次)。如果您有权访问某个对象被更改或删除的点,则可以将其缓存任意长的时间,因为您知道一旦对象被更改,就可以将其从缓存中删除。但是,我的缓存时间不会超过24小时,因为您最终会使用所有RAM。