Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for using memcached in Rails?

as database transcations in our app are getting more and more time consuming, we have started to use memcached to reduce the amount of queries passed to MySQL.

All in all, it works fine and really saves a lot of time.

But as caching was "silently appearing" as a workaround to give the app more juice, a lot of our models now contain code like this:

def self.all_cached

  Rails.cache.fetch('object_name') {

    find(

      :all,
      :include => [associations])

    }

end

This is getting more and more a pain as filling and flushing the cache happens in several classes accross the application.

Now, I was wondering if there was a better way to abstract memcached logic to make it more powerful and easy to use across all needed models?

I was thinking about having some kind of memcached-module which is included in all needed modules.

But before playing around, I thought: Let's ask experts first :-)

Thanks

Matt

like image 380
Matt Avatar asked May 09 '09 07:05

Matt


People also ask

Is Memcached still used?

Memcached was created in 2003 and written in perl before being rewritten in C. Orginally created for livejournal it became one of the goto stack enhancements of the Web 2.0 era. It's still in use by very large web properties such as Youtube, Reddit, Facebook, Pinterest, Twitter, Wikipedia and more.

Does Memcached support multithreading?

Since Memcached is multithreaded, it can make use of multiple processing cores. This means that you can handle more operations by scaling up compute capacity.

Can memcache be distributed?

Unlike databases that store data on disk or SSDs, Memcached keeps its data in memory. By eliminating the need to access disks, in-memory key-value stores such as Memcached avoid seek time delays and can access data in microseconds. Memcached is also distributed, meaning that it is easy to scale out by adding new nodes.

What is the difference between Redis and Memcached?

Memcached is a distributed memory caching system designed for ease of use and simplicity and is well-suited as a cache or a session store. Redis is an in-memory data structure store that offers a rich set of features. It is useful as a cache, database, message broker, and queue.


2 Answers

I would recommend checking out the existing plugins, the two big ones are cache_fu and cache money. For your use case where you want to load the model with its associations out of cache I would strongly recommend that you try Cache Money, which does it almost automatically:

def parent < ActiveRecord::Base
  has_many children
end

def child < ActiveRecord::Base
  index :parent_id
end

#now you can do the following without ever hitting the DB
parents = Parent.find :all
parents.each{ |p| p.children }

The really big win with Cache Money is that when you scale up to the point where database replication lag becomes an issue, write through caching saves your ass. This is especially important with Rails where replication lag can easily cause 500 errors and generally is a nightmare that you don't want to have.

like image 117
Sam Avatar answered Oct 08 '22 18:10

Sam


Yes, having a memcached module that you include into all the models that you need it in I think is the best solution. Your line of thinking is superb :)

like image 25
Ryan Bigg Avatar answered Oct 08 '22 18:10

Ryan Bigg