0

我正在尝试构建一个 Java 应用程序,该应用程序将在 Memcached 中设置数据,并有一个 PHP 脚本来稍后在此过程中获取相同的数据。到目前为止,我还没有找到获得 100% 命中率的方法。为了确保 SET 没有任何问题,我手动确认数据已添加到 Memcached。基于PHP 和 Java 中的 Consistent hashing,我尝试使用 KETAMA(见下面的代码)但没有成功。

配置:
- Spymemcached (2.8.1)
- PHP (5.3.10)
- PECL/memcached (2.0.1)
- libmemcached (1.0.4)

在 Java 和 PHP 之间共享数据的最佳策略是什么?有没有我没有正确使用的配置?我应该使用另一个库吗?

谢谢您的帮助!


MemcachedClient client = new MemcachedClient
(ConnectionFactory) new ConnectionFactoryBuilder ()
.setProtocol (Protocol.TEXT)
.setHashAlg (DefaultHashAlgorithm.KETAMA_HASH)
.setFailureMode (FailureMode.Redistribute)
.setLocatorType (Locator.CONSISTENT).build(),
AddrUtil.getAddresses("192.168.0.101:11211 192.168.0.102:11211"));

$memcached = new Memcached();
$memcached->addserver('192.168.0.101', 11211);
$memcached->addserver('192.168.0.102', 11211);
$memcached->setOption(Memcached::OPT_DISTRIBUTION ,Memcached::DISTRIBUTION_CONSISTENT);
$memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
4

3 回答 3

0

在 spymemcached 中,有一个KETAMA 散列算法的问题。它指的是 2.5rc1 版本,但似乎仍然会发生这种情况。

尝试另一个 java memcached 客户端:xmemcached

于 2012-07-12T08:32:46.043 回答
0

对于那些正在考虑做同样事情的人来说,有一个更好的策略。Twitter 提供了twemproxy(胡桃夹子),这是一个快速、轻量级的 memcached 代理。使用它,我不必担心 Java 和 PHP 是否使用相同的散列算法,代理会处理这个问题。

于 2012-07-13T13:17:46.930 回答
0

我也遇到了这个问题。经过几个小时的调查,我发现这是因为flagsPHP 和 Java memecached 客户端中定义的不同。

我使用xmemcached使其工作。

首先,创建一个新StringTranscoder的来解码响应,忽略标志定义并将它们全部转换为String

/**
 *
 * Php memcached extension uses flags=0 or 1 for all SET values, the default StringTranscoder in Xmemcached uses 0 for string
 *
 */
class PhpStringTranscoder extends PrimitiveTypeTranscoder<String> {

    private String charset = BaseSerializingTranscoder.DEFAULT_CHARSET;

    public PhpStringTranscoder(String charset) {
        this.charset = charset;
    }

    public PhpStringTranscoder() {
        this(BaseSerializingTranscoder.DEFAULT_CHARSET);
    }

    public String decode(CachedData d) {
            String rv = null;
            try {
                if (d.getData() != null) {
                    rv = new String(d.getData(), this.charset);
                }
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            return rv;
    }

    public static final int STRING_FLAG = 1;

    public CachedData encode(String o) {
        byte[] b;
        try {
            b = o.getBytes(this.charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return new CachedData(STRING_FLAG, b);
    }

}

最后,使用这个 newPhpStringTranscoder创建会话:

    MemcachedClientBuilder builder = new XMemcachedClientBuilder(String.format("%s:%s",address,portNum));
    builder.setCommandFactory(new TextCommandFactory());
    builder.setTranscoder(new PhpStringTranscoder());
    builder.setSessionLocator(new LibmemcachedMemcachedSessionLocator(100, HashAlgorithm.ONE_AT_A_TIME));
    MemcachedClient memcachedClient = builder.build();

memcachedClient是您应该使用的。

于 2015-10-12T02:41:38.797 回答