我希望就如何正确使用缓存来加快 Rails 中的时间线查询获得建议。这是背景:
我正在开发一个带有 Rails 后端的 iPhone 应用程序。它是一个社交应用程序,与其他社交应用程序一样,它的主要视图是消息的时间线(即新闻源)。这很像 Twitter,时间线由用户和他/她的追随者的消息组成。API 请求中检索时间线的主要查询如下:
@messages = Message.where("user_id in (?) OR user_id = ?", current_user.followed_users.map(&:id), current_user)
现在这个查询变得非常低效,特别是在规模上,所以我正在研究缓存。以下是我打算做的两件事:
1) 使用 Redis 将时间线缓存为消息 ID 列表
使这个查询如此昂贵的部分原因是确定要即时显示哪些消息。我的计划是继续为每个用户创建一个 Redis 消息 ID 列表。假设我在收到 Timeline API 请求时正确构建了它,我可以调用 Redis 来获取要显示的消息 ID 的预处理有序列表。例如,我可能会得到这样的信息:“[21, 18, 15, 14, 8, 5]”
2) 使用 Memcached 缓存单个消息对象
虽然我相信第一点会有很大帮助,但从数据库中检索单个消息对象仍然存在潜在问题。消息对象可以变得相当大。使用它们,我会返回相关的对象,如评论、喜欢、用户等。理想情况下,我也会缓存这些单独的消息对象。这就是我感到困惑的地方。
如果没有缓存,我会简单地进行这样的查询调用来检索消息对象:
@messages = Message.where("id in (?)", ids_from_redis)
然后我会返回时间线:
respond_with(:messages => @messages.as_json) # includes related likes, comments, user, etc.
现在考虑到我希望利用 Memcache 来检索单个消息对象,看来我需要一次检索一个消息。使用伪代码我在想这样的事情:
ids_from_redis.each do |m|
message = Rails.cache.fetch("message_#{m}") do
Message.find(m).as_json
end
@messages << message
end
这是我的两个具体问题(对不起,冗长的构建):
1)这种方法通常有意义吗(redis 用于列表,memcached 用于对象)?
2)具体来说,在下面的伪代码中,这是唯一的方法吗?一个接一个地抓取消息感觉效率低下,但考虑到我打算进行对象级缓存,我不确定该怎么做。
感谢任何反馈,因为这是我第一次尝试这样的事情。