【问题标题】:Java (spymemcached) and PHP (memcached)Java (spymemcached) 和 PHP (memcached)
【发布时间】:2012-07-11 20:11:37
【问题描述】:

我正在尝试构建一个 Java 应用程序,该应用程序将在 Memcached 中设置数据,并有一个 PHP 脚本来稍后在此过程中获取相同的数据。到目前为止,我还没有找到获得 100% 命中率的方法。为了确保 SET 没有任何问题,我手动确认数据已添加到 Memcached。基于Consistent hashing in PHP and Java,我尝试使用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);

【问题讨论】:

  • 对于我的测试,我使用“test_1”到“test_1000”
  • 你是说 php 客户端和 java 客户端返回不同的键值?
  • PHP 只会返回“false”,因为它无法根据给定的键找到值。它适用于 30% 的 GET,但我认为这只是因为我只有两台服务器,幸运的是它可以从正确的服务器查询。
  • 你确定你对两个客户端使用相同的哈希算法吗?
  • 我尝试过:PHP > Memcached::HASH_FNV1A_32 和 Java > DefaultHashAlgorithm.FNV1A_32_HASH。我还尝试了 PHP > Memcached::HASH_FNV1A_64 和 Java > DefaultHashAlgorithm.FNV1A_64_HASH。我终于尝试使用 PHP > Memcached::HASH_CRC 和 Java > DefaultHashAlgorithm.CRC_HASH。

标签: java php memcached


【解决方案1】:

在 spymemcached 中报告了 issue 使用 KETAMA 哈希算法。它指的是 2.5rc1 版本,但似乎仍然会发生这种情况。

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

【讨论】:

  • 感谢您的回复,仍然无法使用 xmemcached。
  • 不幸的是,xmemcached 也使用与 libmemcached 不同的字符串来计算哈希。好消息是 xmemcached 有 LibmemcachedMemcachedSessionLocator 所以试试吧。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    我使用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);
        }
    
    }
    

    最后,使用这个新的PhpStringTranscoder 创建会话:

        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 是您应该使用的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多