2016-03-26 24 views
2

Sadece Memcached'i kurdum ve bunu Doctrine ORM (Doctrine 2.4.8+, Symfony 2.8+) ile yapılan çeşitli sorguların sonuçlarını önbelleğe almak için kullanmaya çalışıyorum.
Benim app/config/config_prod.yml bu var:Doctrine Sonuç Memcached ile önbelleğe alma

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

Ve böyle 2 sorguları (ben sadece örneğin burada önbellek id yerini) üzerinde useResultCache() çalıştı: return $query->useResultCache(true, 300, "my_cache_id")->getArrayResult();. Buradaki özel sorgular, çünkü onların karmaşıklığı nedeniyle yerel sorgular (SQL), ancak herhangi bir sorgu (class AbstractQuery) için kullanılabilir, bu yüzden çalışması gerektiğini varsayalım.
Ne yazık ki, öyle değil. Sayfayı yenilediğimde, veritabanında bir değişiklik yapsaydım, değişiklik görüntülenir. Memcached istatistiklerini kontrol ettim ve hala bazı önbellek isabetleri var gibi görünüyor ama gerçekten bilmiyorum, cf. az önce ne dedim

Önbelleğe alınan sonuçları almak için önbelleğin neden burada kullanılmadığı konusunda bir fikri olan var mı? Bir şeyi yanlış anladım ve TTL bir şekilde göz ardı edildi mi?
Hata oluşmadı, memcached günlüğü boş.

@nifr tarafından talep edildiği üzere

, burada 2 yerli sorgular oluşturmak için benim kod düzeni i üzerinde bir Memcached testi koymak geçerli: Yani

$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(); 
+0

İlginç bir soru. Önbellek sürücüsü olarak apc'ye geçmek (geri) herhangi bir fark yaratır mı? – mblaettermann

+0

@mblaettermann Varsayılan olarak apc ile belirtilmiştir. Ve beklediğim gibi apc i doğrudan belirlediysem: 'Symfony \ Component \ Debug \ Exception \ UndefinedFunctionException" Doctrine \ Common \ Cache "adında" apc_fetch "işlevini çağırmayı denediniz. – Harest

+0

Ah, tamam. APCu PHP uzantısı eksik görünüyor. Size başka sonuçlar vereceğini merak ettim. Sistemi değiştirebilirseniz, 'apt-get install php5-apcu' ile kurabilirsiniz. Ancak bu, sorulan soruya gerçekten yardımcı olmuyor. – mblaettermann

cevap

1

, bu kadar başarılı olmaz nedense Öğretiler görünüyor ResultCacheDriver'ı edinin. useResultCache()'dan önce ayarlamaya çalıştım ancak Memcached: Error: Call to a member function get() on null'dan bir istisna aldım.

Memcached() öğesini kullanarak daha doğrudan yapmaya karar verdim. İhtiyaçlarıma bağlı olarak kontrolörlerde ve depolarda bu tür şeyler yapacağımı düşünüyorum. Bazı testlerden sonra mükemmel çalışır. İşte
i temelde ne olduğunu:

$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 
    } 

Herhalde bir Hizmetin bu koyacağım. Emin değilim, bu tür şeyler için “en iyi uygulama” nedir?

Düzenleme: Bir hizmet yaptım. Ama sadece yerel sql ile çalışır ... Yani sorun çözülmemiş kalır.
Edit²: Bu boş sorun hakkında bir çalışma çözümü buldum (yani Memcached'i bulamadı). kod bit: Artık

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

, ben sadece useResultCache() işlevini kullanmak config_prod.yml koymak hangi şeyler öğrenmek istiyorum.