我用的是间谍。我设置了几个项目。然后运行一个php脚本,但是我无法使用php memcached获得所有这些项。PHP-Memcached只能部分检索这些项。
我不能更改php的散列算法或分发策略。在我们的系统中,我们使用默认散列(根据php.net文档,这是jenkin的一次)。分发策略是针对php-memcached的模块化的。我读过间谍使用一致的散列。有没有什么方法可以让我在间谍缓存中使用模散列。
换句话说,如何使spymemcached的set操作或任何其他存储操作与php-memcached的get操作兼容?
如果spymemcached无法做到这一点,那么java中还有其他memcached客户机允许我这样做吗?
帮助不仅会受到赏识,也会得到赏赐。
Java代码:
public static void main(String [] args) {
List<InetSocketAddress> addrs = new ArrayList<>();
addrs.add(new InetSocketAddress("10.90.12.87", 11211));
addrs.add(new InetSocketAddress("10.90.12.87", 11311));
try {
MemcachedClient memcache = new MemcachedClient(addrs);
memcache.add("foo", 0, "bar");
memcache.add("sample", 0, "key");
memcache.add("try", 0, "another");
memcache.add("ax-spadg-list", 0, "3045,6645");
} catch (IOException ex) {
Logger.getLogger(CategoryDataOperator.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Done");
}PHP代码:
<?php
$mem = new Memcached();
$mem->addServer('10.90.12.87', 11211);
$mem->addServer('10.90.12.87', 11311);
var_dump $mem->get('foo');
var_dump($mem->get('try'));
var_dump($mem->get('sample'));
var_dump($mem->get('ax-spadg-list'));发布于 2013-10-03 09:07:34
问题在于Hash,默认的php-memcached散列是
(Jenkins一次)项密钥哈希算法
然而,间谍内存缓存散列的列表是:
NATIVE_HASH:简单地说,Native hash (String.hashCode()).与默认的php-memcached Memcached::HASH_DEFAULT不匹配。CRC_HASH => Memcached::HASH_CRCFNV1_64_HASH => Memcached::HASH_FNV1_64FNV1A_64_HASH => Memcached::HASH_FNV1A_64FNV1_32_HASH => Memcached::HASH_FNV1_32FNV1A_32_HASH => Memcached::HASH_FNV1A_32KETAMA_HASH =>“基于md5的散列算法,由ketama使用。所以也许是Memcached::HASH_MD5,但无论如何不是Memcached::HASH_DEFAULT因此,如果不能更改PHP客户端配置或扩展spymemcached lib,则这两个库之间没有直接匹配。
解决方案1: --如果您查看history (您可以使用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");
}
}发布于 2013-09-25 21:29:06
间谍内存缓存支持的哈希算法如下:https://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/DefaultHashAlgorithm.java
您应该能够通过使用ConnectionFactory来创建MemcachedClient来更改哈希算法。做这样的事:
ConnectionFactoryBuilder builder = new ConnectionFactoryBuilder();
builder.setHashAlgorithm(HashAlgorithm.CRC_HASH);
ConnectionFactory factory = builder.build();
MemcachedClient client = new MemcachedClient(Arrays.asList(new InetSocketAddr("localhost", 11211)), factory);发布于 2014-01-03 18:17:48
Re: Kakawait (也是Shades88)
解决方案2是不正确的,因为xmemcached没有正确地移植Jenkins散列的原始C代码,后者使用无符号。修复这个问题也将解决Shades88所看到的Shades88。
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);
// the hash variable in the original C code is a uint32.
// convert the java signed int to an "unsigned",
// represented via a long:
return hash & 0xFFFFFFFFl;
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Hash function error", e);
}
}
}
// Unit test
public class JenkinsHashTest {
@Test
public void testHash() throws Exception {
JenkinsHash j = new JenkinsHash();
Properties p = new Properties();
// This file contains k/v mappings,
// with values generated by the reference C code
p.load(new FileReader("src/test/resources/jenkinsHashTest.dat"));
for (Entry<Object, Object> entry : p.entrySet()) {
long result = j.hash((String)entry.getKey());
// Print out hash mismatches
if (result != Long.parseLong((String)entry.getValue())) {
System.out.println("Key: " + (String)entry.getKey());
System.out.println("Expected Hash Value: " + Long.parseLong((String)entry.getValue()));
System.out.println("Actual Hash Value: " + result);
}
assertEquals(result, Long.parseLong((String)entry.getValue()));
}
}
}测试数据文件是将Java代码与C代码进行比较。构建C代码,然后散列一串随机单词,并将它们映射到一个文件中,如下所示:
jenkinsHashTest.dat:
sausage=2834523395
blubber=1103975961
pencil=3318404908
cloud=670342857
moon=2385442906
water=3403519606
computer=2375101981
school=1513618861
network=2981967937
hammer=1218821080..。想加多少就加多少
https://stackoverflow.com/questions/19008990
复制相似问题