about 4 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

  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秒完成動作,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.

  5. Completed 200 OK in 110ms (Views: 65.6ms | ActiveRecord: 19.7ms)
    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

  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.

  10. I don't cache anything unless I'm not meeting my MAART.

這樣就cache todo了:

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


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

Russian Doll Caching:

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


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


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.


<% 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.

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?

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.

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.
不加cache打的就是資料庫,所以當然很多台server就需要有cache server,但太早架是沒有意義的。

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