gpt4 book ai didi

php - 为什么 CakePHP 的 cake_core_method_cache 文件会随着时间变大?

转载 作者:可可西里 更新时间:2023-11-01 13:22:48 25 4
gpt4 key购买 nike

我们有一个相当大的 CakePHP(目前是 2.4.7)SAAS 应用程序。它非常成熟,直到上周我们还没有遇到任何关于 CakePHPs-core 提供的功能的真正问题。

上周末,我们遇到了一个非常令人担忧的情况,我们的应用程序变得非常缓慢且出现故障。我们查看了所有类型的服务器监控并发现,在过去的几个小时内,I/O 统计数据猛增。经过更多调查后,我们将问题隔离到 Cake 的“cake_core_method_cache”文件。平均一天,该文件的大小为 200 kb。上周末,它上升到 40 MB。

我们部署例程的一部分是从 app/tmp/cache 和 app/tmp/persistent 文件夹中删除所有缓存文件。因为我们经常部署(一天几次),所以缓存经常被清除。不幸的是,上周的假期暂停了我们的部署,看起来这是核心/缓存功能的问题。

所以,我的两个问题是:

a) 有谁知道,为什么 cake_core_method_cache 会随着时间变大?

b) 有没有其他办法解决这个问题,比如不断删除这个文件?

最佳答案

这个缓存是如何使用的

CakePHP 中对 method_cache 的唯一引用是在 DboSource .这是一个在整个类中广泛使用的缓存,用于缓存 (relatively) expensive quoting operations 的结果。 ,或如 a relevant docblock 所示:

Caches result from query parsing operations. Cached results for both DboSource::name() and DboSource::conditions() will be stored here.

考虑以下外壳:

<?php

class SoShell extends AppShell {

function main() {
$this->Post = ClassRegistry::init('Post');

$this->Post->find('all', array(
'conditions' => array(
'find-this-text' => 'x'
)
));

debug(DboSource::$methodCache);
}

}

运行它,产生以下输出:

> Console/cake so
########## DEBUG ##########
array(
'name' => array(
'f5442d1f57be5d9d8ac80ae9613d5ff9' => '`database_name`',
'cfacfed443d6f30e67edf9bbcb06ce30' => '`posts`',
'e13d78515036382daf55fa083088c902' => '`Post`.`id`',
'aafd056e6d53878a75ab4ee3f18645a1' => '`Post`.`title`',
'4084e974416e3a7fb06e6a280721637b' => '`Post`.`body`',
'b4f1ad1de4cdc3a3f82e905f8dfd8673' => '`Post`.`created`',
'bfeffce70e344d7606e17c9ff24530b5' => '`Post`.`modified`',
'e42609d9744a7d1ce80c8d838b9ea07c' => '`find-this-text`', # <-
'c0a33fa0f04ac4682dcdc4b25167b3a8' => '`Post`'
),
'fields' => array(
'952d56c2bf037c8195bdd5fba57b1024' => array(
(int) 0 => '`Post`.`id`',
(int) 1 => '`Post`.`title`',
(int) 2 => '`Post`.`body`',
(int) 3 => '`Post`.`created`',
(int) 4 => '`Post`.`modified`'
)
)
)

请注意,缓存包含“用户”(或开发人员)输入,该数组是写入缓存的内容 at the end of a request .

这个例子还应该强调为什么缓存会随着时间增长——缓存依赖于迄今为止发出的查询,随着时间的推移,应用程序会发出更多的查询排列,导致方法缓存增长(但通常不是很多MB)。

轻松修复

对于所描述的问题有一个非常简单的修复方法:禁用方法缓存。

即将以下内容放在您的应用程序的任何位置:

DboSource::$cacheMethods = false;

这当然意味着性能下降,因为不会使用方法缓存,因此每个请求都会发生相对昂贵的基于 preg 的引用操作。

更好的修复

如果缓存中充满了“模型的数据库实例”——很可能某处存在应用程序问题。这是不正常的,它不应该发生并且取决于应用程序正在做什么。鉴于不可能给出具体的解决方案。

但是,如果您可以在包含大量数据的缓存中识别任何特定键,则可以使用它来查找负责的查询。例如:

// anywhere
if (isset(DboSource::$methodCache['name']['e42609d9744a7d1ce80c8d838b9ea07c']) {
// a query with find-this-text has been issued somewhere
}

您可以(暂时)将这种逻辑添加到where the dbo methodCache property is modified能够“原位”检测修改:

public function cacheMethod($method, $key, $value = null) {
if ($this->cacheMethods === false) {
return $value;
}
if (!$this->_methodCacheChange && empty(self::$methodCache)) {
self::$methodCache = Cache::read('method_cache', '_cake_core_');
}
if ($value === null) {
return (isset(self::$methodCache[$method][$key])) ? self::$methodCache[$method][$key] : null;
}
$this->_methodCacheChange = true;

// Added
if ($method === 'name' && $key === 'e42609d9744a7d1ce80c8d838b9ea07c') {
App::uses('Debugger', 'Utility');
$this->log("Query with find-this-text in it issued", "wat-debug");
$this->log(Debugger::trace(), "wat-debug");
}
// Added end

return self::$methodCache[$method][$key] = $value;
}

这将允许您确定是什么直接负责将大量数据注入(inject)方法缓存;然后更正应用程序代码,以便可以按设计启用和使用方法缓存。

关于php - 为什么 CakePHP 的 cake_core_method_cache 文件会随着时间变大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23240022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com