扫码关注官方订阅号
php做API后 由于API变动不大(题库),缓存用什么方案解决?
如题
光阴似箭催人老,日月如移越少年。
那就题库使用缓存,好多啊memcache,redis
正好有一个api通过redis缓存的接口:
//这里是api接口 /** * @Route("/id={id}/blog", methods={"GET"}, name="bloggetinfo") * @param int $id * @return stdclass */ public function bloggetinfoAction($id = 1) { return $this->redisUtils->getCache(RedisUtils::$CACHEKEYS['ARTICLE']['ID'],'Souii\Controllers\ApiController::bloggetinfo',$id); } //这个是如果不缓存时,具体的业务逻辑 public static function bloggetinfo($id) { $atricle = Article::findFirst( array( "id = :id:", 'bind' => array('id' => $id) ) ); $map = Tags::getAll(); $ret = []; $tags = explode(',', $atricle->tags); foreach ($tags as $tag) { if (!empty($tag)) { $ret[] = $map[$tag]['name']; } } $atricle->tags = implode(',', $ret); return $atricle; }
<?php namespace Souii\Redis; /** * Created by PhpStorm. * User: zx * Date: 2015/8/26 * Time: 9:27 */ use Phalcon\Mvc\User\Component; class RedisUtils extends Component{ /** * redis的key前缀 * @var array */ public static $CACHEKEYS = array( 'ARTICLE' =>array( 'PAGE:TAG:CATE'=>'h:cache:article:cache', 'ID'=>'h:cache:article:id', 'TAG'=>'h:cache:article:tag', 'CATE'=>'h:cache:article:cate', ), 'SYSTEMS' =>array( 'KEY'=>'h:cache:systems:key' ), 'CATEGORY' => array( 'ALL'=>'h:cache:category:all' ), 'TAGS'=>array( 'ALL'=>'h:cache:tags:all' ) ); public static $WEIXIN = array( 'USER' => 'h:weixin:user:', ); /** * 获取redis缓存 * @param $prefix * @param $callback * @return mixed */ public function getCache($prefix,$callback){ /** * 获取函数参数值 */ $param = func_get_args(); /** * 先获取关键参数$prefix和callback,在获取动态参数 */ $prefix = array_shift($param); $callback = array_shift($param); $key = implode(':',$param); //尝试从redis获取参数,如果不存在,调用自定义callback函数获取 $ret = json_decode($this->redis->hGet($prefix,$key),true); if(!$ret){ $ret = call_user_func_array($callback,$param); $this->redis->hset($prefix,$key,json_encode($ret)); } return $ret; } /** * 清理一张表的缓存 * @param $tableName */ public function deleteTableCache($tableName){ $tableName = strtoupper($tableName); if(isset(RedisUtils::$CACHEKEYS[$tableName])){ foreach(RedisUtils::$CACHEKEYS[$tableName] as $key=>$value){ $this->redis->del($value); } } } }
RedisUtilsApiController
模板缓存1、twig2、..
数据缓存1、redis2、memcache
业务场景上,个人建议使用redis hash 的数据结构来存储
Hash相关操作 hSet $redis->hSet('h', 'key1', 'hello'); 向名称为h的hash中添加元素key1—>hello hGet $redis->hGet('h', 'key1'); 返回名称为h的hash中key1对应的value(hello) hLen $redis->hLen('h'); 返回名称为h的hash中元素个数 hDel $redis->hDel('h', 'key1'); 删除名称为h的hash中键为key1的域 hKeys $redis->hKeys('h'); 返回名称为key的hash中所有键 hVals $redis->hVals('h') 返回名称为h的hash中所有键对应的value hGetAll $redis->hGetAll('h'); 返回名称为h的hash中所有的键(field)及其对应的value hExists $redis->hExists('h', 'a'); 名称为h的hash中是否存在键名字为a的域 hIncrBy $redis->hIncrBy('h', 'x', 2); 将名称为h的hash中x的value增加2 hMset $redis->hMset('user:1', array('name' => 'Joe', 'salary' => 2000)); 向名称为key的hash中批量添加元素 hMGet $redis->hmGet('h', array('field1', 'field2')); 返回名称为h的hash中field1,field2对应的value
可以分为两部分,一种是代码层业务缓存,这个前面很多同学做了回答,不再描述。其实还有一种其他的策略对于很多高频读低频写,或者一些实时性要求不高的数据,完全可以上 CDN来做。这比起后端的缓存无论是 redis cache 还是 local cache 都要好得多。后端自己的缓存本身有许多限制,redis cache 可能会有单点过热的问题,而 local cache 无法存储大量数据。而且即便后端缓存,它只是降低了底层服务和数据库的压力而已,对于服务器的 QPS、连接数、带宽这些东西并没有帮助。如果使用 CDN 缓存,后端服务器的压力就几乎可以忽略,而且如果缓存策略设置的好还可以让数据有缓冲,即便后端服务挂掉,在缓存的时间内大部分用户可以不会受影响。
让 API 上 CDN 其实很简单,对 CDN 使用「自有源」把 CDN 源站设置到 API 服务的域名上,并且设置上一定的缓存策略即可。但还是有很多需要注意的点。首先,使用 CDN 来缓存的内容应该是公共内容,不涉及鉴权等行为,没有鉴权机制,我们不能把用户隐私的数据直接暴露出去。 CDN 缓存的 API 数据都是相对静态,不应该是随机生成的内容,也不应该是千人千面的内容。内容不能有实时性需求,应该允许一个时间段内容忍缓存的,因为 CDN 上的缓存是无法实时更新,只有等缓存过期之后才更新(虽然一般的 CDN 也有 API 可以主动清缓存,但并不适合用于所有场景)。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
那就题库使用缓存,好多啊memcache,redis
正好有一个api通过redis缓存的接口:
api代码:
缓存类:
参见代码:
RedisUtils
ApiController
模板缓存
1、twig
2、..
数据缓存
1、redis
2、memcache
业务场景上,个人建议使用redis hash 的数据结构来存储
可以分为两部分,一种是代码层业务缓存,这个前面很多同学做了回答,不再描述。其实还有一种其他的策略对于很多高频读低频写,或者一些实时性要求不高的数据,完全可以上 CDN来做。
这比起后端的缓存无论是 redis cache 还是 local cache 都要好得多。
后端自己的缓存本身有许多限制,redis cache 可能会有单点过热的问题,而 local cache 无法存储大量数据。
而且即便后端缓存,它只是降低了底层服务和数据库的压力而已,对于服务器的 QPS、连接数、带宽这些东西并没有帮助。
如果使用 CDN 缓存,后端服务器的压力就几乎可以忽略,而且如果缓存策略设置的好还可以让数据有缓冲,即便后端服务挂掉,在缓存的时间内大部分用户可以不会受影响。
让 API 上 CDN 其实很简单,对 CDN 使用「自有源」把 CDN 源站设置到 API 服务的域名上,并且设置上一定的缓存策略即可。但还是有很多需要注意的点。
首先,使用 CDN 来缓存的内容应该是公共内容,不涉及鉴权等行为,没有鉴权机制,我们不能把用户隐私的数据直接暴露出去。
CDN 缓存的 API 数据都是相对静态,不应该是随机生成的内容,也不应该是千人千面的内容。
内容不能有实时性需求,应该允许一个时间段内容忍缓存的,因为 CDN 上的缓存是无法实时更新,只有等缓存过期之后才更新(虽然一般的 CDN 也有 API 可以主动清缓存,但并不适合用于所有场景)。