提升性能:解决wecenter创建临时表到磁盘过多的一个性能问题的修改方法

kenw2004
kenw2004 这家伙很懒,还没有设置简介

2 人点赞了该文章 · 2559 浏览

运行中发现Zend fr amework中有大量的DESCRIBE操作,这是读取表结构的一个操作。每次都会建立临时表到磁盘,这会导致大量的磁盘读写。

但mysql中设置了临时表的内存缓存 tmp_table_size 参数,并且足够大,理应是把临时表建到内存而不是磁盘。但依然临时表建到了磁盘上。经查,原来是由 DESCRIBE aws_sessions 引起的。

每次访问(任何页面),zend的db类都会读取aws_sessions表的表结构,此过程会创建一个临时表,可能是表结构数据。由于aws_sessions表中包含text字段,含有此字段的表会跳过内存缓存,直接创建到磁盘上,会引起性能问题。特别是大量访问量,极有可能引起 aws_sessions 锁表(将 aws_sessions  改为 innodb 引擎会缓解此问题)。

以下是减少DESCRIBE aws_sessions的次数,减少创建临时表到磁盘次数的修改方法。

一、打开:system\core\db.php 文件,修改 setob ject 函数,增加缓存部分:

2022年10月又改进了一下,降低了一些使用redis时的系统开销(以下代码只适用于wecenter 3.x版本)  

public function setObject($db_object_name = 'master')

{
if (isset($this->db[$db_object_name]))
{
Zend_Registry::set('dbAdapter', $this->db[$db_object_name]);

//增加缓存,减少 DESCRIBE TABLE 次数,减少生成临时表到磁盘的次数 2020-1-29
//2022-8-24 将cache连接转为类变量,以减少多次初始化cahce带来的系统开销
if ( ! $this->cache_connect)
{
$frontendOptions = array('automatic_serialization' => true);
$backendOptions = array('cache_dir' => ROOT_PATH.'cache/db/');
$this->cache_connect = Zend_Cache::factory(
'Core',
'Redis', //或 'File',

$frontendOptions,
$backendOptions
);
}
Zend_Db_Table_Abstract::setDefaultMetadataCache($this->cache_connect);
//END 增加缓存,减少 DESCRIBE TABLE 次数 2020-1-29

Zend_Db_Table_Abstract::setDefaultAdapter($this->db[$db_object_name]);

$this->current_db_object = $db_object_name;

return $this->db[$db_object_name];
}

throw new Zend_Exception('Can\'t find this db object: '.$db_object_name);
}

2022年10月又改进了一下,降低了一些使用redis时的系统开销(以上代码只适用于wecenter 3.x版本)。

二、在cahce目录下,创建 db 目录做为缓存目录。

如果你使用的redis缓存,则修改 'File' 为 'Redis'即可,可以为用创建cache/db目录

此修改会启用缓存,再次读取表结构时,直接读取缓存,而无需读取源表和创建临时表到磁盘。

这个问题也是找了很久才定位成功。本想自己改了用就行了,但是想想,也许还会有人需要,也可以帮助官方改进。就发到这里,分享给大家,希望能有帮助。

发布于 2020-01-29 23:03

免责声明:

本文由 kenw2004 原创发布于 WeCenter ,著作权归作者所有。

登录一下,更多精彩内容等你发现,贡献精彩回答,参与评论互动

登录! 还没有账号?去注册

bennyyao
2020-02-05 12:00
赞!!!