MST
星途 面试题库

面试题:Ruby on Rails性能优化之缓存策略

描述在Ruby on Rails应用中不同类型缓存(页面缓存、动作缓存、片段缓存)的适用场景和优缺点。如果你的应用需要频繁更新部分页面内容,同时又要保证其他部分的缓存有效性,应该如何设计缓存策略?并举例说明如何在代码中实现这种策略。
24.6万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试

1. 页面缓存(Page Caching)

  • 适用场景:适用于页面内容很少变化的情况,例如静态的营销页面、博客文章等。这些页面的内容在很长时间内保持不变,对所有用户展示相同的内容。
  • 优点
    • 极大提高响应速度,因为整个页面直接从缓存中获取,无需经过Rails应用层的处理。
    • 减轻服务器负载,减少数据库查询和视图渲染的开销。
  • 缺点
    • 缺乏灵活性,只要页面有任何微小变动,整个缓存就需要更新,不适用于动态内容频繁变化的页面。
    • 缓存粒度大,对于不同用户需要个性化展示的页面难以适用。

2. 动作缓存(Action Caching)

  • 适用场景:适用于基于用户请求但内容变化不频繁的页面,比如基于用户角色展示不同内容,但角色对应的内容更新频率低的页面。例如,管理员和普通用户看到不同布局的页面,但管理员和普通用户各自看到的页面内容本身更新不频繁。
  • 优点
    • 比页面缓存更灵活,可以基于请求参数(如不同用户角色)来缓存不同版本的页面。
    • 依然能显著提升响应速度,因为缓存了整个动作的响应,减少了应用层处理。
  • 缺点
    • 缓存粒度还是较大,如果页面内部分内容变化频繁,仍需更新整个动作缓存。
    • 可能存在缓存不一致问题,当数据变化时,需要正确地清除相关缓存。

3. 片段缓存(Fragment Caching)

  • 适用场景:适用于页面中部分内容更新频繁,而其他部分相对稳定的情况。例如电商网站产品详情页,产品基本信息更新少,但实时库存和价格等信息更新频繁。
  • 优点
    • 缓存粒度小,可以精准控制页面中哪些部分需要缓存,哪些部分实时更新。
    • 灵活性高,适合复杂动态页面,只更新变化的片段,不影响其他缓存内容。
  • 缺点
    • 管理复杂度增加,需要仔细规划哪些片段需要缓存,以及何时更新缓存。
    • 相比页面和动作缓存,缓存命中率可能稍低,因为每次请求都要判断多个片段缓存情况。

4. 缓存策略设计

  • 对于需要频繁更新部分页面内容,同时保证其他部分缓存有效性的应用,应主要采用片段缓存策略。把稳定不变的内容片段进行缓存,而频繁更新的内容不缓存或采用较短的缓存时间。例如,在一个新闻网站中,文章主体部分更新频率低,可以缓存;而文章下方的实时评论数量等信息更新频繁,不进行缓存或设置短缓存时间。

5. 代码实现示例

假设我们有一个 products/show.html.erb 视图,产品基本信息稳定,库存实时更新。

在视图文件中:

<div class="product-info">
  <% cache @product do %>
    <h1><%= @product.title %></h1>
    <p><%= @product.description %></p>
    <!-- 其他稳定的产品信息 -->
  <% end %>
</div>
<div class="product-stock">
  <p>库存: <%= @product.stock_count %> </p> <!-- 不缓存实时库存 -->
</div>

在控制器 products_controller.rb 中:

class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])
  end
end

这样,产品基本信息部分会被缓存,而库存部分实时获取最新数据,不会因缓存导致数据过时。