問題はハッシュに関するもので、デフォルトの php-memcached ハッシュは
(Jenkins 1 つずつ) アイテム キー ハッシュ アルゴリズム
一方、spymemcached ハッシュのリストは次のとおりです。
NATIVE_HASH
: デフォルトの php-memcached と単純Native hash (String.hashCode()).
に一致しませんMemcached::HASH_DEFAULT
CRC_HASH
=>Memcached::HASH_CRC
FNV1_64_HASH
=>Memcached::HASH_FNV1_64
FNV1A_64_HASH
=>Memcached::HASH_FNV1A_64
FNV1_32_HASH
=>Memcached::HASH_FNV1_32
FNV1A_32_HASH
=>Memcached::HASH_FNV1A_32
KETAMA_HASH
=> 「ketama が使用する MD5 ベースのハッシュ アルゴリズム。」そうかもしれませんMemcached::HASH_MD5
が、とにかくそうではありませんMemcached::HASH_DEFAULT
そのため、PHP クライアントの構成を変更したり、spymemcached ライブラリを拡張したりできない場合、2 つのライブラリが直接一致することはありません。
解決策 1:履歴を見ると(PHP クライアント ハッシュ変更の例を確認できます)。
解決策2:それ以外の場合は、JenkinHash クラスを作成できます (Xmemcached コードをコピーします: https://code.google.com/p/xmemcached/source/browse/trunk/src/main/java/net/rubyeye/xmemcached/ HashAlgorithm.java?r=801#176 [ただし、Xmemcached ライセンスを考慮し、ソース コード内に作成者/ライセンスを保持する])
import net.spy.memcached.HashAlgorithm;
import java.io.UnsupportedEncodingException;
public class JenkinsHash implements HashAlgorithm {
@Override
public long hash(String k) {
try {
int hash = 0;
for (byte bt : k.getBytes("utf-8")) {
hash += (bt & 0xFF);
hash += (hash << 10);
hash ^= (hash >>> 6);
}
hash += (hash << 3);
hash ^= (hash >>> 11);
hash += (hash << 15);
return hash;
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Hash function error", e);
}
}
}
それから:
import net.spy.memcached.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) throws IOException {
List<InetSocketAddress> addrs = new ArrayList<InetSocketAddress>();
addrs.add(new InetSocketAddress("127.0.0.1", 11211));
addrs.add(new InetSocketAddress("172.28.29.22", 11211));
try {
ConnectionFactory connectionFactory = new ConnectionFactoryBuilder()
.setProtocol(ConnectionFactoryBuilder.Protocol.TEXT)
.setHashAlg(new JenkinsHash())
.setLocatorType(ConnectionFactoryBuilder.Locator.ARRAY_MOD).build();
MemcachedClient memcache = new MemcachedClient(connectionFactory, addrs);
memcache.add("foo", 0, "bar2");
memcache.add("sample", 0, "key");
memcache.add("try", 0, "another");
memcache.add("ax-spadg-list", 0, "3045,6645");
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Done");
}
}
PHP スクリプトを使用する場合:
<?php
$memcached = new Memcached();
$memcached->addserver('127.0.0.1', 11211);
$memcached->addserver('172.28.29.22', 11211);
var_dump($memcached->get('foo'));
var_dump($memcached->get('try'));
var_dump($memcached->get('sample'));
var_dump($memcached->get('ax-spadg-list'));
テスト:
$ echo "flush_all" | nc 172.28.29.22 11211 && echo "flush_all" | nc 127.0.0.1 11211
OK
OK
$ php mem.php
bool(false)
bool(false)
bool(false)
bool(false)
RUN JAVA
$ php mem.php
string(4) "bar2"
string(7) "another"
string(3) "key"
string(9) "3045,6645"
解決策 3:ハッシュ アルゴリズムでhttps://code.google.com/p/xmemcached/を使用するONE_AT_A_TIME
import net.rubyeye.xmemcached.HashAlgorithm;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.impl.ArrayMemcachedSessionLocator;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException, MemcachedException, TimeoutException {
List<InetSocketAddress> addrs = new ArrayList<InetSocketAddress>();
addrs.add(new InetSocketAddress("127.0.0.1", 11211));
addrs.add(new InetSocketAddress("172.28.29.22", 11211));
MemcachedClientBuilder builder = new XMemcachedClientBuilder(addrs);
builder.setSessionLocator(new ArrayMemcachedSessionLocator(HashAlgorithm.ONE_AT_A_TIME));
MemcachedClient memcachedClient = builder.build();
memcachedClient.set("foo", 0, "bar2");
memcachedClient.set("sample", 0, "key");
memcachedClient.set("try", 0, "another");
memcachedClient.set("ax-spadg-list", 0, "3045,6645");
memcachedClient.shutdown();
System.out.println("Done");
}
}