Memcached客户端库 #
一、客户端库概述 #
1.1 主流客户端库 #
text
各语言主流Memcached客户端:
Java:
- Xmemcached
- SpyMemcached
- Enqueue Memcached
Python:
- pymemcache
- python-memcached
- aiomcache(异步)
PHP:
- memcached扩展
- memcache扩展
Go:
- gomemcache
- mc
Node.js:
- memcached
- memjs
Ruby:
- dalli
- memcached
1.2 客户端选择标准 #
text
选择客户端库的标准:
1. 性能
- 连接池支持
- 异步操作
- 批量操作
2. 功能
- 一致性哈希
- 自动故障转移
- 序列化支持
3. 稳定性
- 活跃维护
- 文档完善
- 社区支持
4. 易用性
- API简洁
- 配置简单
- 错误处理
二、Java客户端 #
2.1 Xmemcached #
xml
<!-- Maven依赖 -->
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.7</version>
</dependency>
java
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) throws Exception {
// 创建客户端
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("localhost:11211")
);
MemcachedClient client = builder.build();
// 存储数据
client.set("user:1001", 3600, "{\"name\":\"John\",\"age\":25}");
// 获取数据
String value = client.get("user:1001");
System.out.println(value);
// 删除数据
client.delete("user:1001");
// 递增
long result = client.incr("counter", 1, 0);
System.out.println(result);
// 关闭客户端
client.shutdown();
}
}
2.2 连接池配置 #
java
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.utils.AddrUtil;
public class XmemcachedPoolExample {
public static void main(String[] args) throws Exception {
// 创建客户端构建器
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("localhost:11211,localhost:11212")
);
// 配置连接池
builder.setConnectionPoolSize(10); // 连接池大小
builder.setConnectTimeout(1000); // 连接超时(毫秒)
builder.setOpTimeout(1000); // 操作超时(毫秒)
// 配置一致性哈希
builder.setSessionLocator(new KetamaMemcachedSessionLocator());
// 配置序列化
builder.setTranscoder(new SerializingTranscoder());
MemcachedClient client = builder.build();
// 使用客户端...
client.shutdown();
}
}
2.3 异步操作 #
java
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.utils.AddrUtil;
public class XmemcachedAsyncExample {
public static void main(String[] args) throws Exception {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("localhost:11211")
);
MemcachedClient client = builder.build();
// 异步存储
client.set("key1", 3600, "value1", new CountDownLatch(1));
// 异步获取
client.get("key1", new CountDownLatch(1));
// 使用回调
client.get("key2", new GetCallback<String>() {
@Override
public void received(String key, String value) {
System.out.println("Got value: " + value);
}
@Override
public void error(String key, Throwable throwable) {
System.err.println("Error: " + throwable.getMessage());
}
});
client.shutdown();
}
}
三、Python客户端 #
3.1 pymemcache #
bash
# 安装
pip install pymemcache
python
from pymemcache.client.base import Client
# 创建客户端
client = Client(('localhost', 11211))
# 存储数据
client.set('user:1001', '{"name":"John","age":25}', expire=3600)
# 获取数据
value = client.get('user:1001')
print(value)
# 删除数据
client.delete('user:1001')
# 递增
result = client.incr('counter', 1)
print(result)
# 批量操作
client.set_many({
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
})
values = client.get_many(['key1', 'key2', 'key3'])
print(values)
# 关闭连接
client.close()
3.2 连接池 #
python
from pymemcache.client.base import PooledClient
# 创建连接池客户端
client = PooledClient(
('localhost', 11211),
max_pool_size=10,
timeout=1,
connect_timeout=1
)
# 使用客户端
client.set('key', 'value')
value = client.get('key')
# 关闭连接池
client.close()
3.3 序列化 #
python
import json
from pymemcache.client.base import Client
def json_serializer(key, value):
if isinstance(value, str):
return value, 1
return json.dumps(value), 2
def json_deserializer(key, value, flags):
if flags == 1:
return value
if flags == 2:
return json.loads(value)
raise Exception("Unknown serialization format")
# 创建客户端(带序列化)
client = Client(
('localhost', 11211),
serializer=json_serializer,
deserializer=json_deserializer
)
# 存储对象
user = {'id': 1001, 'name': 'John', 'age': 25}
client.set('user:1001', user, expire=3600)
# 获取对象
user = client.get('user:1001')
print(user)
3.4 异步客户端 #
python
import asyncio
from aiomcache import Client
async def main():
# 创建异步客户端
client = Client('127.0.0.1', 11211)
# 存储数据
await client.set(b'key', b'value', exptime=3600)
# 获取数据
value = await client.get(b'key')
print(value)
# 删除数据
await client.delete(b'key')
# 并发操作
await asyncio.gather(
client.set(b'key1', b'value1'),
client.set(b'key2', b'value2'),
client.set(b'key3', b'value3')
)
# 关闭连接
client.close()
# 运行
asyncio.run(main())
3.5 一致性哈希 #
python
from pymemcache.client.hash import HashClient
# 创建一致性哈希客户端
servers = [
('127.0.0.1', 11211),
('127.0.0.1', 11212),
('127.0.0.1', 11213)
]
client = HashClient(
servers,
use_pooling=True,
timeout=1
)
# 自动分片
client.set('key1', 'value1')
client.set('key2', 'value2')
client.set('key3', 'value3')
# 获取数据
values = client.get_many(['key1', 'key2', 'key3'])
print(values)
四、PHP客户端 #
4.1 安装扩展 #
bash
# Ubuntu/Debian
sudo apt install php-memcached
# CentOS/RHEL
sudo yum install php-memcached
# 验证安装
php -m | grep memcached
4.2 基本使用 #
php
<?php
// 创建客户端
$memcached = new Memcached();
$memcached->addServer('localhost', 11211);
// 存储数据
$memcached->set('user:1001', json_encode([
'name' => 'John',
'age' => 25
]), 3600);
// 获取数据
$user = $memcached->get('user:1001');
echo $user . "\n";
// 删除数据
$memcached->delete('user:1001');
// 递增
$memcached->set('counter', 0);
$result = $memcached->increment('counter', 1);
echo $result . "\n";
// 批量操作
$memcached->setMulti([
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3'
], 3600);
$values = $memcached->getMulti(['key1', 'key2', 'key3']);
print_r($values);
// 关闭连接
$memcached->quit();
?>
4.3 连接池 #
php
<?php
// 创建持久连接
$memcached = new Memcached('persistent_pool');
$memcached->addServer('localhost', 11211);
// 使用连接池
$memcached->set('key', 'value');
$value = $memcached->get('key');
?>
4.4 一致性哈希 #
php
<?php
// 创建客户端
$memcached = new Memcached();
// 添加多个服务器
$memcached->addServers([
['127.0.0.1', 11211],
['127.0.0.1', 11212],
['127.0.0.1', 11213]
]);
// 设置一致性哈希
$memcached->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
// 自动分片
$memcached->set('key1', 'value1');
$memcached->set('key2', 'value2');
$memcached->set('key3', 'value3');
?>
五、Go客户端 #
5.1 gomemcache #
bash
# 安装
go get github.com/bradfitz/gomemcache/memcache
go
package main
import (
"fmt"
"github.com/bradfitz/gomemcache/memcache"
)
func main() {
// 创建客户端
client := memcache.New("localhost:11211")
// 存储数据
err := client.Set(&memcache.Item{
Key: "user:1001",
Value: []byte(`{"name":"John","age":25}`),
Expiration: 3600,
})
if err != nil {
panic(err)
}
// 获取数据
item, err := client.Get("user:1001")
if err != nil {
panic(err)
}
fmt.Println(string(item.Value))
// 删除数据
err = client.Delete("user:1001")
if err != nil {
panic(err)
}
// 递增
client.Set(&memcache.Item{
Key: "counter",
Value: []byte("0"),
})
newValue, err := client.Increment("counter", 1)
if err != nil {
panic(err)
}
fmt.Println(newValue)
// 批量操作
client.SetMulti([]*memcache.Item{
{Key: "key1", Value: []byte("value1")},
{Key: "key2", Value: []byte("value2")},
{Key: "key3", Value: []byte("value3")},
})
items, err := client.GetMulti([]string{"key1", "key2", "key3"})
if err != nil {
panic(err)
}
for key, item := range items {
fmt.Printf("%s: %s\n", key, string(item.Value))
}
}
5.2 多服务器配置 #
go
package main
import (
"fmt"
"github.com/bradfitz/gomemcache/memcache"
)
func main() {
// 创建多服务器客户端
client := memcache.New(
"localhost:11211",
"localhost:11212",
"localhost:11213",
)
// 自动分片
client.Set(&memcache.Item{
Key: "key1",
Value: []byte("value1"),
})
client.Set(&memcache.Item{
Key: "key2",
Value: []byte("value2"),
})
// 获取数据
item, err := client.Get("key1")
if err != nil {
panic(err)
}
fmt.Println(string(item.Value))
}
六、Node.js客户端 #
6.1 memcached #
bash
# 安装
npm install memcached
javascript
const Memcached = require('memcached');
// 创建客户端
const client = new Memcached('localhost:11211');
// 存储数据
client.set('user:1001', JSON.stringify({
name: 'John',
age: 25
}), 3600, (err) => {
if (err) {
console.error(err);
}
});
// 获取数据
client.get('user:1001', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(JSON.parse(data));
});
// 删除数据
client.del('user:1001', (err) => {
if (err) {
console.error(err);
}
});
// 递增
client.incr('counter', 1, (err, result) => {
if (err) {
console.error(err);
return;
}
console.log(result);
});
// 批量操作
client.setMulti({
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
}, 3600, (err) => {
if (err) {
console.error(err);
}
});
client.getMulti(['key1', 'key2', 'key3'], (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
// 关闭连接
client.end();
6.2 多服务器配置 #
javascript
const Memcached = require('memcached');
// 创建多服务器客户端
const client = new Memcached([
'localhost:11211',
'localhost:11212',
'localhost:11213'
], {
retries: 2,
timeout: 1000,
remove: true,
failOverServers: ['localhost:11214']
});
// 自动分片
client.set('key1', 'value1', 3600, (err) => {
if (err) {
console.error(err);
}
});
七、客户端最佳实践 #
7.1 连接管理 #
python
# 不好的做法
def get_user(user_id):
client = Client(('localhost', 11211))
user = client.get(f'user:{user_id}')
client.close()
return user
# 好的做法
client = PooledClient(('localhost', 11211), max_pool_size=10)
def get_user(user_id):
return client.get(f'user:{user_id}')
7.2 错误处理 #
python
from pymemcache.client.base import Client
def safe_get(client, key, default=None):
try:
value = client.get(key)
return value if value is not None else default
except Exception as e:
print(f"Error getting key {key}: {e}")
return default
def safe_set(client, key, value, expire=3600):
try:
client.set(key, value, expire=expire)
return True
except Exception as e:
print(f"Error setting key {key}: {e}")
return False
# 使用
client = Client(('localhost', 11211))
user = safe_get(client, 'user:1001', default={})
safe_set(client, 'user:1001', user, expire=3600)
7.3 超时设置 #
python
from pymemcache.client.base import Client
# 设置超时
client = Client(
('localhost', 11211),
timeout=1, # 操作超时(秒)
connect_timeout=1 # 连接超时(秒)
)
7.4 重试机制 #
python
import time
from pymemcache.client.base import Client
def retry_operation(func, max_retries=3, delay=0.1):
for i in range(max_retries):
try:
return func()
except Exception as e:
if i == max_retries - 1:
raise
time.sleep(delay)
return None
# 使用
client = Client(('localhost', 11211))
result = retry_operation(lambda: client.get('key'))
八、总结 #
客户端库选择:
| 语言 | 推荐客户端 | 特点 |
|---|---|---|
| Java | Xmemcached | 功能全面、性能好 |
| Python | pymemcache | 简单易用、支持异步 |
| PHP | memcached | 官方扩展、功能完善 |
| Go | gomemcache | 官方推荐、简单高效 |
| Node.js | memcached | 社区活跃、功能丰富 |
最佳实践:
- 使用连接池
- 设置合理的超时
- 实现错误处理
- 使用批量操作
- 配置一致性哈希
下一步,让我们学习Memcached的分布式缓存!
最后更新:2026-03-27