about 3 years ago

原文: Speed Up Your Rails App by 66% - The Complete Guide to Rails Caching

  1. Performance never really becomes a priority until the app is basically in flames
    效能從不被認為是重要的事,直到它爆掉為止XD(透過量測數據來告訴大家它的重要性)

  2. 1 second from the instant the user clicked or interacted with the site until that interaction is complete (the DOM finishes painting).
    In order to consistently achieve a 1 second to glass webpage, server responses should be kept below 300ms.
    1秒內完成動作是使用者可接受的(50ms的網路延遲,150ms載入你的js和css,250ms執行你的js)
    為了達成1秒完成動作,server response必須控制在300ms內

  3. ignore action caching and page caching.
    用fragment caching就可以了.

  4. rack-mini-profiler provides an excellent line-by-line breakdown of where exactly all the time goes during a particular server response.
    rack-mini-profiler提供逐行的server的回應時間

  5. Completed 200 OK in 110ms (Views: 65.6ms | ActiveRecord: 19.7ms)
    110ms是總時間
    65.6ms是 render和activeRecord lazy load的時間(ActiveRecord::Relations 會在render View時才執行)
    19.7ms只是query db的時間

  6. get a millisecond-by-millisecond breakdown of exactly where your time goes during a request, you'll need rack-mini-profiler and the flamegraph extension
    flamegraph也不錯用

  7. I suggest setting a maximum acceptable average response time, or MAART, for your site.
    設定最大可接受的回應時間目標,而且要設兩個(一個是for production的,一個是for developer的)

  8. apache bench(ab) ab -t 10 -c 10 http://localhost:3000/
    t是設時間 c是Concurrency

  9. I usually test with at least -c 2 to flush out any weird threading/concurrency errors I might have accidentally committed.
    同時發兩個resequres來看看concurrency的問題。

  10. I don't cache anything unless I'm not meeting my MAART.
    server夠快就別做cache了.

這樣就cache todo了:

<% todo = Todo.first %>
<% cache(todo) %>
  ... a whole lot of work here ...
<% end %>

可以針對目前登入的user作cache:

<% todo = Todo.first %>
<% cache([current_user, todo]) %>
  ... a whole lot of work here ...
<% end %>

Russian Doll Caching:

<% cache('todo_list') %>
  <ul>
    <% @todos.each do |todo| %>
      <% cache(todo) do %>
        <li class="todo"><%= todo.description %></li>
      <% end %>
    <% end %>
  </ul>
<% end %>

這樣做比較好(todo.updated_at有更新再更新cache)

<% cache(["todo_list", @todos.map(&:id), @todos.maximum(:updated_at)]) %>
  <ul>
    <% @todos.each do |todo| %>
      <% cache(todo) do %>
        <li class="todo"><%= todo.description %></li>
      <% end %>
    <% end %>
  </ul>
<% end %>

11.子資料更新時也更新父資料的updated_at

belongs_to :father, touch: true

if we call @brake.car.save, our two outer caches will expire (because their updated_at values changed) but the inner cache (for @brake) will be untouched and reused.

brake.car資料更新時,只有brake.car.corporation和brake.car會更新,原本brake的cache仍然在

<% cache @brake.car.corporation %>
  Corporation: <%= @brake.car.corporation.name %>
  <% cache @brake.car %>
    Car: <%= @brake.car.name %>
    <% cache @brake %>
      Brake system: <%= @brake.name %>
    <% end %>
  <% end %>
<% end %>

12.ActiveSupport::FileStore not an LRU cache
FileStore expires entries from the cache based on the time they were written to the cache, not the last time they were recently used/accessed.
FileStore根據上次資料寫入的時間排序,而不是上次的使用時間(LRU),所以會慢慢的滿出來,很吃空間

13.ActiveSupport::MemoryStore If you have one or two servers, with a few workers each, and you're storing very small amounts of cached data (<20MB)
如果你cache的資料小於20mb 它用起來還ok.再大就別用它了.

14.Memcache? If you're running more than 1-2 hosts, you should be using a distributed cache store. Cache values are limited to 1MB?
(?)它cache的value和key限制1mb和250bytes嗎?

15.Redis? If you're running more than 2 servers or processes, I recommend using Redis as your cache store. In addition to redis-store, there's a new Redis cache gem on the block: readthis. It's under active development and looks promising.
建議用readthis這個gem,不要用redis-store,它只能存string

16.LRURedux? Use LRURedux where algorithms require a performant (and large enough to the point where a Hash could grow too large) cache to function.
很快,但不支援Rails cache store.

17.Speed: LruRedux > MemoryStore > FileStore > DalliStore > RedisStore
很需要速度的用LruRedux, 小東西用MemoryStore, 作者偏好Redis(我偏好memcached).

18.When using a remote, distributed cache, figure out how long it actually takes to read from the cache.
用memcached和redis在remote環境的時間,測一下是不是真的有加比較快,網路延遲是個問題。
不加cache打的就是資料庫,所以當然很多台server就需要有cache server,但太早架是沒有意義的。

← RubyGems 如何運作? React Redux架構摘要 →
 
comments powered by Disqus