Java 无法使用php memcached获取使用spymemcached设置的项

Java 无法使用php memcached获取使用spymemcached设置的项,java,php,memcached,spymemcached,Java,Php,Memcached,Spymemcached,我正在使用SpymeCached。我设置了几个项目。然后我运行了一个php脚本,但是我无法使用php memcached获取所有这些项目。PHP Memcached只能部分检索这些项 我无法更改php的哈希算法或分发策略。在我们的系统中,我们使用默认哈希(根据php.net文档,这是jenkin的一次一个)。php memcached的分发策略是模。我已经读到SpymeCached使用一致散列。有什么方法可以在SpymeMached中使用模散列吗 换句话说,如何使SpymeMached的set操

我正在使用SpymeCached。我设置了几个项目。然后我运行了一个php脚本,但是我无法使用php memcached获取所有这些项目。PHP Memcached只能部分检索这些项

我无法更改php的哈希算法或分发策略。在我们的系统中,我们使用默认哈希(根据php.net文档,这是jenkin的一次一个)。php memcached的分发策略是模。我已经读到SpymeCached使用一致散列。有什么方法可以在SpymeMached中使用模散列吗

换句话说,如何使SpymeMached的set操作或任何其他存储操作与php memcached的get操作兼容

如果SpymeMached无法做到这一点,那么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");
}
publicstaticvoidmain(字符串[]args){
List addrs=new ArrayList();
addrs.add(新的InetSocketAddress(“10.90.12.87”,11211));
addrs.add(新的InetSocketAddress(“10.90.12.87”,11311));
试一试{
MemcachedClient memcache=新的MemcachedClient(addrs);
memcache.add(“foo”,0,“bar”);
memcache.add(“sample”,0,“key”);
memcache.add(“try”,0,“other”);
添加(“axspadg列表”,0,“30456645”);
}捕获(IOEX异常){
Logger.getLogger(CategoryDataOperator.class.getName()).log(Level.SEVERE,null,ex);
}
系统输出打印项次(“完成”);
}
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'));

SpymeMached支持的哈希算法如下所示:

您应该能够通过使用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);

问题在于散列,默认的php memcached散列是

(Jenkins一次一个)项密钥散列算法

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");
    }
}
而SpymeCached哈希的列表是:

  • NATIVE\u HASH
    :只需
    NATIVE HASH(String.hashCode())。
    与默认php memcached
    memcached::HASH\u default不匹配
  • CRC\u HASH
    =>
    Memcached::HASH\u CRC
  • FNV1\u 64\u HASH
    =>
    Memcached::HASH\u FNV1\u 64
  • FNV1A\u 64\u HASH
    =>
    Memcached::HASH\u FNV1A\u 64
  • FNV1\u 32\u HASH
    =>
    Memcached::HASH\u FNV1\u 32
  • FNV1A\u 32\u HASH
    =>
    Memcached::HASH\u FNV1A\u 32
  • KETAMA\u HASH
    =>“KETAMA使用的基于MD5的哈希算法。”所以可能
    Memcached::HASH\u MD5
    ,但无论如何都不是
    Memcached::HASH\u默认值
因此,如果您不能更改PHP客户端配置或扩展SpymeMached库,那么这两个库之间就没有直接匹配

解决方案1:如果您查看(您可以有一个php客户端哈希修改的示例)

解决方案2:否则您可以创建一个JenkinHash类(我复制了Xmemcached代码:[但要考虑Xmemcached许可证,并将作者/许可证保留在源代码中])

解决方案3:
一次一个\u使用
哈希算法

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");
    }
}
import net.rubyye.xmemcached.HashAlgorithm;
导入net.rubyye.xmemcached.MemcachedClient;
导入net.rubyeye.xmemcached.MemcachedClientBuilder;
导入net.rubyye.xmemcached.XMemcachedClientBuilder;
导入net.rubyeye.xmemcached.exception.MemcachedException;
导入net.rubyeye.xmemcached.impl.arraymecachedSessionLocator;
导入java.io.IOException;
导入java.net.InetSocketAddress;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.TimeoutException;
公共班机{
公共静态void main(字符串[]args)引发IOException、InterruptedException、MemcachedException、TimeoutException{
List addrs=new ArrayList();
addrs.add(新的InetSocketAddress(“127.0.0.1”,11211));
addrs.add(新的InetSocketAddress(“172.28.29.22”,11211));

MemcachedClientBuilder=newxmemcachedclientbuilder(addrs); setSessionLocator(新的ArrayMemcachedSessionLocator(HashAlgorithm.ONE_AT_A_TIME)); MemcachedClient MemcachedClient=builder.build(); memcachedClient.set(“foo”,0,“bar2”); memcachedClient.set(“sample”,0,“key”); memcachedClient.set(“try”,0,“other”); memcachedClient.set(“ax spadg list”,0,“30456645”); memcachedClient.shutdown(); 系统输出打印项次(“完成”); } }
Re:Kakawait(以及Shades88)

解决方案#2是不正确的,因为xmemcached没有正确地移植Jenkins散列的原始C代码,该散列使用了未签名的。修复此问题还将解决Shades88看到的ArrayIndexOutOfBoundsException

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()));
        }
    }
}

。。。添加所需数量

我显示的
找不到符号:CRC32
。是否有任何其他jar或我需要为CRC32添加的东西?我编辑了答案,以包含上面文件中包含的一种散列类型。以上代码应作为参考。实际上我并没有编译它。请注意,在该文件中,其他可能的散列算法有原生散列、FNV1\u 64\u散列、KETAMA\u散列等。谢谢。但是HashAlgorithm是一个接口,所以它没有您提到的字段。我使用了
DefaultHashAlgorithm.CRC\u HASH
。但是我尝试了所有的算法。什么都没用:(在php中,memcached哈希设置为默认值,即php.net上指定的詹金的一个接一个的
。我不知道SpymeMached中的默认哈希是什么。此外,php memcached具有模以及一致的默认分发策略。模是默认值。我选择了
ConnectionFactoryBuilder.Locator.ARRAY\u MOD
。但仍然没有lu。)ckYou可能有兴趣在此处阅读一点:。我已经在使用它。但是,使用SpymeMached设置的项在使用php检索它们时给我带来了麻烦
$ 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"
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");
    }
}
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()));
        }
    }
}
sausage=2834523395
blubber=1103975961
pencil=3318404908
cloud=670342857
moon=2385442906
water=3403519606
computer=2375101981
school=1513618861
network=2981967937
hammer=1218821080