上篇文章有讲解Sphinx进行合并请求优化,将多次请求合并为一次请求,最终处理时间和单词请求时间一样。
大多数我们通过Sphinx都是搜索数据,拿到的应该都是作品ID,然后再通过拿到的ID去数据库进行查询,获取作品的相关信息,这里的话我们就要进行缓存的获取与生成,也就是进行文章的主题,单作品数据缓存,也就是数据的原子性
以小说为例,在小说系统中其实都是展示小说的信息:小说首页推荐位、搜索结果列表、猜你喜欢列表、分类页列表等部分;
这些地方无非都是展示小说的封面、名称、描述、作者等信息,我们想要实现的就是这些地方的作品信息最终通过一个方法就能够调用获取出来,其实就是这些位置我们拿到小说的是IDS,然后传递给该方法,返回的就是上述作品的信息。
该方法中,如果作品Redis中有缓存数据,就直接获取;如果没有缓存信息,记录当前小说ID,等全部查询完成后,再去数据库里面进行查询,将获取到的每个作品的信息缓存起来,再次获取的话就是充缓存中获取。
注意:关于数据Redis存储和获取 需要通过Lua脚本一次获取,而不是循环生成缓存依次获取,大概操作流程如下代码所示:
/**
* 获取小说数据信息
*/
public function getBookInfo($ids) {
// 获取作品redisKey
$redisKeys = [];
foreach($ids as $id) {
array_push($redisKeys, "book:info:{$id}");
}
// 获取缓存数据
$redisData = Redis::hmGet($redisKeys); // Lua脚本获取数据
$data = [];
foreach($redisData as $info) {
if (!empty($info)) {
array_push($existData, $info);
}
}
// 查询未缓存数据,并进行缓存处理
if (count($data) != count($ids)) {
$noExistIds = array_diff(array_column($data, 'id'), $ids);
$infos = Book::whereIn('id', $noExistIds)->get()->toArray();
$setRedisKeys = $setRedisValues = [];
foreach($infos as $info) {
// 缓存key
array_push($setRedisKeys, "book:info:{$info['id']}");
// 此处将能用到关于作品的信息全部缓存到对应的缓存key中
array_push($setRedisValues, [
'id' => $info['id'],
'name' => $info['name'],
'author' => $info['author'],
'cover_url' => $info['cover_url']
]);
}
Redis::hmSet($setRedisKeys); // Lua脚本缓存数据
// 合并数据
$data = array_merge($data, $setRedisValues);
}
return $data;
}