一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
缓存简介
- 缓存在现在的Web系统中应用广泛,缓存主要可以帮助我们提升系统的吞吐量。
- 现在成熟的缓存系统,一般使用Redis或者内存缓存来保障我们Web系统的稳定。缓存有多种分类,下面是我在后端实际开发中常用的缓存伪码,分享给你。
缓存的适用场景
- 数据实时性要求不高。读多写少,比如常见的网站内容缓存。
- 高并发场景,用来提升系统的吞吐量。
缓存key设计原则
-
任何变量的命名都应该有规则,key的命名要有意义 建议采用的规范是 groupName:projectName:xxx:xxx
-
每一个key要设置过期时间,提升空间利用率。
读缓存
function getData($key) {
$data = $cache->get($key);
if (!empty($data)) {
return $data;
}
$data = getDataFromDb($key);
$cache->set($key, $data, $expierTime);
return $data;
}
写缓存
function setData($key, $data) {
try {
$result = $db->update($data);
if ($result) {
$cache->delete($key);
}
} catch (Exception $e) {
// todo 异常处理
}
}
高并发场景的缓存设计
读缓存
- 对于每次数据库都查不到的数据,存在缓存穿透的现象。 即使DB返回的结果为空,我们也设置一个默认值的缓存。
function getData($key) {
$data = $cache->get($key);
if (!empty($data)) {
return $data;
}
$data = getDataFromDb($key);
if (empty($data)) {
// 设置默认返回值
$data = $default_data;
}
$cache->set($key, $data, $expierTime);
return $data;
}
- 缓存失效时间的处理 目标:缓存失效的时候,只有一个请求走db。 思路:把缓存时间放到数据中判断。
function getData($key) {
$data = $cache->get($key);
if (!empty($data)) {
// 未过期,直接返回
if ($data['expireTime'] > time() ) {
return $data['data'];
}
// 缓存已过期,但未获得锁,返回数据,只让一个请求穿透
if (!$cache->setNx()) {
return $data['data'];
}
}
$data = getDataFromDb($key);
if (empty($data)) {
// 设置默认返回值
$data = $default_data;
}
// 过期时间提前60s
$data = [
'data' => $data;
'expireTime' => $expierTime - 60;
];
$cache->set($key, $data, $expierTime);
return $data;
}