0

Memcached にデータを設定し、プロセスの後半で同じデータを取得するための PHP スクリプトを持つ Java アプリを構築しようとしています。これまでのところ、100% のヒット率を達成する方法を見つけることができませんでした。SET に問題がないことを確認するために、データが Memcached に追加されたことを手動で確認しました。PHP と 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);
4

3 に答える 3

0

同じことを考えている人には、より良い戦略があります。Twitter は、memcached の高速で軽量なプロキシであるtemproxy (くるみ割り人形) を提供しました。これを使用すると、Java と PHP が同じハッシュ アルゴリズムを使用しているかどうかを心配する必要はありません。プロキシがそれを処理します。

于 2012-07-13T13:17:46.930 に答える
0

spymemcachedでは、KETAMA ハッシュ アルゴリズムに関する問題が報告されています。バージョン 2.5rc1 を参照していますが、これはまだ発生しているようです。

別の Java memcached クライアントを試してください: xmemcached

于 2012-07-12T08:32:46.043 に答える
0

私もこの問題に遭遇しました。何時間もの調査の結果、これはflagsPHP と Java の memecached クライアントで定義されている違いによるものであることがわかりました。

xmemcachedを使用して動作させました。

最初にStringTranscoder、フラグ定義を無視してレスポンスをデコードするための new を作成し、それらすべてを次のように変換します。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 に答える