我正在使用Redis作为缓存层,我想知道什么是最佳实践,或者如何与DB(在本例中为MySQL)一起正确使用它。
这里有一个用户仪表板功能的示例:
public function updateDashboardUser(Request $request) {
$user = app('redis')->hGetAll($request->userID); //Get data from cache
if ($user) { //if there is data use this
$id = $user['id'];
$name = $user['name'];
} else { //otherwise use this
$user = User::select('id', 'name')->where('id', '=', $request->userID)->first();
$id = $user->id;
$name = $user->name;
}
return response()->json(['id' => $id, 'name' => $name], 200);
}
然而,即使来自缓存的$user
可能为空,也从未以其他方式到达此else语句。有更好的方法吗?
也在更新时...当其中之一的数据发生更改时,有没有更好的方法自动更新(缓存和数据库)。
public function editDashboard(Request $request) {
$user = Route::find($request->userID);
$user->name = $request->name;
$user->save();
$cacheEdit = app('redis')->hSet($user->id, 'name', $request->name);
return response()->json(['status' => '200'], 200);
}
此刻,我这样做,但有时仅其中之一可能会更改,然后缓存数据(反之亦然,DB数据)不会同步/更新。
[这是我对Redis和缓存的首次体验,因此能提供任何帮助。
您应该直接使用Laravel缓存API,而不是直接使用Redis API,它可以进行一些抽象,甚至不需要知道哪个是基础缓存。
通过使用Eloquent而不是查询生成器,您可以解锁一些非常强大的功能,例如模型事件。例如,在您的User
模型中:
protected static function booted()
{
parent::booted();
$cache = app('cache');
static::updated(function ($user) use ($cache) {
$cacheKey = $user->getCacheKey();
if ($cache->has($cacheKey) {
$cache->put($cacheKey, $user, 30); //30 is the life duration of this value in cache, you're free to change it
}
});
static::deleted(function ($user) use ($cache) {
$cache->forget($user->getCacheKey());
});
}
public function getCacheKey()
{
return 'users.' . $this->getKey();
}
[每次使用Eloquent更新或删除User
时,Laravel都会自动调用这些“事件挂钩”。
然后,您可以流畅地执行此操作:
use App\User;
use Illuminate\Http\Request;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Contracts\Cache\Repository as Cache;
public function updateDashboardUser(Request $request, Cache $cache, ResponseFactory $responseFactory)
{
$id = $request->userID;
$user = $cache->remember('users.' . $id, 30, function () use ($id) {
return User::findOrFail($id);
});
return $responseFactory->json($user->only(['id', 'name']), 200);
}
如此处https://laravel.com/docs/7.x/cache#retrieving-items-from-the-cache所述,您可以使用remember
(或rememberForever
)从缓存中检索内容,如果找不到,则自动回退到闭包中。然后findOrFail
将从数据库中检索它,并最终抛出Illuminate\Database\Eloquent\ModelNotFoundException
,因为随后发送成功的响应没有意义。我还通过对合约(Laravel接口)进行依赖注入来替换您的助手,例如response
,这是最干净的做法。