noizu-labs/fragmented-keys

Memcache 使用的碎片化密钥管理和失效库。

0.2.1.1 2014-08-08 19:09 UTC

This package is not auto-updated.

Last update: 2024-09-24 02:21:49 UTC


README

tl;dr; 一个用于通过在 memcache、apc 或其他存储设备上跟踪标签值对版本来管理缓存失效的 PHP 库。

有关此库的 Java 版本,请参阅 (https://github.com/noizu/fragmented-keys-4java)

概述

Fragmented Keys 提供了一种管理并失效组合缓存键的简单方法。

它通过在 memcache(或您选择的任何后端持久层)中持久化标签实例版本信息来实现这一点。当构建组合/碎片化键时,这些标签及其版本被用于生成最终的组合键。

因此,如果您想将某些内容与特定于用户名的粒度相关联,可以执行以下操作

  $GlobalGreetingTag = new Tag\Standard("Global.Greeting", "global");
  $UserUserNameTag = new Tag\Standard("User.Username", $userId);
  $keyobj = new Key\Standard(
      "CacheDataThatInvalidatesWhenUserNamesAreChanged", 
      array($UserUserNameTag, $GlobalGreetingTag)
  );
  $cacheKey = $keyObj->getKeyStr(); 

然后,您可以通过调用以下方法来使与您的用户名关联的项目失效

  $UserUserNameTag = new Tag\Standard("User.Username", $userId);
  $UserUserNameTag->Increment(); 

幕后,这看起来就像屏蔽了[目标用户]桶以下的所有内容。

  AllKey
    \ 
     \-[ ]Global.Greeting
            \
             \-[ ]Other User Cached Greeting
              \
               \-[x]Targeted User

或者,您也可以疯狂地使所有依赖于 Global.Greating 的键失效

  $GlobalGreetingTag->Increment(); 

但请确保您的数据库已经准备好。

  AllKey
    \ 
     \-[x]Global.Greeting
            \
             \-[x]Other User Cached Greeting
              \
               \-[x]Target User

设置 & 安装

安装

此项目可在 composer 上使用,只需将 noizu-labs/fragmented-keys 添加到您的需求列表中。 "require": { "noizu-labs/fragmented-keys": "dev-master", }

设置

代码依赖于可用的 Memcached、Memcache 或 APC 处理器以及一个全局前缀来避免冲突。

$m = new \Memcached;
\NoizuLabs\FragmentedKeys\Configuration\setGlobalCacheHandler(new \NoizuLabs\FragmentedKeys\CacheHandler\Memcached($m));
\NoizuLabs\FragmentedKeys\Configuration\setGlobalPrefix("MyApp");

//you may override the handler per tag by calling 
$tag->setCacheHandler($alternativeHandler); 

//or by including a handler in you constructor. 
$tag = new Tag\Standard("Users", 1234, null, CacheHandler\Apc());

组件

缓存处理器

$apcHandler = \NoizuLabs\FragmentedKeys\CacheHandler\Apc();
$inMemoryHandler = \NoizuLabs\FragmentedKeys\CacheHandler\Memory();
$memcachedHandler = \NoizuLabs\FragmentedKeys\CacheHandler\Memcached(new Memcached());
$memcacheHandler = \NoizuLabs\FragmentedKeys\CacheHandler\Memcache(new Memcache());

标签

标签是在某些情况下使相关缓存数据失效的逻辑分组。

用户:$id 对,站点:$siteId 等。此库将标签实例对附加到它们,以便在您想要使大量相关项目失效时,您不需要向 memcache 或 apc 发送数十个失效请求。您只需调用一次 $tag->increment() 即可,任何使用该标签实例(用户:$userId)的关联键都将生成新的键;

*延迟功能尚未实现

密钥环

密钥环通过允许您定义常见的密钥结构一次,然后在需要时在代码中重复使用它来使您的生活变得更简单。您可以在配置中调整设置,甚至定义始终包含某些附加标签的定制密钥 而不需要您的缓存调用者手动包含它们!

示例

<?php
    //=================================================
    // Config stuff you only need to do this once
    //=================================================
    /* Somewhere in you bootstrap or wherever you instiatiate a KeyRing or KeyRing derived Class */
    $cacheHandlers = array(
        'memcache' => new \NoizuLabs\FragmentedKeys\CacheHandler\Memcached($this->container['memcache']),
        'memory' => new \NoizuLabs\FragmentedKeys\CacheHandler\Memory()
        );
    $globalOptions = array(
      'type' => 'standard'  
    );
    $tagOptions = array(
        'universe' => array('type' => 'constant', 'version' => 5)
    );
    $ring = new FragmentedKeys\KeyRing($globalOptions,  $tagOptions, 'memcache', $cacheHandlers);

    /* define you keys */
    $ring->DefineKey("Users", array('universe', array('tag' => 'planet' , 'cacheHandler' => 'memory', 'version' => null, 'type'=>'standard'), 'city'));


    //==============================================
    // Need to check for some cached data? Generating you key now takes one line instead of 5;
    //===============================================
    $users = $ring->getUsersKeyObj('MilkyWay', 'Earth', 'Chicago')->getKeyStr();
    $users = $memcache->get($userKey);
    if(!users) {
          $users = query("select * from users where universe='MilkyWay' AND planet='Earth' AND 'city' => 'Chicago'");
          $memcache->set($userKey, $users);
    }
    
    /* Invalidate them */
    $universeTag = new Tag\Standard('universe', 'MilkyWay'); 
    $universeTag->increment(); 


    //===============================
    // Old Method
    //===============================
    $universeTag = new Tag\Constant("universe", "MilkyWay",5);
    $worldTag = new Tag\Standard("planet", "Earth");
    $cityTag = new Tag\Standard("city", "Chicago", null, new FragmentedKeys\CacheHandler\Memory());
    $key = new Key\Standard("Users", array($universeTag, $worldTag, $cityTag); 
    $userKey = $key->getKeyStr();
    $users = $memcache->get($userKey);
    if(!users) {
          $users = query("select * from users where universe='MilkyWay' AND planet='Earth' AND 'city' => 'Chicago'");
          $memcache->set($userKey, $users);
    }
    
    /* Invalidate them */
    $universeTag->increment(); 

*自动包含参数的功能尚未完全集成到配置过程中,但您可以通过扩展基本密钥环类并执行以下操作来轻松模拟它

class MyGames extends NoizuLabs\FragmentedKeys\KeyRing {
    public getGameDescriptionKeyObj($gameId) {
         /* Define Key in the usual manner  */

         /* . . . */

         $gameSiteId = $this->pimpleContainer['gameSite']; 
         $userId = $this->getUserId(); 
         return $this->getKeyObj("GameDescription", array( $gameId, $gameSiteId, $userId, ... etc.));
    }
}

// Now your cache code looks simple
$gameDescCacheKey = $ring->getGameDescriptionKeyObj($gameId)->getKeyStr();