使用标准php库使许多Memcache键无效的最佳方法? [英] Best way to invalidate a number of memcache keys using standard php libraries?

查看:75
本文介绍了使用标准php库使许多Memcache键无效的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含文件的数据库,该文件可以搜索,浏览并在多个服务器上具有多个副本.

I have a database with files which can be searched, browsed and have multiple copies on multiple servers.

我缓存搜索,浏览页面和服务器位置(URL).假设我删除了一个文件,那么使该文件的所有搜索,浏览数据和网址的一种好方法是什么?还是文件服务器出现故障,并且我需要使指向该服务器的所有URL无效?

I cache searches, browse pages and server locations (urls). Say I delete a file, what's a good way to invalidate all searches, browse data and urls for this file? Or if a file server goes down, and I need to invalidate all urls pointing to this server?

基本上,我正在寻找与 memcache-tags 类似的东西,但是带有标准的memcache和php组件. (无需更改Web服务器本身的任何内容).在密钥之间,我需要某种多对多的关系(一个服务器有许多文件,一个文件有多个服务器),但是似乎无法找出实现此目的的好方法.在某些情况下,过时的缓存是可以接受的(较小的更新等),但是在某些情况下(通常是删除并关闭服务器),我需要使所有包含对它的引用的缓存项无效.

Essentially I'm looking for something similar to memcache-tags, but with standard memcache and php components. (Without having to change anything on the web server itself). I need some sort of many to many relation (one server has many files, and one file has multiple servers) in between keys, but can't seem to figure out a good way to accomplish this. In some situations stale cache is acceptable (minor updates etc.), but in some cases it's not (typically delete, and server down) where I need to invalidate all cache items containing references to it.

我研究过的一些方法:

命名空间 :

$ns_key = $memcache->get("foo_namespace_key");
// if not set, initialize it
if($ns_key===false) $memcache->set("foo_namespace_key", rand(1, 10000));
// cleverly use the ns_key
$my_key = "foo_".$ns_key."_12345";
$my_val = $memcache->get($my_key);

//To clear the namespace do:
$memcache->increment("foo_namespace_key");

  • 将缓存键限制为单个名称空间
  • Item caching approach:

    $files = array('file1','file2');
    // Cache all files as single entries
    foreach ($files as $file) {
      $memcache->set($file.'_key');
    }
    $search = array('file1_key','file2_key');
    // Retrieve all items found by search (typically cached as file ids)
    foreach ($search as $item) {
      $memcache->get($item);
    }
    

    • 如果文件服务器已关闭,则所有问题都将失效,并且所有包含该服务器URL的密钥都应无效(例如,将需要大量的小型缓存项,这反过来又需要针对缓存的大量请求)-中断任何缓存完整对象和结果集的机会
    • 标记实现 :

      Tag implemenation:

      class KeyEnabled_Memcached extends Zend_Cache_Backend_Memcached
      {
      
          private function getTagListId()
          {
              return "MyTagArrayCacheKey";
          }
      
          private function getTags()
          {
              if(!$tags = $this->_memcache->get($this->getTagListId()))
              {
                  $tags = array();
              }
              return $tags;
          }
      
          private function saveTags($id, $tags)
          {
              // First get the tags
              $siteTags = $this->getTags();
      
              foreach($tags as $tag)
              {
                  $siteTags[$tag][] = $id;
              }
              $this->_memcache->set($this->getTagListId(), $siteTags);        
          }
      
          private function getItemsByTag($tag)
          {
              $siteTags = $this->_memcache->get($this->getTagListId());
              return isset($siteTags[$tag]) ? $siteTags[$tag] : false;
          }
      
          /**
           * Save some string datas into a cache record
           *
           * Note : $data is always "string" (serialization is done by the
           * core not by the backend)
           *
           * @param  string $data             Datas to cache
           * @param  string $id               Cache id
           * @param  array  $tags             Array of strings, the cache record will be tagged by each string entry
           * @param  int    $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime)
           * @return boolean True if no problem
           */
          public function save($data, $id, $tags = array(), $specificLifetime = false)
          {
              $lifetime = $this->getLifetime($specificLifetime);
              if ($this->_options['compression']) {
                  $flag = MEMCACHE_COMPRESSED;
              } else {
                  $flag = 0;
              }
              $result = $this->_memcache->set($id, array($data, time()), $flag, $lifetime);
              if (count($tags) > 0) {
                  $this->saveTags($id, $tags);
              }
              return $result;
          }
      
          /**
           * Clean some cache records
           *
           * Available modes are :
           * 'all' (default)  => remove all cache entries ($tags is not used)
           * 'old'            => remove too old cache entries ($tags is not used)
           * 'matchingTag'    => remove cache entries matching all given tags
           *                     ($tags can be an array of strings or a single string)
           * 'notMatchingTag' => remove cache entries not matching one of the given tags
           *                     ($tags can be an array of strings or a single string)
           *
           * @param  string $mode Clean mode
           * @param  array  $tags Array of tags
           * @return boolean True if no problem
           */
          public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array())
          {
              if ($mode==Zend_Cache::CLEANING_MODE_ALL) {
                  return $this->_memcache->flush();
              }
              if ($mode==Zend_Cache::CLEANING_MODE_OLD) {
                  $this->_log("Zend_Cache_Backend_Memcached::clean() : CLEANING_MODE_OLD is unsupported by the Memcached backend");
              }
              if ($mode==Zend_Cache::CLEANING_MODE_MATCHING_TAG) {
                  $siteTags = $newTags = $this->getTags();
                  if(count($siteTags))
                  {
                      foreach($tags as $tag)
                      {
                          if(isset($siteTags[$tag]))
                          {
                              foreach($siteTags[$tag] as $item)
                              {
                                  // We call delete directly here because the ID in the cache is already specific for this site
                                  $this->_memcache->delete($item);
                              }
                              unset($newTags[$tag]);
                          }
                      }
                      $this->_memcache->set($this->getTagListId(),$newTags);
                  }
              }
              if ($mode==Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG) {
                  $siteTags = $newTags = $this->getTags();
                  if(count($siteTags))
                  {
                      foreach($siteTags as $siteTag => $items)
                      {
                          if(array_search($siteTag,$tags) === false)
                          {
                              foreach($items as $item)
                              {
                                  $this->_memcache->delete($item);
                              }
                              unset($newTags[$siteTag]);
                          }
                      }
                      $this->_memcache->set($this->getTagListId(),$newTags);
                  }
              }
          }
      }
      

      • 由于内部内存缓存密钥丢失,无法控制哪些密钥无效,何时可以丢弃标签密钥,从而使大量实际有效密钥(仍将存在)失效
      • 存在写并发问题
      • 两个-步进缓存系统 :

        Two-step cache system:

        // Having one slow, and one fast cache mechanism where the slow cache is reliable storage  containing a copy of tag versions 
        $cache_using_file['tag1'] = 'version1';
        $cache_using_memcache['key'] = array('data' = 'abc', 'tags' => array('tag1' => 'version1');
        

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆