Oct
29
yii framework cache 深坑
用框架的cache时发现,command和controller设置的cache互相之间居然是独立的,对于CFileCache,通过grep可以在 app/runtime/cache 下面看到,相同的key在两边set以后,会存在两个不同的文件里面:显然是在hash得到cache key的时候用了一个额外的串。
没办法,只能去翻Yii的源码,在 framework/cache/CCache.php 可以看到get/set方法是调用了 generateUniqueKey 来生成cache key;该方法用到的keyPrefix 是取值于 "Yii::app()->getId()" 。追过去,在 framework/base/CApplication.php 里面可以看到,这个getId()的实现是"crc32($this->getBasePath().$this->name)"。
于是去看了一下,果然 config 下面 main.php 和 console.php 配置的 name 不同,所以框架把它们认为是两个project。改成一样,就解决了。
但是……
还有一个隐藏得更深的坑:
缓存文件(例如runtime/cache/04/51/045113ce863440795dab03b29a4ec384.bin)里的内容是这样的:
也就是说,这个缓存在遇到两个md5相同的key时,无法做出区分!
这个只能看命了。
UPDATE:
缓存冲突问题,虽然不能彻底解决,但是可以通过简单的包装,把原先set的value换成 {'key': ..., 'value': value}, 然后在get的时候检查一下是否匹配,不匹配的话简单丢弃,这样至少不会遇到莫名其妙的BUG。
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
没办法,只能去翻Yii的源码,在 framework/cache/CCache.php 可以看到get/set方法是调用了 generateUniqueKey 来生成cache key;该方法用到的keyPrefix 是取值于 "Yii::app()->getId()" 。追过去,在 framework/base/CApplication.php 里面可以看到,这个getId()的实现是"crc32($this->getBasePath().$this->name)"。
于是去看了一下,果然 config 下面 main.php 和 console.php 配置的 name 不同,所以框架把它们认为是两个project。改成一样,就解决了。
但是……
还有一个隐藏得更深的坑:
缓存文件(例如runtime/cache/04/51/045113ce863440795dab03b29a4ec384.bin)里的内容是这样的:
引用
a:2:{i:0;s:26:"2015-10-29 18:28:03command";i:1;N;}
也就是说,这个缓存在遇到两个md5相同的key时,无法做出区分!
这个只能看命了。
UPDATE:
缓存冲突问题,虽然不能彻底解决,但是可以通过简单的包装,把原先set的value换成 {'key': ..., 'value': value}, 然后在get的时候检查一下是否匹配,不匹配的话简单丢弃,这样至少不会遇到莫名其妙的BUG。
欢迎扫码关注:
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
ctqmumu
2015-11-2 15:49
框架自带的功能一般都有点边边角角的问题... 比较好的解决方案可能是自己另写一个cache了..
lovelucy
2015-10-29 20:19
用 Yii2 吧………
felix021 回复于 2015-10-30 10:45
公司项目,不是我想换就能换的。。
分页: 1/1 1