Monthly Archive for 十一月, 2010

改进Smarty的缓存过期检测

Smarty仍然是被广泛采用的模板引擎,国产的开源网店程序Ecshop就是使用Smarty作模板引擎,它广泛采用了Smarty的静态缓存技术。

然而,Smarty检查缓存新旧居然是通过往缓存文件的开头写入经过一串经过序列化的数组(记录着缓存的过期时间等信息)——检查的时候把第一个“<”出现之前的字符串读入并unserialize(),从而获取原本数组中记录着的缓存过期时间,进而来判断是否更新缓存。

这么做有一个缺点,就是每次检查缓存是否过期的时候都要进行一次读取文件和unserialize()操作,势必影响了效率,我们不妨用以下方法来取代Smarty默认的缓存机制:

$compile_file = '../temp/compile/index.html';
if (file_exist($compile_file))
{
    $filestat = stat($compile_file)
    if (time() - $tmp['mtime'] < $smarty->cache_lifetime) //如果缓存未过期则直接输出
    {
        echo file_get_contents($compile_file);
        exit(1);
    }
    //如果缓存过期了 生成缓存+输出
    do_some_db_query(); //一些数据库查询操作
    $html = $smarty->fetch($compile_file,$smarty->cache_id);
    file_put_contents($compile_filel);
    echo $html;
}

此外,根据“在输出缓存之前,永不加载没用的东西”这条原则,Smarty类的引入和实例化应该放在过期检测之后,而不是放在init.php里,这样,如果缓存存在,就直接输出缓存并终止代码的运行,能最大化的提升应用的效率。

在网上找到了篇牛人写的关于此方法的测试和改进:
http://www.9enjoy.com/optimize-smarty-html-test/

[转]MySQL+HandlerSocket = MySQL的功能+NoSQL的性能

下文转自国内某PHP大牛的博客,原文链接:http://www.dualface.com/index.php/archives/1124

最近看到一篇博客,用8核服务器跑MySQL达到了每秒750,000次PK(主键)查询。原文网址:http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html(翻墙)。

文章首先分析了MySQL查询时的瓶颈(SQL分析、数据表的打开关闭等),然后介绍了HandlerSocket插件。HandlerSocket插件让MySQL达到了近两倍于memcached的查询性能,灰常的niubi!

                           approx qps     server CPU util
MySQL via SQL                105,000      %us 60%  %sy 28%
memcached                    420,000      %us  8%  %sy 88%
MySQL via HandlerSocket      750,000      %us 45%  %sy 53%

MySQL+HandlerSocket的架构如下图(来自原文):

mysql_handlersocket_thumb.png

从图中可以看到,HandlerSocket开了9998和9999端口,分别用于读写操作。对于基于主键的CRUD操作,客户端通过HandlerSocket进行,省略了SQL分析、数据表的打开关闭等操作。而其他查询仍然通过MySQL的3306端口进行。

相比常见的memcached+MySQL的架构,MySQL+HandlerSocket架构有两个最明显的优势:

  • 节约内存:由于MySQL InnoDB本身就会缓存数据,所以没必要在memcached多保存一份。
  • 避免数据不一致性:引入memcached后,一个很头痛的问题就是保证数据的一致性。而去掉memcached后,由于所有的数据库操作都是直接达到InnoDB引擎,所以完全消除了此问题。

相对于其他NoSQL解决方案,MySQL+HandlerSocket也有优势:

  • 降低应用开发难度:由于SQL提供了丰富的查询功能,相当于大多数NoSQL来说,开发应用时更简单。
  • 降低风险:NoSQL各有特色,选择不慎会造成深远的影响。而且能够完全掌握NoSQL的技术人员也不够普遍,出了问题不一定能够马上解决。

不过,HandlerSocket虽然省掉了一些步骤,但要是内存不足以缓存大部分常用数据。那么HandlerSocket带来的优势就荡然无存了。因此在使用HandlerSocket时,服务器一定要具备足够的内存空间用于InnoDB的Buffer Pool。此外对PHP开发者来说,HandlerSocket目前还没有可用的PHP扩展。

作者说他们已经将HandlerSocket用于了生产环境,取得了很好的效果。作者目前就职于日本最大的社会化游戏平台提供商DeNA

最后,附上HandelrSocket的仓库地址,这是一个开源项目:http://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL