- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我希望获得有关正确使用缓存以加速 Rails 中的时间线查询的建议。这是背景:
我正在开发一个带有 Rails 后端的 iPhone 应用程序。这是一个社交应用程序,与其他社交应用程序一样,它的主要 View 是消息的时间线(即新闻源)。这与 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) 具体来说,在下面的伪代码中,这是唯一的方法吗?一条一条地抓取消息感觉效率很低,但考虑到我打算进行对象级缓存,我不确定还能怎么做。
感谢任何反馈,因为这是我第一次尝试这样的事情。
最佳答案
从表面上看,这似乎是合理的。 Redis 非常适合存储列表等,可以持久化等,memcached 检索单个消息的速度非常快,即使您像那样顺序调用它也是如此。
这里的问题是每次发布消息时您都需要清除/补充 redis 缓存。在这种情况下只清除缓存似乎有点浪费,因为您已经麻烦地识别邮件的每个收件人。
因此,在不希望回答错误问题的情况下,您是否考虑过在发布每条消息时将消息的可见性“呈现”到数据库(或 Redis,就此而言)?像这样:
class Message
belongs_to :sender
has_many :visibilities
before_create :render_visibility
sender.followers.each do |follower|
visibilities.build(:user => follower)
end
def
end
然后您可以非常简单地呈现消息列表:
class User
has_many :visibilities
has_many :messages, :through => :visibilities
end
# in your timeline view:
<%= current_user.messages.each { |message| render message } %>
然后我会像这样添加单独的消息:
# In your message partial, caching individual rendered messages:
<%= cache(message) do %>
<!-- render your message here -->
<% end %>
然后我还会像这样添加整个时间线的缓存:
# In your timeline view
<%= cache("timeline-for-#{current_user}-#{current_user.messages.last.cache_key}") do %>
<%= current_user.messages.each { |message| render message } %>
<% end %>
这应该实现的(我没有测试过)是整个时间轴 HTML 将被缓存,直到发布新消息。发生这种情况时,时间线将重新呈现,但所有单独的消息都将来自缓存而不是再次呈现(除了任何其他人未查看的任何新消息可能异常(exception)!)
请注意,这假设消息呈现对于每个用户都是相同的。如果不是,您还需要缓存每个用户的消息,这会有点遗憾,所以如果可以,请尽量不要这样做!
FWIW,我相信这就是 Twitter 所做的模糊(我的意思是模糊)。不过,他们有一种“大数据”方法,推文被分解并插入到大型机器集群的关注者时间线中。我在这里描述的内容将难以在拥有大量追随者的写入密集型环境中扩展,尽管您可以通过使用 resque 或类似工具来稍微改善这一点。
附言我对这里的代码有点懒惰——你应该考虑重构它来移动,例如将时间轴缓存 key 生成到助手和/或人员模型中。
关于ruby-on-rails - 使用缓存优化 Rails 中的时间线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14206376/
sanitize 是什么意思在 Rails 中是什么意思? 我正在阅读 CanCanCan 的文档.它说: When using strong_parameters or Rails 4+, you
在过去的几个月里,我感觉自己对 Ruby on Rails (RoR) 开发的了解达到了极限。我为大/小客户和 friend /爱好项目开发了大大小小的应用程序。我知道如何开发这些应用程序,但开始感觉
我昨天参加了一个关于扩展 Rails 的聚会,其中一个主题是 Hexagonal Rails。然而,我只做了一年的 Rails,对 MVC 结构非常满意(也许太舒服了),所以我不太了解适配器和消息队列
我使用多个 Rails 应用程序,一些在 Rails 3.2/Ruby 2.0 上,一些在 Rails 2.3/Ruby 1.8.7 上。 他们的共同点是,随着他们的成长和添加更多的依赖项/ gem
这个问题在这里已经有了答案: Using Rails-UJS in JS modules (Rails 6 with webpacker) (5 个答案) 关闭 3 年前。 我正在尝试使用 UJS
我正在开发一个当前使用 Rails 1.2 的 Rails 应用程序,所以我现在离最新的稳定版本(Rails 2.3)还有很长的路要走。 我应该如何进行迁移到更新版本的 Rails 的过程? 我应该一
尝试按照 Ryan Bates Backbone.js 教程构建抽奖应用程序,但我已经遇到了第一段代码的问题。在 application.js 的 init 函数中,他初始化了 Raffler 路由的
我正在使用 Rails 3.2 并且我有一个数据库表,我想在其中找到符合以下条件的所有行: a = true and b = true and ( 0 true, :b =>
我有一个用户类和一个联系人,其中联系人是用户的子类。这两个类都存储在用户表中。 我的联系人可能有也可能没有电子邮件地址,而我的用户需要一个电子邮件地址(我的用户模型定义中有 validates_pre
我正在编写一个教程,我在其中演示了一些 rails 命令。在我的机器上 rails和 script/rails两者都同样有效。有“首选”形式吗?两者中哪一个更普遍? 最佳答案 当您运行 rails 时
我正在寻找有关通过我的应用程序前进的最佳方式的建议,这是我首次开始集成Elasticsearch。我是一名初学者,但是热衷于深入研究,以便原谅任何明显的错误! 我遵循了http://www.sitep
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我有 Rails 4,这是我的默认版本(我仍然希望它是)。但我不想在我的电脑上添加 rails 3.2。在以下命令中:gem install rails -v 3.2.16 我有这个警告: railt
您好,我想使用 Sheevaplug 构建一个“Rails Brick”来自 Marvell(操作系统是开箱即用的 Ubuntu,但您可以在其上安装其他发行版)。它将成为家庭服务器和静音、低成本(99
我需要能够从 Rails 控制台发送我的 Rails 应用程序的 Postgres 数据库中所有未接受的邀请。 (我有一个名为 Invitations 的表,其中包含一个名为 accepted 的 b
validate :cannot_modify_if_locked, on: :update def cannot_modify_if_locked if self.locked erro
我正在学习教程(学习 Rails 播客),需要更改以下路由语法,以便它与 Rails 3.0 兼容。谁能帮忙? map.view_page ':name', :controller => 'viewe
我是一名优秀的程序员,十分优秀!