Search in sources :

Example 21 with MemcachedClient

use of net.spy.memcached.MemcachedClient in project zm-mailbox by Zimbra.

the class ZimbraMemcachedClient method connect.

/**
 * Connects/reconnects the memcached client with server list, protocol and hashing algorithm.
 * @param servers memcached server list
 * @param useBinaryProtocol if true, use the binary protocol; if false, use the ascii protocol
 * @param hashAlgorithm net.spy.memcached.HashAlgorithm enum
 * @param defaultExpiry in seconds
 * @param defaultTimeout in milliseconds
 * @throws ServiceException
 */
public void connect(String[] servers, boolean useBinaryProtocol, String hashAlgorithm, int defaultExpiry, long defaultTimeout) throws ServiceException {
    // Force spymemcached to use log4j rather than raw stdout/stderr.
    Properties props = System.getProperties();
    props.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.Log4JLogger");
    HashAlgorithm hashAlgo = DefaultHashAlgorithm.KETAMA_HASH;
    if (hashAlgorithm != null && hashAlgorithm.length() > 0) {
        HashAlgorithm ha = DefaultHashAlgorithm.valueOf(hashAlgorithm);
        if (ha != null)
            hashAlgo = ha;
    }
    int qLen = DefaultConnectionFactory.DEFAULT_OP_QUEUE_LEN;
    int bufSize = DefaultConnectionFactory.DEFAULT_READ_BUFFER_SIZE;
    MemcachedClient client = null;
    StringBuilder serverList = new StringBuilder();
    if (servers != null && servers.length > 0) {
        // Eliminate duplicates and sort case-insensitively.  This negates operator error
        // configuring server list with inconsistent order on different memcached clients.
        // TreeSet provides deduping and sorting.
        TreeSet<String> tset = new TreeSet<String>();
        for (int i = 0; i < servers.length; ++i) {
            tset.add(servers[i].toLowerCase());
        }
        for (String s : tset) {
            if (serverList.length() > 0)
                serverList.append(", ");
            serverList.append(s);
        }
        List<InetSocketAddress> serverAddrs = parseServerList(tset.toArray(new String[0]));
        ConnectionFactory cf;
        if (useBinaryProtocol)
            cf = new BinaryConnectionFactory(qLen, bufSize, hashAlgo);
        else
            cf = new DefaultConnectionFactory(qLen, bufSize, hashAlgo);
        try {
            client = new MemcachedClient(cf, serverAddrs);
            boolean added = client.addObserver(new ConnObserver());
            if (!added)
                ZimbraLog.misc.error("Unable to add connection observer to memcached client");
        } catch (IOException e) {
            throw ServiceException.FAILURE("Unable to initialize memcached client", e);
        }
    }
    MemcachedClient oldClient = null;
    synchronized (this) {
        oldClient = mMCDClient;
        mMCDClient = client;
        mDefaultExpiry = defaultExpiry;
        mDefaultTimeout = defaultTimeout;
        mServerList = serverList.length() > 0 ? serverList.toString() : null;
        mHashAlgorithm = hashAlgo.toString();
        mBinaryProtocolEnabled = useBinaryProtocol;
    }
    // New client is ready for use by other threads at this point.
    if (oldClient != null)
        disconnect(oldClient, 30000);
}
Also used : DefaultConnectionFactory(net.spy.memcached.DefaultConnectionFactory) InetSocketAddress(java.net.InetSocketAddress) BinaryConnectionFactory(net.spy.memcached.BinaryConnectionFactory) IOException(java.io.IOException) Properties(java.util.Properties) ConnectionFactory(net.spy.memcached.ConnectionFactory) DefaultConnectionFactory(net.spy.memcached.DefaultConnectionFactory) BinaryConnectionFactory(net.spy.memcached.BinaryConnectionFactory) TreeSet(java.util.TreeSet) MemcachedClient(net.spy.memcached.MemcachedClient) DefaultHashAlgorithm(net.spy.memcached.DefaultHashAlgorithm) HashAlgorithm(net.spy.memcached.HashAlgorithm)

Example 22 with MemcachedClient

use of net.spy.memcached.MemcachedClient in project zm-mailbox by Zimbra.

the class ZimbraMemcachedClient method putBigByteArray.

/**
 * Puts the key/value pair for a big byte array.
 *
 * A big byte array value is a byte array whose length can be greater than memcached limit of 1MB.
 * If the data is smaller than MAX_CHUNK_SIZE (1MB - 1KB) it is set in a single key/value pair in
 * memcached, with the value suffixed with a "V". (V for value)  If the data is bigger, the data is
 * split into MAX_CHUNK_SIZE chunks and set as individual cache entries.  The cache keys for the
 * chunks are the combination of the original key, the data "fingerprint" (for some uniqueness),
 * and chunk number.  The cache value for the original key is set to a table of contents containing
 * the number of chunks, the fingerprint, and length and checksum of each chunk, followed by a "T".
 * (T for table of contents)
 *
 * During retrieval, the value for the main key is examined to see if the last byte is a V or T.  If
 * it's a V, the preceding bytes constitute the entire cache value.  If it's a T, the preceding bytes
 * are interpreted as the table of contents.  The information in the table of contents can be used
 * to then fetch the chunks and reassemble them.  All chunks must exist and must match the length and
 * checksum in the table of contents.  Otherwise the whole get operation is considered a cache miss.
 *
 * When the main key is updated or removed, the chunk values become orphaned because the table of contents
 * will no longer contain the same fingerprint.  (Some collision risk exists.)  These entries will age
 * out of the cache eventually.
 *
 * Example of a short value:
 *
 * key = "foo", value = ['b', 'a', 'r']
 * Memcached will have "foo" = ['b', 'a', 'r', 'V'].
 *
 * Example of a big value:
 *
 * key = "foo", value = <1.5MB byte array>
 * Assume the fingerprint computed is 1234567890.
 * Memcached will have:
 *   "foo" = <table of contents> 'T'
 *   "foo:1234567890.0" = <1st chunk of ~1MB>
 *   "foo:1234567890.1" = <2nd chunk of ~0.5MB>
 *
 * @param key
 * @param value
 * @param expirySec expiry in seconds
 * @param timeout in millis
 * @param waitForAck if true, block until ack'd or timeout; if false, return immediately
 * @return
 */
public boolean putBigByteArray(String key, byte[] value, int expirySec, long timeout, boolean waitForAck) {
    MemcachedClient client;
    synchronized (this) {
        client = mMCDClient;
        if (expirySec == DEFAULT_EXPIRY)
            expirySec = mDefaultExpiry;
        if (timeout == DEFAULT_TIMEOUT)
            timeout = mDefaultTimeout;
    }
    if (client == null)
        return false;
    ByteArrayTranscoder bat = new ByteArrayTranscoder();
    ByteArray mainValue;
    if (value.length < MAX_CHUNK_SIZE) {
        // Value is short enough.  Set it directly, with a prefix.  Requires 1 memcached set operation.
        byte[] prefixed = new byte[value.length + 1];
        System.arraycopy(value, 0, prefixed, 0, value.length);
        prefixed[value.length] = BBA_PREFIX_VALUE;
        mainValue = new ByteArray(prefixed);
    } else {
        // Value can't fit in a single memcached entry.  Split into chunks and use table of contents.
        // Requires N+1 memcached set operations.
        ByteArrayChunks chunks;
        try {
            chunks = new ByteArrayChunks(value);
        } catch (ServiceException e) {
            ZimbraLog.misc.warn("Unable to split byte array into chunks", e);
            return false;
        }
        ByteArrayChunksTOC toc = chunks.makeTOC();
        // Add chunks to the cache.
        String chunkKeyPrefix = key + ":" + toc.getFingerprint() + ".";
        int numChunks = chunks.getNumChunks();
        for (int i = 0; i < numChunks; ++i) {
            String chunkKey = chunkKeyPrefix + i;
            ByteArray byteArray = chunks.getChunk(i);
            Future<Boolean> future = client.set(chunkKey, expirySec, byteArray, bat);
            if (waitForAck) {
                Boolean success = null;
                try {
                    success = future.get(timeout, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    ZimbraLog.misc.warn("memcached set timed out after " + timeout + "ms", e);
                    future.cancel(false);
                } catch (InterruptedException e) {
                    ZimbraLog.misc.warn("InterruptedException during memcached set operation", e);
                } catch (ExecutionException e) {
                    ZimbraLog.misc.warn("ExecutionException during memcached set operation", e);
                }
                if (success == null || !success.booleanValue())
                    return false;
            }
        }
        // Put the table of contents as the main value.  Do this after all chunks have been
        // added successfully.
        byte[] tocBytes;
        try {
            tocBytes = toc.encode().getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            ZimbraLog.misc.warn("Unable to get bytes for BBA table of contents", e);
            return false;
        }
        byte[] prefixed = new byte[tocBytes.length + 1];
        System.arraycopy(tocBytes, 0, prefixed, 0, tocBytes.length);
        prefixed[tocBytes.length] = BBA_PREFIX_TOC;
        mainValue = new ByteArray(prefixed);
    }
    // Put the main value.
    Future<Boolean> future = client.set(key, expirySec, mainValue, bat);
    if (waitForAck) {
        Boolean success = null;
        try {
            success = future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            ZimbraLog.misc.warn("memcached set timed out after " + timeout + "ms", e);
            future.cancel(false);
        } catch (InterruptedException e) {
            ZimbraLog.misc.warn("InterruptedException during memcached set operation", e);
        } catch (ExecutionException e) {
            ZimbraLog.misc.warn("ExecutionException during memcached set operation", e);
        }
        return success != null && success.booleanValue();
    } else {
        return true;
    }
}
Also used : UnsupportedEncodingException(java.io.UnsupportedEncodingException) ServiceException(com.zimbra.common.service.ServiceException) MemcachedClient(net.spy.memcached.MemcachedClient) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Example 23 with MemcachedClient

use of net.spy.memcached.MemcachedClient in project zm-mailbox by Zimbra.

the class ZimbraMemcachedClient method get.

/**
 * Retrieves the value corresponding to the given key.
 * @param key
 * @param timeout in millis
 * @return null if no value is found for the key
 */
public Object get(String key, long timeout) {
    Object value = null;
    MemcachedClient client;
    synchronized (this) {
        client = mMCDClient;
        if (timeout == DEFAULT_TIMEOUT)
            timeout = mDefaultTimeout;
    }
    if (client == null)
        return null;
    Future<Object> future = client.asyncGet(key);
    try {
        value = future.get(timeout, TimeUnit.MILLISECONDS);
    } catch (TimeoutException e) {
        ZimbraLog.misc.warn("memcached asyncGet timed out after " + timeout + "ms", e);
        future.cancel(false);
    } catch (InterruptedException e) {
        ZimbraLog.misc.warn("InterruptedException during memcached asyncGet operation", e);
    } catch (ExecutionException e) {
        ZimbraLog.misc.warn("ExecutionException during memcached asyncGet operation", e);
    }
    return value;
}
Also used : MemcachedClient(net.spy.memcached.MemcachedClient) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Example 24 with MemcachedClient

use of net.spy.memcached.MemcachedClient in project DataX by alibaba.

the class ConfigurationChecker method hostReachableCheck.

/**
 * 检查ocs服务器网络是否可达
 */
private static void hostReachableCheck(Configuration config) {
    String proxy = config.getString(Key.PROXY);
    String port = config.getString(Key.PORT);
    String username = config.getString(Key.USER);
    String password = config.getString(Key.PASSWORD);
    AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" }, new PlainCallbackHandler(username, password));
    try {
        MemcachedClient client = new MemcachedClient(new ConnectionFactoryBuilder().setProtocol(ConnectionFactoryBuilder.Protocol.BINARY).setAuthDescriptor(ad).build(), AddrUtil.getAddresses(proxy + ":" + port));
        client.get("for_check_connectivity");
        client.getVersions();
        if (client.getAvailableServers().isEmpty()) {
            throw new RuntimeException("没有可用的Servers: getAvailableServers() -> is empty");
        }
        client.shutdown();
    } catch (Exception e) {
        throw DataXException.asDataXException(OcsWriterErrorCode.HOST_UNREACHABLE, String.format("OCS[%s]服务不可用", proxy), e);
    }
}
Also used : PlainCallbackHandler(net.spy.memcached.auth.PlainCallbackHandler) ConnectionFactoryBuilder(net.spy.memcached.ConnectionFactoryBuilder) AuthDescriptor(net.spy.memcached.auth.AuthDescriptor) MemcachedClient(net.spy.memcached.MemcachedClient) DataXException(com.alibaba.datax.common.exception.DataXException)

Example 25 with MemcachedClient

use of net.spy.memcached.MemcachedClient in project hazelcast by hazelcast.

the class InvalidEndpointTest method attemptMemcacheOnHttpEndpoint.

@Test
public void attemptMemcacheOnHttpEndpoint() throws IOException, InterruptedException {
    Config config = createRestEndpointConfig();
    HazelcastInstance instance = factory.newHazelcastInstance(config);
    // Invalid endpoint - points to REST
    InetSocketAddress address = instance.getCluster().getLocalMember().getSocketAddress(REST);
    ConnectionFactory factory = new ConnectionFactoryBuilder().setOpTimeout(60 * 60 * 60).setDaemon(true).setFailureMode(FailureMode.Retry).build();
    MemcachedClient client = new MemcachedClient(factory, Collections.singletonList(address));
    try {
        client.set("one", 0, "two").get();
        fail("Should not be able to connect");
    } catch (InterruptedException e) {
        ignore(e);
    } catch (ExecutionException e) {
        ignore(e);
    }
    shutdownQuietly(client);
}
Also used : ConnectionFactoryBuilder(net.spy.memcached.ConnectionFactoryBuilder) ConnectionFactory(net.spy.memcached.ConnectionFactory) HazelcastInstance(com.hazelcast.core.HazelcastInstance) Config(com.hazelcast.config.Config) ServerSocketEndpointConfig(com.hazelcast.config.ServerSocketEndpointConfig) RestServerEndpointConfig(com.hazelcast.config.RestServerEndpointConfig) InetSocketAddress(java.net.InetSocketAddress) MemcachedClient(net.spy.memcached.MemcachedClient) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test) SlowTest(com.hazelcast.test.annotation.SlowTest)

Aggregations

MemcachedClient (net.spy.memcached.MemcachedClient)52 Test (org.junit.Test)22 IntegrationTest (org.apache.geode.test.junit.categories.IntegrationTest)20 FlakyTest (org.apache.geode.test.junit.categories.FlakyTest)17 InetSocketAddress (java.net.InetSocketAddress)11 ExecutionException (java.util.concurrent.ExecutionException)9 ConnectionFactoryBuilder (net.spy.memcached.ConnectionFactoryBuilder)8 ConnectionFactory (net.spy.memcached.ConnectionFactory)7 IOException (java.io.IOException)6 TimeoutException (java.util.concurrent.TimeoutException)6 Map (java.util.Map)5 HashMap (java.util.HashMap)4 ArrayList (java.util.ArrayList)3 Properties (java.util.Properties)3 BinaryConnectionFactory (net.spy.memcached.BinaryConnectionFactory)3 Predicate (com.google.common.base.Predicate)2 Supplier (com.google.common.base.Supplier)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 ImmutableSet (com.google.common.collect.ImmutableSet)2 Config (com.hazelcast.config.Config)2