前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >缓存技术 2

缓存技术 2

作者头像
PM吃瓜
发布2019-08-13 10:38:34
6750
发布2019-08-13 10:38:34
举报
文章被收录于专栏:PM吃瓜(公众号)PM吃瓜(公众号)

随着网络的发展,数据越来越多,从而导致运算压力越来越大。为了解决这一问题,就需要合理分配资源,充分利用已有资源,缓存的工作实际就是资源的合理分配。

在web世界里,理论上每层都可以被缓存。

  1. 底层的cpu缓存,磁盘文件缓存。
  2. 应用层的虚拟机变量缓存,memcached缓存,apc基于字节码的缓存。
  3. 数据库层table cache,thread cache,queary cache.
  4. servlet 容器层有apache缓存

命中率衡量缓存机制的好坏和效率。

一般来说命中率达到85%以上已经很高了,达到98%是理想状态。

缓存更新策略

FIFO最先进缓存的数据在缓存空间不够的情况下,会首先清理出来。

LFU最少使用元素会被清理掉。这要求缓存元素有Hit属性,最小的先被清理掉。

LRU最近最少使用的元素被清理掉。缓存元素有个时间戳,最早的元素会被清理掉。

ThinkPHP提供了方便的缓存方式,包括数据缓存、静态缓存和查询缓存等,支持包括文件方式、APC、Db、Memcache、Shmop、Sqlite、Redis、Eaccelerator和Xcache在内的动态数据缓存类型,以及可定制的静态缓存规则,并提供了快捷方法进行存取操作。

文件在 项目名/Home/runtime。只要把runtime的文件删除再在页面刷新就会出现新增的模块。或者改配置,把缓存有效期的时间改成一秒。。。。配置在下面 /* 数据缓存设置 */ 'DATA_CACHE_TIME' => 0, // 数据缓存有效期 0表示永久缓存 'DATA_CACHE_COMPRESS' => false, // 数据缓存是否压缩缓存 'DATA_CACHE_CHECK' => false, // 数据缓存是否校验缓存 'DATA_CACHE_TYPE' => 'File', // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator 'DATA_CACHE_PATH' => TEMP_PATH,// 缓存路径设置 (仅对File方式缓存有效) 'DATA_CACHE_SUBDIR' => false, // 使用子目录缓存 (自动根据缓存标识的哈希创建子目录) 'DATA_PATH_LEVEL' => 1, // 子目录缓存级别

数据缓存

Thinkphp缓存文件的配置 Home是我建立的前台项目,在Home\Conf\config.php找到缓存的配置文件,配置如下

代码语言:javascript
复制
<?php   
   return array(       
   'DB_TYPE'=>'mysql',       
   'DB_HOST'=>'127.0.0.1',       
  'DB_NAME'=>'w3note',       
   'DB_USER'=>'root',       
  'DB_PWD'=>'123456',       
  'DB_PORT'=>'3306',       
  'DB_PREFIX'=>'w3_',       
  'DATA_CACHE_TYPE'=>'file',//设置缓存方式为file       
  'DATA_CACHE_TIME'=>'600',//缓存周期600秒       
 );       
 ?>

Thinkphp缓存函数的使用 在thinkphp中,使用快捷缓存函数S()进行缓存,其用法如下:

代码语言:javascript
复制
S('data',$Data);//使用data标识缓存$Data数据  
S('data',$Data,600);// 缓存$Data数据600秒  
 $Data = S('data');// 获取缓存数据  
S('data',NULL);// 删除缓存数据

实例演示

代码语言:javascript
复制
<?php       
 // 本类由系统自动生成,仅供测试用途       
  class IndexAction extends Action{       
    public function index(){       
        //如果有缓存,则读取缓存数据       
        //如果没有缓存,则读取数据库当中的数据放入缓存       
        $lists=S('lists');                     
        if(emptyempty($lists)){                           
          $news=M('news');   
          $lists=$news->select();   
          S('lists',$lists,600);   
          echo '这是直接读取数据库的数据';       
           }   
        dump($list);  
 ?>

第一次访问

代码语言:javascript
复制
这是直接读取数据库的数据
array(10) {  
   [0] => array(12) {  
     ["id"] => string(1) "1"  
     ["catid"] => string(2) "13"  
     ["title"] => string(4) "thinkphp的缓存技术"  
     ["content"] => string(8) "thinkphp的缓存技术"  
     ["tags"] => string(4) "缓存"  
     ["thumb"] => string(0) ""  
     ["description"] => string(7) "thinkphp的缓存技术"  
     ["inputtime"] => string(10) "1348370202"  
     ["posid"] => string(1) "1"  
     ["ord"] => string(1) "2"  
     ["hits"] => string(1) "1"  
     ["status"] => string(1) "1"  

}

第二次访问

代码语言:javascript
复制
array(10) {  
   [0] => array(12) {  
     ["id"] => string(1) "1"  
     ["catid"] => string(2) "13"  
     ["title"] => string(4) "thinkphp的缓存技术"  
     ["content"] => string(8) "thinkphp的缓存技术"  
     ["tags"] => string(4) "缓存"  
     ["thumb"] => string(0) ""  
     ["description"] => string(7) "thinkphp的缓存技术"  
     ["inputtime"] => string(10) "1348370202"  
     ["posid"] => string(1) "1"  
     ["ord"] => string(1) "2"  
     ["hits"] => string(1) "1"  
     ["status"] => string(1) "1"  
 }

说明:第一次运行时,会打印出如上面所示信息,刷新一下页面后,少了 “ 这是直接读取数据库的数据" ,说明读取的是先前生成的缓存数据.

快速缓存

如果你仅仅是希望用文件的方式缓存一些简单的数据,并且没有有效期的概念,那么系统还提供了一个快速缓存方法F可以用来更快的操作。 快速缓存Data数据,默认保存在DATA_PATH目录下面

代码语言:javascript
复制
F('data',$Data);

快速缓存Data数据,保存到指定的目录

代码语言:javascript
复制
F('data',$Data,TEMP_PATH);

获取缓存数据

代码语言:javascript
复制
$Data = F('data');

删除缓存数据

代码语言:javascript
复制
F('data',NULL);

F方法支持自动创建缓存子目录,在DATA_PATH目录下面缓存data数据,如果User子目录不存在,则自动创建:

代码语言:javascript
复制
F('User/data',$Data);

3.1.2版本开始F方法支持使用通配符批量删除功能,使用如下:

代码语言:javascript
复制
F('User/*',NULL);

表示删除DATA_PATH.'User/'目录下面的数据缓存。 系统内置的数据字段信息缓存就是用了快速缓存机制

查询缓存

对于及时性要求不高的数据查询,我们可以使用查询缓存功能来提高性能,而且无需自己使用缓存方法进行缓存和获取。 APP/config.php配置:

代码语言:javascript
复制
'DATA_CACHE_TIME'   => 60, // 数据缓存有效期 0表示永久缓存
'DATA_CACHE_TYPE'   => 'File',
 // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
'DB_SQL_BUILD_CACHE' => true,
'DB_SQL_BUILD_LENGTH' => 20, // SQL缓存的队列长度
'DATA_CACHE_PATH' => TEMP_PATH,

查询缓存功能支持所有的数据库,并且支持所有的缓存方式和有效期。 在使用查询缓存的时候,只需要调用Model类的cache方法,例如:

代码语言:javascript
复制
$Model->cache(true)->select();

如果使用了cache(true) ,则在查询的同时会根据当前的查询SQL生成查询缓存,默认情况下缓存方式采用DATA_CACHE_TYPE参数设置的缓存方式(系统默认值为File表示采用文件方式缓存),缓存有效期是DATA_CACHE_TIME 参数设置的时间,也可以单独制定查询缓存的缓存方式和有效期:

代码语言:javascript
复制
$Model->cache(true,60,'xcache')->select();

表示当前查询缓存的缓存方式为xcache,并且缓存有效期为60秒。 同样的查询,如果没有使用cache方法,则不会获取或者生成任何缓存,即便是之前调用过Cache方法。 查询缓存只是供内部调用,如果希望查询缓存开放给其他程序调用,可以指定查询缓存的Key,例如:

代码语言:javascript
复制
$Model->cache('cache_name',60)->select();

则可以在外部通过S方法直接获取查询缓存的内容,

代码语言:javascript
复制
$value = S('cache_name');

除了select方法之外,查询缓存还支持find和getField方法,以及他们的衍生方法(包括统计查询和动态查询方法)。具体应用的时候可以根据需要选择缓存方式和缓存有效期。

SQL解析缓存

除了查询缓存之外,ThinkPHP还支持SQL解析缓存,因为ThinkPHP的ORM机制,所有的SQL都是动态生成的,然后由数据库驱动执行。 所以如果你的应用有大量的SQL查询需求,那么可以开启SQL解析缓存以减少SQL解析提高性能。要开启SQL解析缓存,只需要设置:

代码语言:javascript
复制
'DB_SQL_BUILD_CACHE' => true,

即可开启数据库查询的SQL创建缓存,默认缓存方式为文件方式,还可以支持xcache和apc方式缓存,只需要设置:

代码语言:javascript
复制
'DB_SQL_BUILD_QUEUE' => 'xcache',

我们知道,一个项目的查询SQL的量可能会非常巨大,所以有必要设置下缓存的队列长度,例如,我们希望SQL解析缓存不超过20条记录,可以设置:

代码语言:javascript
复制
'DB_SQL_BUILD_LENGTH' => 20, // SQL缓存的队列长度

注意:只有查询方法才支持SQL解析缓存

静态缓存

要使用静态缓存功能,需要开启HTML_CACHE_ON参数,并且使用HTML_CACHE_RULES配置参数设置静态缓存规则文件 。

虽然也可以在应用配置文件中定义静态缓存规则,但是建议是在模块配置文件中为不同的模块定义静态缓存规则。

静态规则定义

静态规则的定义方式如下:

代码语言:javascript
复制
'HTML_CACHE_ON' => true, // 开启静态缓存
'HTML_CACHE_TIME' => 60, // 全局静态缓存有效期(秒)
'HTML_FILE_SUFFIX' => '.shtml', // 设置静态缓存文件后缀
'HTML_CACHE_RULES' => array( // 定义静态缓存规则
 // 定义格式1 数组方式
 '静态地址' => array('静态规则', '有效期', '附加规则'), 
 // 定义格式2 字符串方式
 '静态地址' => '静态规则', 
)

定义格式1采用数组方式 便于单独为某个静态规则设置不同的有效期,定义格式2采用字符串方式订阅静态规则,同时采用HTML_CACHE_TIME设置的全局静态缓存有效期。

静态缓存文件的根目录在HTML_PATH定义的路径下面,并且只有定义了静态规则的操作才会进行静态缓存。 并且静态缓存支持不同的存储类型。 静态缓存仅在GET请求下面有效。

静态地址

静态地址包括下面几种定义格式:

  1. 第一种是定义全局的操作静态规则,例如定义所有的read操作的静态规则为:
代码语言:javascript
复制
'read'=>array('{id}',60)

其中,{id} 表示取$_GET['id'] 为静态缓存文件名,第二个参数表示缓存60秒。

  1. 第二种是定义全局的控制器静态规则,例如定义所有的User控制器的静态规则为:
代码语言:javascript
复制
'user:'=>array('User/{:action}_{id}','600')

其中,{:action} 表示当前的操作名称

  1. 第三种是定义某个控制器的操作的静态规则,例如,我们需要定义Blog控制器的read操作进行静态缓存
代码语言:javascript
复制
'blog:read'=>array('{id}',0)
  1. 第四种方式是定义全局的静态缓存规则,这个属于特殊情况下的使用,任何模块的操作都适用,例如
代码语言:javascript
复制
'*'=>array('{$_SERVER.REQUEST_URI|md5}'),

表示根据当前的URL进行缓存。

静态规则

静态规则是用于定义要生成的静态文件的名称,静态规则的定义要确保不会冲突,写法可以包括以下情况:

  1. 使用系统变量 包括 _GET、_REQUEST、_SERVER、_SESSION、_COOKIE 格式:
代码语言:javascript
复制
{$_×××|function}

例如:

代码语言:javascript
复制
{$_GET.name} 
{$_SERVER.REQUEST_URI|md5}
  1. 使用框架特定的变量 {:module} 、{:controller} 和{:action} 分别表示当前模块名、控制器名和操作名。 例如:
代码语言:javascript
复制
{:module}/{:controller}_{:action}
  1. 使用_GET变量 {var|function}也就是说 {id}其实等效于 {$_GET.id}
  2. 直接使用函数 {|function} 例如:{|time}
  3. 支持混合定义 例如我们可以定义一个静态规则为:
代码语言:javascript
复制
'{id},{name|md5}' 

在{}之外的字符作为字符串对待,如果包含有"/",会自动创建目录。 例如,定义下面的静态规则:

代码语言:javascript
复制
{:module}/{:action}_{id}

则会在静态目录下面创建模块名称的子目录,然后写入操作名_id.shtml 文件。

静态缓存有效期

单位为秒。如果不定义,则会获取配置参数HTML_CACHE_TIME的设置值,如果定义为0则表示永久缓存。

附加规则

通常用于对静态规则进行函数运算,例如

代码语言:javascript
复制
'read'=>array('Think{id},{name}','60', 'md5') 

翻译后的静态规则是

代码语言:javascript
复制
md5('Think'.$_GET['id']. ', '.$_GET['name']);
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Tech爬虫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据缓存
  • 快速缓存
  • 查询缓存
  • SQL解析缓存
  • 静态缓存
    • 静态规则定义
      • 静态地址
        • 静态规则
          • 静态缓存有效期
            • 附加规则
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档