· 6 years ago · Sep 07, 2019, 12:08 AM
1### Memcached
2* **In-memory** key-value store that is used to speed up a Rails app by caching the results of
3database calls, API calls or page rendering
4---
5### Rails Integration
6* `brew install memcached` and start up manually `/usr/local/bin/memcached`
7* Make sure to add `gem 'dalli`, then `bundle install`
8---
9* Check memcached version, enter in terminal: `memcached -h | head -1`
10* To have launchd start memcached now and restart at login `brew services start memcached`
11* If you don't want/need a background service you can just run `/usr/local/opt/memcached/bin/memcached`
12---
13* In **production** -> `config/environments/production.rb`:
14```ruby
15config.cache_store = :mem_cache_store,
16 (ENV["MEMCACHIER_SERVERS"] || "").split(","),
17 {:username => ENV["MEMCACHIER_USERNAME"],
18 :password => ENV["MEMCACHIER_PASSWORD"],
19 :failover => true,
20 :socket_timeout => 1.5,
21 :socket_failure_delay => 0.2,
22 :down_retry_delay => 60
23 }
24```
25* In **development** -> `config/environments/development.rb`:
26```ruby
27config.action_controller.perform_caching = true
28config.cache_store = :dalli_store
29```
30* Difference between `:mem_cache_store` and `:dalli_store`?
31 * They are both memcached adapters
32 * `:mem_cache_store` is provided by Rails ActiveSupport, that requires the `dalli` gem and
33 provides a cache store implementation that wraps `Dalli::Client`
34 * `:dalli_store` is provided by the `dalli` gem
35 * Both perform the same functionality
36* The index action makes a call to your db to get all records to display them on your page.
37* You can use memcached to cache the records so your db won't have to re-query for them.
38* In your model, create a method, for example:
39```ruby
40def self.all_cached
41 Rails.cache.fetch('Contact.all') { all.to_a }
42 # fetches a key named 'Contact.all' with a value of an array of all contact records
43end
44```
45* In your, controller: `@contacts = Contact.all_cached` for your index action
46* Use `@stats = Rails.cache.stats.first.last`
47 * call in your views `<%= @stats['get_hits'] %>`
48 * call in your views `<%= @stats['get_misses'] %>`
49* If records are added, you will need to **expire the cache**
50* Create callbacks in your model for `after_save` and `after_destroy` where you perform `Rails.cache.delete('Contact.all')`
51* Allow rails to fetch and expire cache for you, in `config/environments/production.rb`:
52 * `config.action_controller.perform_caching = true`
53 * This enables you to perform fragment, action and page caching.
54---
55### Fragment Caching
56* Cache parts of your code, for example if there is a contact section that loops through contacts
57```ruby
58<% @contacts.each do |c| %>
59 <% cache contact do %>
60 # code
61 <% end %>
62<% end %>
63```
64---
65### Page and Action Caching
66* Rails can also cache whole page with page and action caching.
67* Page caching is more efficient: allows you to bypass the Rails stack but it does not work with pages with
68before_filters (such as authentication)
69* To use action caching:
70 * add `gem 'actionpack-action_caching'` to your gemfile, then `bundle install`
71 * To start caching the results of the `show` action, for example: `caches_action :show` above all actions in your controller
72 * For proper expiration, when you `update` or `delete` a resource, within these actions: `expire_action :action => :show`
73---
74### Session Caching
75* Caching session storage, in `config/initializers/session_store.rb`: `Rails.application.config.session_store :cache_store, key: '_memcache-example_session`
76* Asset caching is done with