跨多个服务器将 Zend Cache 与 AWS 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 对 的后续调用将返回 hello 的预期结果。$cache->load('message');

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

就我对ElastiCache的理解而言,发出读取请求的服务器应该与返回的缓存值无关。谁能对此有所了解?


答案 1

你能说出你用什么hash_strategy来做记忆缓存吗?我过去在使用默认标准时遇到过问题,但自从更改为一致以来,一切都很好:

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


答案 2

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

假设您的缓存集群中有 5 个 ElastiCache 节点,添加第六台服务器可能会导致 40% 以上的密钥突然指向与平常不同的服务器。此活动是不可取的,可能会导致缓存未命中,并最终用请求淹没后端数据库。为了最大限度地减少这种重新映射,建议在缓存客户端中遵循一致的哈希模型。

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


推荐