cache_fu 好用, 不过我有很多表间关联,我希望某些表的数据,通过关联(has_one,has_many)能够按id统一从memcache中读取或者写入. 该如何呢?
唯一的办法就是 monkey patch了,自己写吧.
第一个版本
require 'active_record/associations/belongs_to_association'
require 'active_record/associations/has_many_association'
module ActiveRecord
class Base
public
def self.has_one_cached *params
has_one *params # call the standard association
assoc_name = params[0]
define_method ("#{assoc_name}_with_cache") do
assoc = self.class.reflections[assoc_name.to_sym]
instance_values[assoc_name.to_s] ||
(assoc.klass.get_cache(instance_values["#{assoc_name}_cached_id"]) if instance_values["#{assoc_name}_cached_id"] ) ||
(a = HasOneAssociation.new(self, assoc)
assoc.klass.get_cache(a.id)
self.instance_variable_set("@#{assoc_name}_cached_id", a.id)
self.instance_variable_set("@#{assoc_name}", a)
)
end
# switch out the method. has_one -> has_one_with_cache
alias_method_chain assoc_name, :cache
end
end
end
代码解释下,捡重要的说吧
1-7行,可以忽略
8 增加一个 has_one_cache的方法,使用起来等同于 has_one
17-23行的三个 "||"
第一个,就是读取AR中的缓存数据,这个没啥说的
第二个"||",是根据instance中保存的instance_values["#{assoc_name}_cached_id"]从memcache中获取对应的数据
第三个"||",就是第一次运行的时候,保存一个cache_id的变量和值,和对AR对象中缓存进行赋值
所以这里实际上是三级的缓存读取方式,先对象缓存,再memcache,如果还没有就直接读取数据库.
不过这里有个很明显的缺陷.要求instance长期存在,这个代码才能起作用.不过rails中对象的生命周期仅限于action,超出这个就没有啥用了.所以上面的代码,到头来只能在偶尔的情况下才能真正的用到memcache
解决办法是有,不过看各位是否喜欢的问题,就是把id也保存到memcache中.呵呵,很土的没有办法的办法.
于是上面的方法就改成了
define_method ("#{assoc_name}_with_cache") do
assoc = self.class.reflections[assoc_name.to_sym]
instance_values[assoc_name.to_s] ||
(assoc.klass.get_cache(instance_values["#{assoc_name}_cached_id"]) if instance_values["#{assoc_name}_cached_id"] ) ||
(id = assoc.klass.get_cache_ex("#{self.class.to_s}:#{self.id}:#{assoc_name}")
assoc.klass.get_cache(id) if id)||
(a = HasOneAssociation.new(self, assoc)
assoc.klass.get_cache(a.id)
assoc.klass.set_to_cache("#{self.class.to_s}:#{self.id}:#{assoc_name}",a.id,assoc.klass.ttl)
self.instance_variable_set("@#{assoc_name}_cached_id", a.id)
self.instance_variable_set("@#{assoc_name}", a)
)
end
增加了一个"||"
(id = assoc.klass.get_cache_ex("#{self.class.to_s}:#{self.id}:#{assoc_name}")
assoc.klass.get_cache(id) if id)
先用memcache中获取id数据,在获取对应的纪录,很囧吧.
不过要看应用场合的,如果你需要访问的数据属于基础数据,永远不变的,或者长期不变的数据,这样的办法能够减轻数据库的访问负担,但是要注意的是"这样的方法不会比直接访问数据库要快"
这里重申下memcache的作用:
"memcache不会使得你的网站访问速度更快,只是为了减轻数据库的访问负担"
另外顺便提下,cache_fu中没有get_cache_ex的函数.这个函数是在robbin的提示下加进来,专门用于非id key的memcache数据读写的.
代码如下
def get_cache_ex(key, timeout = 60 * 30)
reset = cache_reset
data = get_from_cache(key) unless reset
return data unless data.nil?
if block_given?
if data = yield
test = true
if data.instance_of? Array
test = false if data.size ==0
end
set_to_cache(key, data, timeout) if test
end
return data
end
end
还有,我这里的代码是参考http://groups.google.com/group/acts_as_cached/browse_thread/thread/5fefb2d2355a5048/25ea72ecd0d5a0c9
这个thread写的.
如果有has_many, belongs_to 的需求,还是参考google groups上的帖子来改写吧.
最后感谢下robbin的自动保存功能,真是救命功能阿
分享到:
相关推荐
Windows_Memcache安装(XAMPP+Memcache+PHP) 安装步骤,详细说明
$memcache = new Memcache; $memcache->connect("localhost",11211); echo "Server's version: " . $memcache->getVersion() . "\n"; $tmp_object = new stdClass; $tmp_object->str_attr = "test"; $tmp_object->...
Memcached.exe服务器端安装 php_memcache.dll客户端 extension=php_memcache.dll
这个模块是平和php5.3的,在我的windowsxp php5.3.5上安装成功 里面有两个php库,一个php_memcache.dll.vc6 和一个php_memcache.dll.vc9 另外一个windows的memcache.exe文件,都是网上收集的,因为现在要找齐很不容易,...
php_memcache.dll php_memcache.dll php_memcache.dll php_memcache.dll
通过expect 实现自动登陆远程linux服务器安装 nginx php mysql memcache xcache chkrootkit 等软件
wampserver2.4 64位集成包的php_memcache扩展库,在window8.1 64位系统下测试可以正常使用。
php_memcache.dll
$memcache = new Memcache; $memcache->connect("localhost",11211); echo "Server's version: " . $memcache->getVersion() . "\n"; $tmp_object = new stdClass; $tmp_object->str_attr = "test"; $tmp_...
php5.4常用dll扩展文件 php_redis.dll php_memcache.dll php_mongo.dll
测试环境 php7.1.11 ts vc14 x64 ,直接放到php安装目录的ext文件夹下 即可
php5.4 php_memcache.dll;memcached window64位
之后,在php.ini中加入配置 extension=php_memcache.dll和 [Memcache] memcache.allow_failover = 1 memcache.max_failover_attempts=20 memcache.chunk_size =8192 memcache.default_port = 11211
windows下的memcache服务,在windows平台下搭建wamp或者php环境的时候,如果没有memcache服务,会报错找不到memcache()方法,下载并解压这个压缩包,将memcache.exe放到任意位置,然后使用管理员权限在命令行转到...
PHP 添加 Memcache 扩展 : 下载包中包括如下: php_memcache-3.0.8-5.5-nts-vc11-x64.zip php_memcache-3.0.8-5.5-nts-vc11-x86.zip ...在 php.ini 中添加 extension=php_memcache.dll, 重启Apache服务器
php5.3.8下载内含php5apache2_2.dll,php_memcache.dll,php_xdebug.dll vc9版本配合apache2.2版本 根据自己的情况来配置php.ini文件
Erlang_Memcache
php-7.2.x_memcache_winx64。最新版memcache支持库。2018-03-28 MSVC 15.6.4 / 19.13.26129 - Window Kit 10.0.16299.0 - Compiled with: PHP 7.2.4
php_memcache-5.2 5.3 5.4