2012-07-05 68 views
0

我正在谷歌应用程序引擎上使用python和jinja2构建一个web应用程序。我有一个网站,用户可以写文章,我有15个主要类别,每个有4个部门。现在我想实现内存缓存,因为我有一个20:1的阅读器与海报比例,但我怎么能做到这一点,而不需要制作60个不同的键?我应该这样做吗?或者我应该打在数据库和结果进行排序,并且对能使那些结果,像这样的功能的一些参数:如何实现许多类别的memcache

def posts_cache(update = False, category = None, sport = None): 
     key = 'main' 
     posts = memcache.get(key) 
     if posts is None or update: 
       logging.error("DB QUERY") 
       posts = db.GqlQuery("SELECT * " 
             "FROM Post " 
             "ORDER BY created DESC " 
             "LIMIT 100", 
             key) 
       posts = list(posts) 
       memcache.set(key, posts) 
     if category and sport: 
      sportcatlist = [] 
      for post in posts: 
        if post.category == category: 
         if post.sport == sport: 
          sportcatlist.append(post) 
      return sportcatlist 
     elif category: 
      categorylist = [] 
      for post in posts: 
        if post.category == category: 
          categorylist.append(post) 
      return categorylist 
     elif sport: 
      sportlist = [] 
      for post in posts: 
        if post.sport == sport: 
          sportlist.append(post) 
      return sportlist 
     return posts 

或者是有一个更有效的方式来做到这一点?

+0

我不认为你的解决方案会扩展。如果您获得大量帖子,那么您将无法将这些详细信息填充到单个memcache记录中(确定您当前将结果集限制为100)。我认为你应该考虑分割缓存 - 每个分类一次。另外,我觉得你可以通过在创建帖子时为每个类别创建简要记录来提高效率。然后,当您获取这些内容时,将它们缓存在内存缓存中。 (并在更新类别时使缓存无效)。 – 2012-07-06 00:52:07

+0

还算不错,我想我可能不得不在某个时间点头。简要记录是什么意思?在这种情况下他们会持有什么? – clifgray 2012-07-06 04:57:33

+0

那么每次添加帖子时,您都可以更新一个类别记录,该记录包含该类别的最近n个帖子。然后,您可以从缓存中获取前n个文章,如果没有缓存,则使用db.get(category_record键)而不是查询。这意味着您可以在写入而不是查询时进行所有类别的筛选。 – 2012-07-06 07:48:27

回答

1

更有效地做到这一点的一种可能方式是按类别和'post_%s(post_key')分别按预定义的键格式('category_%s(category_name)')分别缓存每个类别的帖子和内容的列表)'。首先包含列表文章的关键字(可能包含一些元信息,如需要的话最后更新日期,第二个 - 按键的帖子内容)在'关键'中,我的意思是序列化的数据存储区密钥或数据存储区中的标识或者其他你可以用来简单地从数据存储中读取文章的内容,如果它不在memcache中分别存储每个特定的文章和类别内容,即使在巨大的负载下也是有效的,包括更新后更新后的单个内存缓存键失效,通过添加/删除文章您使单个类别的列表无效,所有其他memcached数据仍然存在,所以其他请求仅由memcache处理。由于appengine强制限制o n的数据量可以存储在内存缓存中,它会删除旧的和罕见的命中项并保持经常使用,这正是你所需要的,并且完全可以缩放,你描述的方法不会给你这个。 希望它有帮助。