1. Java实现代码(Lettuce客户端)
java
import io.lettuce.core.RedisURI;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.sync.RedisCommands;
import com.google.protobuf.InvalidProtocolBufferException;
import your.package.UserPB; // 替换为您的PB3生成类
public class RedisStorage {
private static final String HOST = "your-redis-host";
private static final int PORT = 6379;
private static final String PASSWORD = "your-password";
private static final int DATABASE = 0;
public static void main(String[] args) throws InvalidProtocolBufferException {
// 创建Redis连接
RedisURI uri = RedisURI.builder()
.withHost(HOST)
.withPort(PORT)
.withPassword(PASSWORD.toCharArray())
.withDatabase(DATABASE)
.build();
RedisClient client = RedisClient.create(uri);
StatefulRedisConnection<String, byte[]> connection = client.connect(new PB3RedisCodec());
RedisCommands<String, byte[]> sync = connection.sync();
// 创建PB3对象
UserPB.User user = UserPB.User.newBuilder()
.setId(1)
.setName("xxx")
.setEmail("xxx@example.com")
.build();
// 序列化存储
byte[] userBytes = user.toByteArray();
sync.set("user:1", userBytes);
// 查询反序列化
byte[] storedBytes = sync.get("user:1");
UserPB.User storedUser = UserPB.User.parseFrom(storedBytes);
System.out.println("Retrieved User: " + storedUser);
connection.close();
}
}
- 自定义 RedisCodec
java
import io.lettuce.core.codec.RedisCodec;
import java.nio.ByteBuffer;
public class PB3RedisCodec implements RedisCodec<String, byte[]> {
@Override
public String decodeKey(ByteBuffer bytes) {
return bytes.toString();
}
@Override
public byte[] decodeValue(ByteBuffer bytes) {
return toByteArray(bytes);
}
@Override
public ByteBuffer encodeKey(String key) {
return ByteBuffer.wrap(key.getBytes());
}
@Override
public ByteBuffer encodeValue(byte[] value) {
return ByteBuffer.wrap(value);
}
public static byte[] toByteArray(ByteBuffer buffer) {
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
buffer.rewind(); // 恢复原始状态
return bytes;
}
}
- 使用连接池配置
java
GenericObjectPool<StatefulRedisConnection<String, byte[]>> pool =
ConnectionPoolSupport.createGenericPool(
() -> client.connect(new PB3RedisCodec()),
new GenericObjectPoolConfig()
);
2. 关键配置说明
-
PB3序列化:
java// 序列化 byte[] data = protoObject.toByteArray(); // 反序列化 ProtoClass obj = ProtoClass.parseFrom(data); -
Lettuce连接池优化:
java// 连接池配置 RedisURI uri = RedisURI.builder() .withHost("host") .withPassword("pass".toCharArray()) .withTimeout(Duration.ofSeconds(10)) .build(); RedisClient client = RedisClient.create(uri); StatefulRedisConnection<String, byte[]> connection = client.connect();
3. 替代方案(Python实现)
若环境限制Java使用,可使用Python方案:
python
import redis
from user_pb2 import User # 需先编译.proto文件
# 连接Redis Labs
r = redis.Redis(
host='your-redis-host',
port=6379,
password='your-password',
decode_responses=False
)
# 序列化存储
user = User(id=1, name="John Doe", email="john.doe@example.com")
r.set("user:1", user.SerializeToString())
# 查询反序列化
stored_bytes = r.get("user:1")
stored_user = User.FromString(stored_bytes)
print(f"Retrieved User: {stored_user}")
4. 常见问题处理
-
依赖安装:
bash# Java项目 <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.3.0.RELEASE</version> </dependency> # Python项目 pip install redis protobuf -
连接问题排查:
- 检查防火墙设置(开放6379端口)
- 验证密码正确性
- 测试网络连通性:
telnet host 6379
-
性能优化:
- 使用连接池(Lettuce自动管理)
- 启用压缩选项(PB3支持)
- 设置合理超时时间(建议10-30秒)
注意:生产环境建议:
- 使用SSL/TLS加密连接
- 配置Redis访问白名单
- 启用持久化存储(RDB/AOF)
- 监控内存使用情况(免费套餐有30MB限制)
netty中实现Protobuf协议编解码与传输
Protobuf序列化机制的核心原理
lettuce支持的redis模式