线上Redis流量优化经历全过程,一点点的小改动,流量下降500%
简要说明:#
1、阿里云 Redis 服务。
2、32G 内存,100M 带宽。
3、Redis 的 Get 请求频率大约 5000 次 /s。
4、Redis 的 Key 总量约 2000 万。
原因:#
高峰期已过,阿里云钉钉群每天至少有一次流量报警,有时更多。
处理方法:#
1、阿里云离线全量 Key 分析数据。#
1)第一步分析大 Key,大部分是集合,找代码没有发现取全量。
2)第二步按 KEY 占用大小倒序,找到部分频率高,且 KEY 值较大键值优化。主要是减小本身 key 值的大小。(优化后没有效果,有些时候可以解决问题)
2、通过 monitor 实时命令分析。#
1)第一步把 Redis 在 5 秒内执行的 GET 打印到文件(时间再长就有点多),进行筛选,没有找到原因,执行命令如下。
redis-cli -h 主机名 -p 6379 -a 密码 monitor |grep "GET" > /tmp/temp-1.log
2)第二步把导出数据放在 Excel 分析,抽取数据中某一秒的所有数据(要取中间, 不要取最前面和最后面的),肉眼寻找可能有问题的 KEY 进行优化。(问题仍未解决)
3)第三步在分析第二步时,发现有些 Key 已过期,Get 不到数据。
4)第四步写一个直接分析 monitor 日志脚本,并打印所有 Key 大小。
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$file = "/tmp/monitor-2.log";
$totalLen = $this->fileHandel($file);
echo "完成 总大小:" . $totalLen . "\r\n";
return 0;
}
/**
* 根据文件获取
*/
public function fileHandel($fileURL)
{
$handle = fopen($fileURL, "r");
$totalLen = 0;
if ($handle) {
while (($line = fgets($handle)) !== false) {
// 处理每一行
preg_match('/\[([0-9]+)[\s\S]+GET[\s\S]+"([^"]+)"/i', $line, $arr);
if (count($arr) != 3) {
echo "错误";
} else {
$len = $this->getLen($arr[2], $arr[1]);
$totalLen += $len;
echo $len . " " . $arr[2] . " " . $arr[1] . "\r\n";
}
}
fclose($handle);
} else {
echo "无法打开文件";
}
return $totalLen;
}
private function getLen($key, $dbSelect)
{
//去掉前缀
$key1 = (string)str_replace("redis端缀", "", $key);
//设置库名
Redis::select($dbSelect);
//查询大小
$len = Redis::strlen($key1);
return $len;
}
5)第五步根据 Key 大小再筛选,然后再看看 1 秒内执行的次数,最终发现了问题。
6)最后优化代码
// 新代码
$key = \getRedisKey('qSubjectList') . implode("", $ids);
$fields = [ 'id', 'name' ];
$list = Cache::remember($key, TTL::TTL_DAY_RAND(), function () use ($fields, $ids) {
return self::query()->where('status', self::STATUS_ON)
->select($fields)
->whereIn("id", $ids)
->get()->toArray();
}) ?? [];
return collect($list)->whereIn('id', $ids);
// 旧代码,需要优化
// $list = self::getCacheList();
// return collect($list)->whereIn('id', $ids);
7)更改代码后,实际效果如图:
总结:#
1、最难的问题是怎么找到这个 Key,为了找这个 Key 花费了不少时间。
2、最主要问题还是代码质量,所以大家写代码时一定按需取字段,且记不可以把所有数据存在一个 Key,而是按唯一性存储(后台有时候方便,可以使用)。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: