跨多个服务器使用Zend Cache和AWS ElastiCache的缓存值不一致

时间:2012-09-17 20:14:25

标签: php zend-framework caching amazon-web-services amazon-elasticache

我们正在使用Zend Cache和memcached后端,该后端指向具有2个缓存节点的AWS ElastiCache群集。我们的缓存设置如下所示:

$frontend = array(
    'lifetime' => (60*60*48),
    'automatic_serialization' => true,
    'cache_id_prefix' => $prefix
);
$backend = array(
    'servers' => array(
        array( 'host' => $node1 ),
        array( 'host' => $node2 )
    )
);
$cache = Zend_Cache::factory('Output', 'memecached', $frontend, $backend);

我们没有注意到过去使用单个EC2服务器从缓存中写入和读取时缓存有任何问题。

但是,我们最近推出了第二个EC2服务器,突然间我们从一个服务器写入缓存并从另一个服务器读取时遇到问题。两个服务器都由同一AWS账户管理,并且两个服务器都没有分别写入缓存或从缓存读取的问题。两者都使用相同的缓存配置。

服务器A 执行$cache->save('hello', 'message');

服务器A 调用$cache->load('message');会返回 hello 的预期结果。

但是,当服务器B 执行$cache->load('message');时,我们会 false

就我对ElastiCache的理解而言,发出读取请求的服务器应该对返回的缓存值没有影响。任何人都可以对此有所了解吗?

2 个答案:

答案 0 :(得分:1)

你能说出你用于memcache的hash_strategy吗?我在过去使用默认的标准时遇到了问题,但自从更改为一致后一切都很好:

http://php.net/manual/en/memcache.ini.php#ini.memcache.hash-strategy

答案 1 :(得分:0)

使用正常的散列算法,更改服务器数量可能会导致许多密钥重新映射到不同的服务器,从而导致大量缓存未命中。

想象一下,在缓存群集中有5个ElastiCache节点,添加第六个服务器可能会导致40%以上的密钥突然指向不同于正常的服务器。此活动是不受欢迎的,可能会导致缓存未命中,并最终使请求淹没您的后端数据库。要最大限度地减少此重新映射,建议您在缓存客户端中遵循一致的哈希模型。

Consistent Hashing是一种模型,允许在添加或删除服务器时更稳定地分发密钥。 Consistent Hashing描述了将密钥映射到服务器列表的方法,其中添加或删除服务器会导致密钥映射到的位置发生非常小的转换。使用此方法,添加第十一个服务器应该会导致少于10%的密钥被重新分配。这个百分比可能在生产中有所不同,但与普通哈希算法相比,它在这种弹性场景中效率更高。还建议在使用一致哈希时,在所有客户端配置中保持memcached服务器顺序和服务器数量相同。 Java应用程序可以通过spymemcached使用“Ketama库”将此算法集成到他们的系统中。有关一致性哈希的更多信息,请访问http://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients