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
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.
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.
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.
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.
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.
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With