Symfony2 - 如何在多个应用程序中设置Doctrine APC缓存前缀

4
更新:请见本文底部(此文章最初发布时我们使用的是 SF 2.3,现在我们已经升级到 2.7.0)
我们的服务器上运行着多个 Symfony 应用程序,但由于所有 doctrine ORM 缓存条目都以“sf2”为前缀,似乎在这些网站之间存在缓存污染。
从过去30分钟的谷歌搜索中得知,似乎没有简单的解决方案。
首先建议使用 ProjectConfiguration.class.php,但那似乎只适用于 Symfony 1。
下一个可能的解决方案是使用 ApcUniversalClassLoader 类(如此问题中所述:Multiple Symfony2 Sites using APC Cache)。
问题是我们的设置使用 composer 进行自动加载,因此我们不能像那个例子一样简单地使用代码。
APC 的类缓存功能很好,你可以在前端控制器中设置键,但它不会为 doctrine 缓存设置键。
请问有人有什么想法吗?因为目前我们只能在第一个应用程序上禁用 doctrine 的 APC。
前端控制器:
<?php

use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;

require_once __DIR__.'/../app/bootstrap.php.cache';

// Use APC for autoloading to improve performance.
// Change 'sf2' to a unique prefix in order to prevent cache key    conflicts
// with other applications also using APC.
$loader = new ApcClassLoader('app_1', $loader);
$loader->register(true);

require_once __DIR__.'/../app/AppKernel.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();

// wrap the default AppKernel with the AppCache one
require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppCache($kernel);

Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

-- 澄清 --

以上代码涉及到了类的APC缓存,这很好地完成了任务。我们似乎无法更改Doctrine ORM APC条目的默认命名空间,因为这些命名空间是固定的,会与每个运行实例发生冲突。

-- 更新 --

尝试了Zerrvox的建议设置命名空间后,仍然没有起作用,主要缓存仍在使用默认命名空间。如果缓存被清除时默认命名空间是随机生成的话,那么情况就不会太糟糕,但是默认命名空间在我的vagrant盒子和实际环境中都相同,并且缓存是在不同的盒子上生成的,所以显然不是随机的。

这些方法在appProdProjectContainer类中的缓存仍然引用默认命名空间。

protected function getDoctrineCache_Providers_Doctrine_Orm_DefaultMetadataCacheService()
{
....        
$instance->setNamespace('sf2orm_default_9e755ef08ba52b507455ecd06d0a648985c9593b15aca1522b4725acaaf77ce6');
        return $instance;
}

// Same for...

protected function getDoctrineCache_Providers_Doctrine_Orm_DefaultQueryCacheService   

protected function getDoctrineCache_Providers_Doctrine_Orm_DefaultResultCacheService
2个回答

3

您没有说明您是在谈论Doctrine ORM缓存还是使用Doctrine Annotations的注释缓存。

无论如何,您可以创建自己的APC缓存服务,通过在Symfony中定义一个服务来实现两者的使用(yml)

   app.doctrine.apc_cache:
       class: Doctrine\Common\Cache\ApcCache
       calls:
           - [setNamespace, ["app_namespace"]]

-- 更新 --

您是否将已定义的服务指定为Doctrine元数据缓存?请参阅Doctrine Bundle配置的配置参考http://symfony.com/doc/current/reference/configuration/doctrine.html#caching-drivers

   doctrine:
       orm:
           metadata_cache_driver:
               type: service
               id: app.doctrine.apc_cache

抱歉 - 是的,我指的是所有Doctrine缓存。话虽如此,注释是否会使用与类缓存相似的与文件路径相关的键进行缓存?如果是这样,它们已经是唯一的了,因为两个Symfony安装位于不同的目录中。无论如何,我会尝试您的解决方案并在之后更新。感谢您的回复。 - Steve Childs
Zerrvox - 请看更新的帖子,我无法在评论中发表我需要的内容。 - Steve Childs
1
我已更新我的答案,包括如何配置Doctrine以使用缓存服务。 - Zerrvox
啊,谢谢 - 不,我没有!顺便问一下,有没有办法在“运行时”设置它,而不是在配置文件中?当页面加载时,我们会切换数据库,因此我们可以在一个代码安装上运行多个站点,如果可能的话,我们可以同时切换或设置缓存。 - Steve Childs
我猜你可以从容器中获取缓存驱动程序并调用setNamespace("dynamic_namespace")。这应该可以工作,但如果您没有使用不同的源代码,则无需更改元数据缓存。更改Doctrine结果缓存可能是相关的,如果您将其用于其他缓存目的。 - Zerrvox

1

在我的情况下它有效(Symfony 2.8 - 3.4):

doctrine_cache:
    providers:
        my_redis:
            type: redis
            namespace: "%prefix%"
            aliases:
              - redis_cache

"namespace" 是在 parameters.yml 中设置的给定应用程序的前缀。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接