Memcache缓存服务器键值最大值及优化
今天下午升级服务器和程序准备使用Memcache缓存为本地数据库的缓存,希望能减少服务器压力。目前为止,可以看到数据还是比较好的
那么说下,升级到 时候遇到的小细节吧。
首先,就是考虑到Memcache的键最大长度能存储多少?
好吧是的,item最大1M以内,但是我的本地数据最开始是以数组的方式存在的,我呢也想简单粗暴的直接存进去,这怎么办呢?
方法1:分割成若干份每份小于1M开始存储,例如:
$ac = new memcahed(); $data = str_repeat('a', 1024* 1024); //1M的数据 $r = $ac->set('key', $data, 9999);
可是这种方法经过测试,最后转换回来的数据并返回到客户端的时间跟之前没做缓存相差无几,因此放弃了。
方法2:还是按照最开始的想法来,那么就开始查手册吧,发现Memcache好像更新了 ,可以直接使用MEMCACHE_COMPRESSED标记对数据进行压缩,然后开始测试吧
$ac = new memcahe(); $r = $ac->set('key', $data, MEMCACHE_COMPRESSED, 9999);
经过测试,能把100M的文本压缩成100kb 这还是非常可观的。ok直接写代码上传到服务器运行测试,结果显示速度由之前的500+ms 到现在的110ms左右(客户端数据)。
但是,现在还有一个小问题,就是使用Memcache后服务器的上行和下行流量全部暴涨,但是在服务器后台看流量还是正常的,可能是宝塔面板的问题吧 ,这个还需要在研究下。
后记:
因为本地数据使用了memcache做缓存,并且数据每天更新次数也不是很多,所以想到缓存时间直接设置memcache最大时间30天,然后判断本地数据是否更新,如果有更新就自动清除memcache缓存使其更新生效。
有了想法就开始实战吧。首先定义一个 检查本地数据是否更新的函数Demo:
/* 判断文件是否有更新 有更新返回true 否则false 参数1:记录上次更新时间文件 参数2:被检测的文件 */ function fileExists($Record, $databaseFile) { //判断记录时间文件是否存在 if (file_exists($Record)) { //文件存在并判断文件内时间是否有更新 if (file_get_contents($Record) == filemtime($databaseFile)) { //表示文件没有更新 return false; } else { //更新文件时间 file_put_contents($Record, filemtime($databaseFile)); return true; } } else { //第一次记录直接创建文件并写入文件修改时间 file_put_contents($Record, filemtime($databaseFile)); return true; } }
然后在a.php要缓存数据之前调用这个函数,判断文件更新状态,但是经过测试,并发超过100时候大大影响了memcache缓存命中率。
所以这种方法不实用,因此准备在准备一个php文件单独的检测文件更新状态并更新缓存,利用linux定时任务,间隔10分钟自动执行一个php文件来检测来实现这种效果。
准备checkUpdate.php,代码Demo:
//实例化memcache $memcache = new Memcache(); //连接memcache $memcache->connect('127.0.0.1', 11211); //判断文件是否更新 if (fileExists('./fileExists', './a.php')) { $memcache->delete('key'); echo "清除缓存成功!"; }else{ echo "文件未更新,无需清除缓存"; }
当然了,这只是个测试Demo,实际使用中需要判断key来保证不被人恶意使用。
这里是利用了宝塔面板的计划任务,下面是运行日志
重启memcache,重新查看memcache缓存命中率
OK,大功告成。
这里需要说明的是,因为我的缓存的键并不多,因此可以使用这种简单粗暴的方式直接清除缓存,如果你的键特别多的话,还是建议老实的使用缓存失效时间吧
评论