前因
又一次redis 内存爆了,这个但看记录没有发现大问题,通过离线分析数据得出可能是session暴增导致的问题。
过程
找不到就暴力解决,分析redis 数据存储的key的规律,暴力设置过期时间让key 都过期,
看代码吧
//数据量太大没有采用 keys的形式
//尝试了一下网上发的关于laravel scan的用法 包含采用原生的 Redis::command('scan') 都不行,采用稍微原始的类解决了问题
//临时解决可以,还得找到问题的真正原因,我的问题已经找到真正原因了😂
public function handle()
{
//分析session 数据的key的数量
$redis = new \Redis();
$redis->connect(xxxx, 6379);
$redis->auth(xxxx);//此处一定要设置,不然会有问题,我也是排查了一段时间才发现的
$iterator=1018844;
$num=0;
$num1=0;
do{
$res=$redis->scan($iterator, 'laravel_database_laravel_cache:*',100);
if ($res === false) {//迭代结束,未找到匹配pattern的key
dd('done');
}
//dd($res);
foreach ($res as $val){
//获取这个key的到期时间,获取json 里面的token 和 id
$arr_res=unserialize(unserialize($redis->get($val)));
if(is_array($arr_res)){
if(!isset($arr_res['id'])&&isset($arr_res['_token'])){
//设置过期时间
$time=$redis->ttl($val);
if($time>691200){
//dump($arr_res);
$redis->expireAt($val,$this->timeout());
$num++;
}
}
}
$num1++;
//判断符合条件的将过期时间变为 86000-(400-8000)(防止雪崩)
}
info('num==>'.$num.' num1==>'.$num1.' iterator==>'.$iterator);
}while(true);
}
function timeout(){
$now= time()+rand(400,8000)+86000;
return $now;
}
在集群中 scan 会不能遍历所有的key 经测试别的db有 存储占用还很大
那只能离线分析了,将备份的数据导出来进行离线分析 工具 redis-rdb-tools
rdb -c justkeys dump.rdb|uniq >002.txt 我这导出所有的key 用程序一个一个处理
网友评论