Spymemcached’s client configuration is surprisingly flexible, allowing you to tune everything from connection timeouts to the very way it serializes your Java objects.
Let’s see it in action. Imagine you have a simple User object:
public class User {
private String id;
private String name;
private int age;
// Constructor, getters, setters
}
And you want to store and retrieve it from Memcached using Spymemcached. Here’s a basic client setup:
import net.spy.memcached.MemcachedClient;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
public class MemcachedClientConfig {
public static void main(String[] args) throws Exception {
MemcachedClient mcc = new MemcachedClient(
new ConnectionFactoryBuilder()
.setProtocol(ConnectionFactoryBuilder.Protocol.BINARY) // Use binary protocol
.setOpTimeout(5000) // Operation timeout in milliseconds
.setTranscoder(new SerializingTranscoder()) // Default Java serialization
.build(),
new InetSocketAddress("localhost", 11211) // Memcached server address
);
User user = new User("user123", "Alice", 30);
// Store the object
mcc.set("user:user123", 600, user); // Key, expiration (seconds), value
// Retrieve the object
User retrievedUser = (User) mcc.get("user:user123");
if (retrievedUser != null) {
System.out.println("Retrieved User: " + retrievedUser.getName());
} else {
System.out.println("User not found.");
}
mcc.shutdown(1, TimeUnit.SECONDS); // Shutdown gracefully
}
}
This sets up a client connecting to localhost:11211. It uses the binary protocol (generally more efficient), sets an operation timeout of 5 seconds, and uses the default Java serialization. The set operation stores the User object with a key user:user123 and an expiration of 10 minutes (600 seconds). get then retrieves it.
The core of Spymemcached’s configuration lies in the ConnectionFactoryBuilder. This builder allows you to customize various aspects of how the client interacts with Memcached servers.
First, the protocol. You can choose between TEXT (ASCII) and BINARY. The binary protocol is generally preferred for performance and efficiency, especially when dealing with non-string data.
.setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
Next, timeouts. Spymemcached offers several timeout configurations:
setOpTimeout(long timeout): This is the operation timeout. It defines the maximum time Spymemcached will wait for a response from the Memcached server after sending an operation. If the server doesn’t respond within this time, the operation fails.setConnectTimeout(int timeout): This is the connection timeout. It specifies how long the client will attempt to establish a connection to a Memcached server. If a connection cannot be made within this period, it’s considered a failure.setReadTimeout(long timeout): This is the read timeout. It’s the maximum time Spymemcached will wait for data to be read from the socket after an operation has been initiated. This is distinct fromsetOpTimeoutwhich is the total time for the operation including the read.
.setOpTimeout(5000) // 5 seconds
The transcoder is crucial for handling data serialization and deserialization. By default, Spymemcached uses net.spy.memcached.transcoders.SerializingTranscoder, which relies on Java’s built-in ObjectOutputStream and ObjectInputStream. This is convenient for storing arbitrary Java objects but can be inefficient and has versioning issues. For better performance and more control, you might implement your own transcoder (e.g., using JSON libraries like Jackson or Gson).
.setTranscoder(new CustomJsonTranscoder()) // Example for JSON
When dealing with multiple Memcached servers, you configure them as a list of InetSocketAddress objects. Spymemcached uses a consistent hashing algorithm to distribute keys across these servers.
List<InetSocketAddress> servers = Arrays.asList(
new InetSocketAddress("memcached1.example.com", 11211),
new InetSocketAddress("memcached2.example.com", 11211)
);
MemcachedClient mcc = new MemcachedClient(new ConnectionFactoryBuilder().build(), servers);
You can also configure read and write buffers. While defaults are usually fine, you can adjust setReadBufferSize and setWriteQueueCapacity if you’re seeing performance bottlenecks related to network I/O.
.setReadBufferSize(2 << 16) // 64KB read buffer
The ConnectionFactoryBuilder also allows you to configure authentication if your Memcached servers require it, using setAuthDescriptor.
When Spymemcached establishes connections, it doesn’t do so all at once for all servers. Instead, it lazily connects to each server as needed when a key mapping to that server is first accessed. This means the first operation to a particular server might experience a slight delay as the connection is established. Subsequent operations to that server will be faster.
One aspect often overlooked is how Spymemcached handles lost connections. By default, it attempts to re-establish connections periodically. You can tune the setFailureMode and setRetry parameters in the ConnectionFactoryBuilder to control this behavior, but be aware that aggressive retries can sometimes mask underlying network issues.
The next step in mastering Spymemcached configuration involves understanding its event listeners and watcher mechanisms, which allow you to react to connection status changes and other important lifecycle events.