`
student_lp
  • 浏览: 429396 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

一、文件缓存产生原因

    文件缓存是把缓存数据存储到文件系统即硬盘文件中。与内存相比,硬盘属于比较慢的存储设备。那为什么还需要用到文件存储呢?原因如下:

  • 磁盘容量大,可以存放足够多的数据。现在的常规磁盘已经进入TB级别,但内存还处于GB级别。磁盘价格远远低于内存价格,通常只有同样大小内存价格的百分之一到十分之一;
  • 磁盘与内存相比更稳定更可靠,断电后数据不丢失,存储也比较简单可靠;
  • 随着制造技术的进步,出现了固态硬盘(SSD),是硬盘的读取和写入速度得到极大的提高,能达到500Mb/s;
  • 扩展容易。可以使用磁盘阵列、分布式处理等进行大规模的存储和管理。

二、文件缓存机制

     常用的文件缓存有两种类型,分别是:①站点配置信息或一些变量通过文件缓存,生成php文件,使用时直接加载即可;②将页面生成静态的HTML文件,用户访问时由服务器直接读取HTML文件返回即可。

1、变量的php文件缓存

     在一个大型站点中,我们用来配置站点系统的配置参数可能会有很多,而且为了方便管理或动态修改这些配置参数,常常将这些配置参数存放在数据库中。但是用户一旦访问站点,就需要从数据库中加载这些配置信息,当访问量特别大的时候,数据库的压力就会急剧上升,导致站点访问速度变慢,这个时候就需要优化,减少从数据库获取配置信息的次数,因此采用文件缓存就是一个不错的选择。

     通过页面更新站点配置信息的时候,在更新完数据库以后,删除原有的php缓存文件,重新从数据库中读取配置信息,生成出新的php配置信息文件,这样当用户访问站点的时候,php程序直接加载php缓存文件,获取缓存文件中的变量信息,就完成了配置信息的加载,从而节省了访问数据库的开销。并且站点的配置信息变动次数较少,所以采用这种方式缓存非常方便,也可以提升站点的访问速度。

2、生成静态的HTML文件

    当用户访问站点时,一些页面信息或者是页面中主要的内容一经发布,基本上很少会发生变动,例如:CMS类的资讯页面。这个时候如果把动态的php代码“编译”成静态的HTML文件,当下次读取时不用再“编译”直接读取静态文件。这样就可以极大的提升服务器的处理效率,提高访问速度。

    有人可能想问,有时候页面中的广告信息和其他的一些列表信息是动态变化的,页面静态化以后,这部分信息如何处理,在这里我提供几个建议希望大家看看:CSI、SSI和ESI。其实简单起见,我们直接通过ajax请求,完成这部分页面内容的加载即可(这其实就是CSI的一种实现方式)。

    现在的模板工具,例如:smarty等。都提供了这个功能,用户通过配置就能够非常容易的实现。在配合URL静态化,很多时候,用户请求,直接由nginx或Apache服务器进行文件流的读取就能够处理完成,因而无需php等脚本语言的相应。

    基本原理:

  • 先根据配置文件判断是否要进行缓存,若不需要缓存,则直接include加载php文件。若需要缓存,则转到下一步。
  • 判断对应的静态文件,此处即缓存文件是否存在,若不存在,则进行“编译”,将编译内容保存为静态的HTML文件。否则,转到下一步。
  • 判断静态文件是否过期,若未过期则读取,否则重新编译。

注意:有关HTML静态化,我们在编程的过程中,多借助于模板文件了,一般模板工具都拥有这个功能,所以下面不在详解。如果需要了解,其本质就是将要输出的html内容写入到文件中。如果想要简单的实现,可以参考ob_start();ob_end_clean();ob_get_contents();的使用。

三、开源产品Secache

    Secache是文件型缓存解决方案,其特点如下:

  • 纯php实现,无需任何扩展,支持php4/5;
  • 使用LRU算法自动清理过期内容;
  • 最大支持1GB缓存文件;
  • 使用HASH定位,读取迅速;

    在虚拟主机不支持Memcached等高速缓存的情况下,可以考虑采用Secache。下面是该工具使用示例:

require '../Secache/Secache.php';
$cache = new Secache;
$cache->workat('cachedata');

$key = md5('test');//必须自己做HASH,前4位是16进制0-f,最长32位
$value = '数据';//必须是字符串

$cache->store($key,$value);

if($cache->fetch($key,$return)){
   echo $return;
}else{
   echo "date get failed";
}

四、自己编写文件缓存

<?php 
class cache
{   
    private static $_instance = null;
 
    protected $_options = array(
        'cache_dir'        => "./",
        'file_name_prefix' => 'cache',
        'mode'            => '1', //mode 1 为serialize model 2为保存为可执行文件
    );  
     
    /**
     * 得到本类实例
     * 
     * @return Ambiguous
     */
    public static function getInstance()
    {
        if(self::$_instance === null)
        {
            self::$_instance = new self();
        }
        return self::$_instance;
    } 
     
    /**
     * 得到缓存信息
     * 
     * @param string $id
     * @return boolean|array
     */
    public static function get($id)
    {
        $instance = self::getInstance();
         
        //缓存文件不存在
        if(!$instance->has($id))
        {
            return false;
        }
         
        $file = $instance->_file($id);
         
        $data = $instance->_fileGetContents($file);
         
        if($data['expire'] == 0 || time() < $data['expire'])
        {
            return $data['contents'];
        }
        return false;
    }
     
    /**
     * 设置一个缓存
     * 
     * @param string $id   缓存id
     * @param array  $data 缓存内容
     * @param int    $cacheLife 缓存生命 默认为0无限生命
     */
    public static function set($id, $data, $cacheLife = 0)
    {
        $instance = self::getInstance();
         
        $time = time();
        $cache         = array();
        $cache['contents'] = $data;
        $cache['expire']   = $cacheLife === 0 ? 0 : $time + $cacheLife;
        $cache['mtime']    = $time;
         
        $file = $instance->_file($id);
         
        return $instance->_filePutContents($file, $cache);
    }
     
    /**
     * 清除一条缓存
     * 
     * @param string cache id    
     * @return void
     */  
    public static function delete($id)
    {
        $instance = self::getInstance();
         
        if(!$instance->has($id))
        {
            return false;
        }
        $file = $instance->_file($id);
        //删除该缓存
        return unlink($file);
    }
     
    /**
     * 判断缓存是否存在
     * 
     * @param string $id cache_id
     * @return boolean true 缓存存在 false 缓存不存在
     */
    public static function has($id)
    {
        $instance = self::getInstance();
        $file     = $instance->_file($id);
         
        if(!is_file($file))
        {
            return false;
        }
        return true;
    }
     
    /**
     * 通过缓存id得到缓存信息路径
     * @param string $id
     * @return string 缓存文件路径
     */
    protected function _file($id)
    {
        $instance  = self::getInstance();
        $fileNmae  = $instance->_idToFileName($id);
        return $instance->_options['cache_dir'] . $fileNmae;
    }   
     
    /**
     * 通过id得到缓存信息存储文件名
     * 
     * @param  $id
     * @return string 缓存文件名
     */
    protected function _idToFileName($id)
    {
        $instance  = self::getInstance();
        $prefix    = $instance->_options['file_name_prefix'];
        return $prefix . '---' . $id;
    }
     
    /**
     * 通过filename得到缓存id
     * 
     * @param  $id
     * @return string 缓存id
     */
    protected function _fileNameToId($fileName)
    {
        $instance  = self::getInstance();
        $prefix    = $instance->_options['file_name_prefix'];
        return preg_replace('/^' . $prefix . '---(.*)$/', '$1', $fileName);
    }
     
    /**
     * 把数据写入文件
     * 
     * @param string $file 文件名称
     * @param array  $contents 数据内容
     * @return bool 
     */
    protected function _filePutContents($file, $contents)
    {
        if($this->_options['mode'] == 1)
        {
            $contents = serialize($contents);
        }
        else
        {
            $time = time(); 
            $contents = "<?php\n".
                    " // mktime: ". $time. "\n".
                    " return ".
                    var_export($contents, true).
                    "\n?>";
        }
         
        $result = false;
        $f = @fopen($file, 'w');
        if ($f) {
            @flock($f, LOCK_EX);
            fseek($f, 0);
            ftruncate($f, 0);
            $tmp = @fwrite($f, $contents);
            if (!($tmp === false)) {
                $result = true;
            }
            @fclose($f);
        }
        @chmod($file,0777);
        return $result;             
    }
     
    /**
     * 从文件得到数据
     * 
     * @param  sring $file
     * @return boolean|array
     */
    protected function _fileGetContents($file)
    {
        if(!is_file($file))
        {
            return false;
        }
         
        if($this->_options['mode'] == 1)
        {
            $f = @fopen($file, 'r'); 
            @$data = fread($f,filesize($file));
            @fclose($f);
            return unserialize($data);
        }
        else
        {
            return include $file;
        }
    }
     
    /**
     * 构造函数
     */
    protected function __construct()
    {
     
    }
     
    /**
     * 设置缓存路径
     * 
     * @param string $path
     * @return self
     */
    public static function setCacheDir($path)
    {
        $instance  = self::getInstance();
        if (!is_dir($path)) {
            exit('file_cache: ' . $path.' 不是一个有效路径 ');
        }
        if (!is_writable($path)) {
            exit('file_cache: 路径 "'.$path.'" 不可写');
        }
     
        $path = rtrim($path,'/') . '/';
        $instance->_options['cache_dir'] = $path;
         
        return $instance;
    }
     
    /**
     * 设置缓存文件前缀
     * 
     * @param srting $prefix
     * @return self
     */
    public static function setCachePrefix($prefix)
    {
        $instance  = self::getInstance();
        $instance->_options['file_name_prefix'] = $prefix;
        return $instance;
    }
     
    /**
     * 设置缓存存储类型
     * 
     * @param int $mode
     * @return self
     */
    public static function setCacheMode($mode = 1)
    {
        $instance  = self::getInstance();
        if($mode == 1)
        {
            $instance->_options['mode'] = 1;
        }
        else
        {
            $instance->_options['mode'] = 2;
        }
         
        return $instance;
    }
     
    /**
     * 删除所有缓存
     * @return boolean
     */
    public static function flush()
    {
        $instance  = self::getInstance();
        $glob = @glob($instance->_options['cache_dir'] . $instance->_options['file_name_prefix'] . '--*');
         
        if(empty($glob))
        {
            return false;
        }
         
        foreach ($glob as $v)
        {
            $fileName = basename($v);
            $id =  $instance->_fileNameToId($fileName);
            $instance->delete($id);
        }
        return true;
    }
}
 
/* 初始化设置cache的配置信息什么的 */
cache::setCachePrefix('core'); //设置缓存文件前缀
cache::setCacheDir('./cache'); //设置存放缓存文件夹路径
 
//模式1 缓存存储方式
//a:3:{s:8:"contents";a:7:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:34;i:4;i:5;i:5;i:6;i:6;i:6;}s:6:"expire";i:0;s:5:"mtime";i:1318218422;}
//模式2 缓存存储方式
/*
 <?php
 // mktime: 1318224645
 return array (
  'contents' => 
  array (
    0 => 1,
    1 => 2,
    2 => 3,
    3 => 34,
    4 => 5,
    5 => 6,
    6 => 6,
  ),
  'expire' => 0,
  'mtime' => 1318224645,
)
?>
 * 
 * 
 */
cache::setCacheMode('2'); 
 
if(!$row = cache::get('zj2'))
{
     
    $array = array(1,2,3,34,5,6,6);
    $row = cache::set('zj2',$array);
}
// cache::flush(); 清空所有缓存
 
print_r($row);
分享到:
评论

相关推荐

    Java思维导图xmind文件+导出图片

    CDN静态文件访问 分布式存储 分布式搜索引擎 应用发布与监控 应用容灾及机房规划 系统动态扩容 分布式架构策略-分而治之 从简到难,从网络通信探究分布式通信原理 基于消息方式的系统间通信 理解通信协议...

    HTML5 Web缓存和运用程序缓存(cookie,session)

    在介绍HTML5 web缓存前,来认识一下cookie和session: session: 由于HTTP是无状态的,你是谁?你干了什么?抱歉服务器都是不知道的。 因此session(会话)出现了,它会在服务器上存储用户信息以便将来使用(比如...

    精通windows server 2008 命令行与powershell 电子书PDF单文件完整版

    精通windows server 2008 命令行与powershell 电子书PDF单文件完整版 内容简介: 本书全面地介绍了Windows Server 2008命令行、PowerShell和脚本的使用,包括文件和文件夹的管理、磁盘管理、系统管理、活动目录...

    详解Android数据存储之Android 6.0运行时权限下文件存储的思考

    基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以往直接sdcard根目录上直接新建了一个xxx/cache/目录来做文件存储就会不是那么容易控制了,所以有必要重新认识一下Android文件存储的相关知识了。...

    零基础学ASP.NET.2.0(PPT 迅速入门)

    第1章 认识ASP.NET 2 第2章 Visual Studio 2005开发环境 第3章 C# 2.0 第4章 ASP.NET 2. 第5章 创建智能表单 第6章 执行表单的检验 第7章 高级页面开发 第8章 创建用户控件和自定义 第9章 使用母版页统一网 第10章 ...

    入门学习Linux常用必会60个命令实例详解doc/txt

    文件为doc版,可自行转成txt,在手机上看挺好的。 本资源来自网络,如有纰漏还请告知,如觉得还不错,请留言告知后来人,谢谢!!!!! 入门学习Linux常用必会60个命令实例详解 Linux必学的60个命令 Linux提供...

    PHP使用header方式实现文件下载功能

    认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此问题): &lt;html&gt; &lt;?php // 结果出错 // 在调用 header() 之前已存在输出...

    Oracle 从入门到精通视频教程(11G版本)(ppt)

    认识Oracle 11g 回忆Oracle的产品版本 学习Oracle 11g的新特性 第2章-Oracle 11g的安装与测试 能够使用Oracle 11g的基本条件 在Windows 2003上安装Oracle 11g 移除Oracle 11g 第3章-熟悉数据库 什么是...

    ORACLE9i_优化设计与系统调整

    §1.6 块缓存(数据高速缓冲区) 33 §1.7 数据库写入进程 34 §1.8 日志写进程 34 §1.9 数据库检查点 34 §1.10 归档处理 35 §1.11 程序全局区(PGA) 35 第2章 警告日志与跟踪日志 35 §2.1 警告与日志文件 36 §...

    ramdisk5 by gavotte

    一个linux的启动盘,也没有什么问题,只不过windows 不认识磁盘格式,但是vmware 可以通过 这个非fat格式的软盘启动(当然vmware可以直接用镜像文件启动,我这样是为了测试)。 支持命令行接口,可以把命令“ ...

    Discuz_X2.5四合一版本

    产品的现有架构,仅数据库操作相关的架构优化,就涉及317个程序文件的4525处代码片段修改,并新增DB类文件217个。 从Discuz! X2.5起,数据读写层已经实现全面独立封装。新版支持以表为单位的分服务器部署;数据表...

    Java Web程序设计教程

    6.5.2struts2文件上传实现方式 136 6.5.3struts2文件下载实现方式 141 本章小结 143 课后练习 144 第7章 struts2中应用模板语言 145 7.1模板语言简介 145 7.2应用velocity 146 7.2.1velocity基础 146 7.2.2...

    ASP.NET3.5典型模块开发源代码

    17.1 认识流媒体服务器WMS 208 17.1.1 Windows Media Services 9简介 208 17.1.2 WMS的应用范围 209 17.1.3 WMS流媒体的优势 209 17.2 通过WMS生成点播HTM页面 209 17.2.1 添加发布点 209 17.2.2 创建...

    ASP.NET 2.0开发技术大全

    包括认识ASP.NET 2.0、ASP.NET 2.0网页语法、字符串与日期处理、Page对象、Response和Request对象、Application和Session对象、Server对象、Cookie对象、Cache对象、Global.asax全局程序集文件、标准服务器控件、...

    零基础学asp.net2.0源代码

    第1章认识ASP.NET2.0 第2章VisualStudio2005开发环境 第3章C#2.0程序设计基础 第4章ASP.NET2.0页面基本对象 第二篇ASP.NET2.0界面设计篇 第5章创建职能表单 第6章执行表单的检验 第7章高级页面开发 第8章创建用户...

    从入门到精通HTML5——PDF——网盘链接

     2.3.9 禁止从缓存中调用 24  2.3.10 删除过期的cookie 25  2.3.11 强制打开新窗口 25  2.3.12 设置网页的过渡效果 26  2.4 基底网址标记&lt;base&gt; 29  2.5 页面的主体标记&lt;body&gt; 30  2.5.1 设置...

    ASP.NET 2.0开发技术大全光盘

    全书共分37章,包括认识ASP.NET 2.0、ASP.NET 2.0 网页语法、字符串与日期处理、Page对象、Response和Request对象、 Application和Session对象、Server对象、Cookie对象、Cache对象、 Global.asax全局程序集文件、...

    ASP.NET编程之道.part1.rar

    感悟01 程序员的成长之路 感悟02 程序员应具备的素质 感悟03 程序员的必备技能 感悟04 程序员的认识误区 感悟05 程序员的生涯规划 感悟06 未来IT发展趋势 第2章 编程经验谈6则 经验01 培养编程的兴趣 经验02 编程...

    分享5个非常有用的Laravel Blade指令

    Blade视图文件使用.blade.php文件扩展并存放在resources/views目录下。 接下来我将带大家认识下五个 Laravel Blade 指令,这些指令将让你在解决特定问题时如虎添翼。如果你是刚接触 Laravel 的用户,这些小技巧能带...

Global site tag (gtag.js) - Google Analytics