Rails可能很多人诟病的就是性能问题,所以很多人想出来了改善方法,其中dalli这个gem就是通过memcache来改善的。
地址
https://github.com/mperham/dalli 使用这个gem必须保证安装了memcached
什么数据适合存入cache呢?
一般情况下,数据库里面不怎么改变的数据,并且使用的地方比较多的话是非常适合存入cache的。例如:一个国家的所有省份。
举个例子说明下:
1 2 3 4 5 6 7 |
|
如果想取得一个grade所有skills非常简单如下:
1 2 |
|
现在每次取一个grade的skills都会访问数据库,可以考虑把skill放到cache里面去了。
1 2 3 4 5 |
|
所以我们取skills的话可以通过下面方式取出来
1
|
|
这个过程是什么样的呢?当第一次访问的时候,会去访问数据库然后把数据存入到memcached里面去,下次访问的话就直接从cache里面取了,不再访问数据库了。
- [self.class.name, id, :skills] 这是存储的key
- cache将会在240小时后过期
- 如果不转化成数组(to_a)直接将active-record的relations存储到cache的话,每次访问cache这个relations还是会查询数据库的,所以大家务必要注意。
让cache过期
如果某个grade的skills改变了,而grade又没有收到通知,这时候从cache中取出来的将是旧的数据,这个时候我们需要让cache里面这个grade过期或者删除掉
一种方法使用after_commit
在Skill的model里面加上
1 2 3 4 5 6 |
|
这个方法可以保证cache里面的数据都是最新的。
第二种方法是通过改变key和加入touch关键字
model定义如下:
1 2 3 4 5 6 7 |
|
touch什么意思呢?如果skill更新的话,也会更新grade的updated_at字段
这时候将cached_skills方法修改成下面的:
1 2 3 4 5 |
|
这样的话如果skill发生改变的话,因为把updated_at作为key了,所以从cache里面取的永远是最新的skills。
但这种方法有如下缺点,使用的时候需要小心:
在这种情况下,如果topic改变也会更新grade的updated_at,这样的话,也会影响skills,cache的效果就不明显了。 上面的2种cache过期方法,大家根据实际情况自行选择。
总结
这个gem可以帮助我们减少很多数据库访问,极大的提高性能。大家使用的时候,务必注意cache里面数据保持更新的问题,不然引起很多因为旧数据引起的bug就不太好了。