杰瑞科技汇

Memcache Java客户端如何高效连接与使用?

Of course! Here is a comprehensive guide to using a Java client for Memcached, covering the most popular client, its setup, basic operations, and best practices.

Memcache Java客户端如何高效连接与使用?-图1
(图片来源网络,侵删)

The Most Popular Java Client: Spymemcached

For a long time, SpyMemcached was the de-facto standard Java client for Memcached. It's known for being lightweight, simple, and asynchronous.

However, it's important to note that SpyMemcached is no longer actively maintained. The last release was in 2025. While it still works perfectly fine with modern Memcached servers, it does not receive updates or bug fixes.

A more modern and actively maintained alternative is Xmemcached. We will cover both, but the examples will primarily focus on SpyMemcached due to its widespread historical use and simplicity, with a note on how to transition to Xmemcached.


Setup with SpyMemcached (Maven)

First, you need to add the SpyMemcached dependency to your pom.xml file.

Memcache Java客户端如何高效连接与使用?-图2
(图片来源网络,侵删)
<dependency>
    <groupId>net.spy</groupId>
    <artifactId>spymemcached</artifactId>
    <version>2.12.3</version> <!-- Use a recent version from the 2.12.x line -->
</dependency>

Connecting to Memcached

The entry point to the client is the MemcachedClient class. You'll need to provide it with a list of Memcached server addresses.

import net.spy.memcached.AddrUtil;
import net.spy.memcached.MemcachedClient;
public class MemcachedConnectionExample {
    public static void main(String[] args) {
        try {
            // Connect to a Memcached server on localhost (port 11211)
            MemcachedClient mcc = new MemcachedClient(
                AddrUtil.getAddresses("localhost:11211")
            );
            System.out.println("Successfully connected to Memcached!");
            // Don't forget to shut down the client when you're done
            mcc.shutdown();
        } catch (Exception e) {
            System.err.println("Error connecting to Memcached: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Basic Operations (CRUD)

SpyMemcached uses a Future-based API for all operations, which is a key part of its asynchronous nature.

Setting a Key-Value Pair

The set operation adds a key-value pair to the cache. You can also specify an expiration time.

import net.spy.memcached.MemcachedClient;
import net.spy.memcached.internal.OperationFuture;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
// ... inside your class
MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("localhost", 11211));
try {
    // Set a key "user:1001" with value "Alice" to expire in 3600 seconds (1 hour)
    OperationFuture<Boolean> setFuture = mcc.set("user:1001", 3600, "Alice");
    // The get() method blocks until the operation completes
    boolean success = setFuture.get();
    if (success) {
        System.out.println("Set operation was successful.");
    } else {
        System.out.println("Set operation failed.");
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    mcc.shutdown();
}

Getting a Value by Key

The get operation retrieves the value for a given key.

Memcache Java客户端如何高效连接与使用?-图3
(图片来源网络,侵删)
// ... after setting the value as above
try {
    // Get the value for the key "user:1001"
    Object myObject = mcc.get("user:1001");
    if (myObject != null) {
        // The result is an Object, so you need to cast it
        String userName = (String) myObject;
        System.out.println("Retrieved user name: " + userName);
    } else {
        System.out.println("Key 'user:1001' not found in cache.");
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    mcc.shutdown();
}

Deleting a Key

The delete operation removes a key-value pair from the cache.

// ... after setting the value
try {
    OperationFuture<Boolean> deleteFuture = mcc.delete("user:1001");
    boolean success = deleteFuture.get();
    if (success) {
        System.out.println("Key 'user:1001' was successfully deleted.");
    } else {
        System.out.println("Failed to delete key 'user:1001'. It might not exist.");
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    mcc.shutdown();
}

Adding and Replacing (Atomic Operations)

  • add: Adds a key-value pair only if the key does not already exist. If it exists, the operation fails.
  • replace: Replaces a key-value pair only if the key already exists. If it doesn't exist, the operation fails.
try {
    // Add will succeed because the key doesn't exist
    mcc.add("new_key", 300, "new_value").get();
    // Add will fail this time because the key now exists
    mcc.add("new_key", 300, "another_value").get(); // This will return false
    // Replace will succeed because the key exists
    mcc.replace("new_key", 300, "replaced_value").get();
    // Replace will fail this time because we deleted the key
    mcc.delete("new_key").get();
    mcc.replace("new_key", 300, "will_fail").get(); // This will return false
} catch (Exception e) {
    e.printStackTrace();
}

Working with Custom Java Objects

By default, SpyMemcached uses Java's built-in serialization. For custom objects, your class must implement the Serializable interface.

import java.io.Serializable;
public class User implements Serializable {
    private String name;
    private int age;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
}

Now you can store and retrieve this object directly:

MemcachedClient mcc = new MemcachedClient(AddrUtil.getAddresses("localhost:11211"));
User user = new User("Bob", 30);
// Store the custom object
mcc.set("user:1002", 3600, user);
// Retrieve the custom object
User retrievedUser = (User) mcc.get("user:1002");
System.out.println("Retrieved user: " + retrievedUser); // Will call the toString() method
mcc.shutdown();

Advanced Features

CAS (Check-And-Set) for Atomic Operations

CAS is a powerful feature to prevent lost updates. It uses a unique 64-bit value (the "cas id") for each item. You can get the cas id when you retrieve an item and then use it in an update operation to ensure you're modifying the exact version you read.

// Set a value first
mcc.set("counter", 0, 10).get();
// Get the value and its CAS id
CASValue<Object> casValue = mcc.gets("counter");
long casId = casValue.getCas();
Integer counterValue = (Integer) casValue.getValue();
System.out.println("Initial counter: " + counterValue + " with CAS ID: " + casId);
// Atomically increment the counter if it hasn't changed since we read it
// The 'cas' method will only succeed if the casId matches the one on the server
OperationFuture<CASResponse> casResult = mcc.cas("counter", casId, counterValue + 1);
CASResponse response = casResult.get();
if (response == CASResponse.OK) {
    System.out.println("CAS operation successful. Counter incremented.");
} else {
    System.out.println("CAS operation failed. Counter was modified by another process.");
}
mcc.shutdown();

Alternative: Xmemcached

Xmemcached is a more modern, actively maintained client with a feature-rich API, including support for the binary protocol and better performance in some scenarios.

Setup (Maven)

<dependency>
    <groupId>com.googlecode.xmemcached</groupId>
    <artifactId>xmemcached</artifactId>
    <version>2.4.7</version> <!-- Check for the latest version -->
</dependency>

Basic Example with Xmemcached

The API is slightly different but conceptually similar.

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.utils.AddrUtil;
public class XmemcachedExample {
    public static void main(String[] args) {
        MemcachedClientBuilder builder = new XMemcachedClientBuilder(
            AddrUtil.getAddresses("localhost:11211")
        );
        try (MemcachedClient mcc = builder.build()) { // The try-with-resources statement ensures shutdown
            System.out.println("Successfully connected to Memcached with Xmemcached!");
            // Set
            mcc.set("user:2001", 3600, "Charlie");
            System.out.println("Set 'user:2001' to Charlie.");
分享:
扫描分享到社交APP
上一篇
下一篇