使用Memcached进行条令结果缓存


Doctrine Result caching with Memcached

我刚刚安装了Memcached,我正试图用它来缓存使用Doctrine ORM(Doctrine 2.4.8+,Symfony 2.8+)完成的各种查询的结果。
我的app/config/config_prod.yml有这个:

doctrine:
    orm:
        metadata_cache_driver: memcached
        result_cache_driver: memcached
        query_cache_driver: memcached  

我尝试在两个类似的查询上useResultCache()(我只是在这里替换了缓存id作为示例):return $query->useResultCache(true, 300, "my_cache_id")->getArrayResult();。这里的特殊查询是因为它们的复杂性是本机查询(SQL),但该方法可用于任何查询(类AbstractQuery),所以我认为它应该可以工作
不幸的是,事实并非如此。每次刷新页面时,如果我只是对数据库进行了更改,则会显示更改。我已经检查了memcached的统计数据,似乎仍然有一些缓存命中率,但我真的不知道怎么做,参见我刚才说的。

有人知道为什么这里似乎没有使用缓存来获得所谓的缓存结果吗?我是不是误解了什么,TTL被忽略了
没有生成错误,memcached日志为空。

根据@nifr的要求,以下是我的代码布局,用于创建我进行Memcached测试的2个本地查询:

    $rsm = new ResultSetMapping;
    $rsm->addEntityResult('my_entity_user', 'u');
    // some $rsm->addFieldResult('u', 'column', 'field');
    // some $rsm->addScalarResult('column', 'alias');
    $sqlQuery = 'SELECT
        ... 
        FROM ...
        INNER JOIN ... ON ...
        INNER JOIN ... ON ...
        // some more join
        WHERE condition1
            AND condition2';
    // some conditions added depending on params passed to this function
    $sqlQuery .= '
            AND (fieldX = (subrequest1))
            AND (fieldY = (subrequest2))
            AND condition3
            AND condition4
        GROUP BY ...
        ORDER BY ...
        LIMIT :nbPerPage
        OFFSET :offset
        ';
    $query =
        $this->_em->createNativeQuery($sqlQuery, $rsm)
        // some ->setParameter('param', value)
        ;
    return $query->useResultCache(true, 300, "my_cache_id")->getArrayResult();

因此,由于某种原因,Doctrine似乎无法成功获得ResultCacheDriver。我试图在useResultCache()之前设置它,但我在Memcached中遇到了一个异常:Error: Call to a member function get() on null

我决定更直接地调用Memcached()。我想我会在控制器和存储库中做这类事情,这取决于我的需求。经过一些测试,它运行得很好
以下是我基本上要做的:

    $cacheHit = false;
    $cacheId = md5("my_cache_id"); // Generate an hash for your cache id
    // We check if Memcached exists, if it's not installed in dev environment for instance
    if (class_exists('Memcached'))
    {
        $cache = new 'Memcached();
        $cache->addServer('localhost', 11211);
        $cacheContent = $cache->get($cacheId);
        // We check if the content is already cached
        if ($cacheContent != false)
        {
            // Content cached, that's a cache hit
            $content = $cacheContent;
            $cacheHit = true;
        }
    }
    // No cache hit ? We do our stuff and set the cache content for future requests
    if ($cacheHit == false)
    {
        // Do the stuff you want to cache here and put it in a variable, $content for instance
        if (class_exists('Memcached') and $cacheHit == false) $cache->set($cacheId, $content, time() + 600); // Here cache will expire in 600 seconds
    }  

我可能会把这个放在服务中。还不确定这种东西的"最佳实践"是什么。

编辑:我做了一个服务。但它只适用于本机sql。。。所以这个问题一直没有解决
Edit²:我已经找到了一个关于这个null问题的有效解决方案(意味着它找不到Memcached)。代码位:

        $memcached = new 'Memcached();
        $memcached->addServer('localhost', 11211);
        $doctrineMemcached = new 'Doctrine'Common'Cache'MemcachedCache();
        $doctrineMemcached->setMemcached($memcached);
        $query
            ->setResultCacheDriver($doctrineMemcached)
            ->useResultCache(true, 300);  

现在,我想知道我应该在config_prod.yml中放入哪些内容才能使用useResultCache()函数。