Redis 客户端连接概述
Redis 客户端连接是应用程序与 Redis 服务器通信的桥梁。不同编程语言都有相应的 Redis 客户端库,提供了丰富的功能和优化的连接管理机制。
客户端连接的重要性:
- 性能影响:连接管理直接影响应用性能
- 资源消耗:合理的连接池可以减少资源消耗
- 稳定性:良好的连接管理提高系统稳定性
- 扩展性:支持高并发和集群部署
☕ Java 客户端
Java 生态系统中有多个优秀的 Redis 客户端:
1. Jedis - 传统同步客户端
// Maven 依赖
/*
redis.clients
jedis
4.3.1
*/
// 基本连接
Jedis jedis = new Jedis("localhost", 6379);
jedis.auth("password");
jedis.set("key", "value");
String value = jedis.get("key");
jedis.close();
// 连接池配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(20);
config.setMinIdle(5);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
config.setTestWhileIdle(true);
config.setMaxWaitMillis(3000);
JedisPool pool = new JedisPool(config, "localhost", 6379, 2000, "password");
// 使用连接池
try (Jedis jedis = pool.getResource()) {
jedis.set("key", "value");
String value = jedis.get("key");
}
pool.close();
2. Lettuce - 异步响应式客户端
// Maven 依赖
/*
io.lettuce
lettuce-core
6.2.4.RELEASE
*/
// 基本连接
RedisClient client = RedisClient.create("redis://password@localhost:6379");
StatefulRedisConnection connection = client.connect();
RedisCommands commands = connection.sync();
commands.set("key", "value");
String value = commands.get("key");
connection.close();
client.shutdown();
// 异步操作
RedisAsyncCommands async = connection.async();
RedisFuture future = async.get("key");
future.thenAccept(value -> System.out.println(value));
// 响应式操作
RedisReactiveCommands reactive = connection.reactive();
Mono mono = reactive.get("key");
mono.subscribe(value -> System.out.println(value));
// 连接池
GenericObjectPoolConfig> poolConfig =
new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(100);
poolConfig.setMaxIdle(20);
ConnectionPoolSupport.createGenericObjectPool(
() -> client.connect(), poolConfig);
3. Redisson - 分布式对象客户端
// Maven 依赖
/*
org.redisson
redisson
3.20.1
*/
// 配置连接
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setPassword("password")
.setConnectionPoolSize(100)
.setConnectionMinimumIdleSize(10);
RedissonClient redisson = Redisson.create(config);
// 基本操作
RBucket bucket = redisson.getBucket("key");
bucket.set("value");
String value = bucket.get();
// 分布式锁
RLock lock = redisson.getLock("myLock");
lock.lock();
try {
// 业务逻辑
} finally {
lock.unlock();
}
redisson.shutdown();
🐍 Python 客户端
Python 中最流行的 Redis 客户端是 redis-py:
# 安装
# pip install redis
import redis
from redis.connection import ConnectionPool
# 基本连接
r = redis.Redis(host='localhost', port=6379, password='password', db=0)
r.set('key', 'value')
value = r.get('key')
# 连接池
pool = ConnectionPool(
host='localhost',
port=6379,
password='password',
max_connections=100,
retry_on_timeout=True,
socket_timeout=5,
socket_connect_timeout=5
)
r = redis.Redis(connection_pool=pool)
# 管道操作
pipe = r.pipeline()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.get('key1')
results = pipe.execute()
# 异步客户端 (redis-py 4.2+)
import asyncio
import redis.asyncio as redis
async def main():
r = redis.Redis(host='localhost', port=6379, password='password')
await r.set('key', 'value')
value = await r.get('key')
await r.close()
asyncio.run(main())
# 集群连接
from rediscluster import RedisCluster
startup_nodes = [
{"host": "127.0.0.1", "port": "7000"},
{"host": "127.0.0.1", "port": "7001"},
{"host": "127.0.0.1", "port": "7002"}
]
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
rc.set('key', 'value')
value = rc.get('key')
🟢 Node.js 客户端
Node.js 生态系统中的主要 Redis 客户端:
1. node_redis - 官方推荐
// 安装
// npm install redis
const redis = require('redis');
// 基本连接
const client = redis.createClient({
host: 'localhost',
port: 6379,
password: 'password',
db: 0
});
client.on('error', (err) => {
console.log('Redis Client Error', err);
});
await client.connect();
// 基本操作
await client.set('key', 'value');
const value = await client.get('key');
// 管道操作
const pipeline = client.multi();
pipeline.set('key1', 'value1');
pipeline.set('key2', 'value2');
pipeline.get('key1');
const results = await pipeline.exec();
// 发布订阅
const subscriber = client.duplicate();
await subscriber.connect();
subscriber.subscribe('channel', (message) => {
console.log('Received:', message);
});
await client.publish('channel', 'Hello World');
await client.disconnect();
2. ioredis - 功能丰富的客户端
// 安装
// npm install ioredis
const Redis = require('ioredis');
// 基本连接
const redis = new Redis({
host: 'localhost',
port: 6379,
password: 'password',
db: 0,
retryDelayOnFailover: 100,
maxRetriesPerRequest: 3,
lazyConnect: true
});
// 基本操作
await redis.set('key', 'value');
const value = await redis.get('key');
// 集群连接
const cluster = new Redis.Cluster([
{ host: '127.0.0.1', port: 7000 },
{ host: '127.0.0.1', port: 7001 },
{ host: '127.0.0.1', port: 7002 }
]);
// Lua 脚本
const result = await redis.eval(
'return redis.call("set", KEYS[1], ARGV[1])',
1,
'mykey',
'myvalue'
);
// 事务
const pipeline = redis.pipeline();
pipeline.set('key1', 'value1');
pipeline.set('key2', 'value2');
const results = await pipeline.exec();
redis.disconnect();
🔷 C# 客户端
C# 中最流行的 Redis 客户端是 StackExchange.Redis:
// NuGet 包
// Install-Package StackExchange.Redis
using StackExchange.Redis;
// 基本连接
var connection = ConnectionMultiplexer.Connect("localhost:6379,password=mypassword");
var db = connection.GetDatabase();
// 基本操作
await db.StringSetAsync("key", "value");
var value = await db.StringGetAsync("key");
// 连接配置
var config = new ConfigurationOptions
{
EndPoints = { "localhost:6379" },
Password = "password",
ConnectTimeout = 5000,
SyncTimeout = 5000,
AbortOnConnectFail = false,
ConnectRetry = 3
};
var connection = ConnectionMultiplexer.Connect(config);
// 批量操作
var batch = db.CreateBatch();
var tasks = new List();
for (int i = 0; i < 100; i++)
{
tasks.Add(batch.StringSetAsync($"key{i}", $"value{i}"));
}
batch.Execute();
await Task.WhenAll(tasks);
// 发布订阅
var subscriber = connection.GetSubscriber();
await subscriber.SubscribeAsync("channel", (channel, message) =>
{
Console.WriteLine($"Received: {message}");
});
await subscriber.PublishAsync("channel", "Hello World");
// 事务
var transaction = db.CreateTransaction();
transaction.StringSetAsync("key1", "value1");
transaction.StringSetAsync("key2", "value2");
var committed = await transaction.ExecuteAsync();
connection.Close();
📊 客户端对比
不同 Redis 客户端的特性对比:
语言 | 客户端 | 特性 | 性能 | 推荐度 |
---|---|---|---|---|
Java | Jedis | 简单易用,同步阻塞 | 中等 | ⭐⭐⭐ |
Java | Lettuce | 异步非阻塞,响应式 | 高 | ⭐⭐⭐⭐⭐ |
Java | Redisson | 分布式对象,功能丰富 | 高 | ⭐⭐⭐⭐ |
Python | redis-py | 官方推荐,功能完整 | 中等 | ⭐⭐⭐⭐⭐ |
Node.js | node_redis | 官方客户端,异步支持 | 高 | ⭐⭐⭐⭐ |
Node.js | ioredis | 功能丰富,集群支持好 | 高 | ⭐⭐⭐⭐⭐ |
C# | StackExchange.Redis | 高性能,异步支持 | 高 | ⭐⭐⭐⭐⭐ |
⚙️ 连接优化最佳实践
优化 Redis 客户端连接的最佳实践:
连接池配置:
- 最大连接数:根据并发需求设置合理的最大连接数
- 最小空闲连接:保持一定数量的空闲连接
- 连接超时:设置合适的连接和读取超时时间
- 连接验证:启用连接有效性检查
- 重试机制:配置连接失败重试策略
常见问题和解决方案:
- 连接泄漏:确保正确关闭连接,使用 try-with-resources
- 连接超时:调整超时参数,检查网络状况
- 连接数过多:优化连接池配置,使用连接复用
- 性能问题:使用管道技术,批量操作
监控和诊断:
- 监控连接池状态和使用情况
- 记录连接异常和超时日志
- 定期检查连接数和性能指标
- 使用 Redis 的 CLIENT LIST 命令监控客户端