提升性能:解决wecenter创建临时表到磁盘过多的一个性能问题的修改方法
运行中发现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-02-05 12:00