数据库查询结果缓存
为了提高接口访问速度,并减小数据库压力,我重写了 Illuminate\Database\Query\Builder ,将所有的查询结果都缓存在 Redis 里(主要是懒,不想花时间去一个一个找热点数据)。
目前这是我想到的“一招制敌”办法,可以不用花时间找热点数据,还能提高访问速度,减轻 DB 压力,这样做可以吗?还有没有什么更好的 办法 和 工具?
下面是重写的简化代码:
protected function runSelect()
{
if($this->enableCache && $this->isShouldBeCached()){
$caching_key = $this->getCachingKey();
$caching_data = \Redis::get($caching_key);
if($caching_data){
// 命中缓存后延长过期时间
\Redis::expire($caching_key, $this->cachingTime);
return unserialize($caching_data);
}
$caching_data = parent::runSelect();
\Redis::set($caching_key, serialize($caching_data), 'EX', $this->cachingTime);
return $caching_data;
}
return parent::runSelect();
}
顺便发个小广告,我把我想的办法做成了一个插件,希望大佬们可以指点一下:GitHub: laravel-db-caching
这里还有个问题:
怎样可以做到在增 删 改操作后,将新数据刷新到缓存里?
我想到将 SQL 语句保存下来,增删改操作后再重新执行查询。
但这种只针对简单的 where id > {id} 有效。对于 where id in (1,2) 这种 甚至于复杂的查询,就不一定能起作用了,导致重新查询的结果没有变化。希望大佬们能给我指点下。
关于 LearnKu
试试接口缓存?
不去解析sql,通过接口化去缓存sql的查询结果?
通过接口方法和参数 生成键值
比如
这样比单独缓存sql的好处是:一不用关注sql条件,而是可以多条sql的结果统一缓存
缺点一,可能会涉及到多张表的查询结果,不易在某张表删改时,清除缓存
缺点二,上述方法我没用过,瞎说的 :confused:
@biyugwv 感谢你提供的方法和思路,帮我多了一个思考方向,确实有优点。但是这个没有办法在
增删改时主动更新数据。举个例子:A接口第一次请求时,携带参数name,通过数据库查询到结果为Mike,并缓存了数据。A接口第二次请求时,携带参数name,会直接返回缓存结果Mike。B接口,执行了一个更新操作,把name字段改为Ming。A接口第三次请求时,携带参数name,通过参数对比发现:诶?还是同样的参数,那就还给你缓存的数据吧!结果还是Mike不知道我的这个例子恰不恰当,我的目的是希望
缓存中的数据结果是和通过查询数据库结果保持一致的。简单的有两个,第一是延时双删,第二使用中间件canal。
延时双删是一个比较经典的方案,很大程度上保证数据一致性问题。
中间件canal是阿里开源产品,原理是监听mysql的binlog同步redis。
最后一个小看法,你既然要将所有查询结果缓存到redis里面,可以参考陌陌的技术架构,就是增删改查都用redis。
@L学习不停 感谢大佬指点🙏,,虽然不太清楚
延时双删和canal的原理,但我这就去查查你说的这两种技术资料。陌陌的技术架构我该去那里找呢?@biyugwv 查询还用like?ES是摆设?