问题现象
Redis 响应变慢,查询或写入操作耗时增加。
原因
- 数据量过大,导致操作复杂度增加。
- 频繁的大 key 操作(如
HGETALL
、SMEMBERS
)。 - 网络延迟或带宽不足。
- Redis 实例负载过高,CPU 或内存资源不足。
- AOF 或 RDB 持久化操作影响性能。
解决方案
- 优化大 key:拆分大 key,避免一次性操作大量数据。
- 使用 Pipeline:将多个命令打包发送,减少网络开销。(如果redis分片,不建议使用)
- 升级硬件:增加 CPU、内存或网络带宽。
- 调整持久化策略:根据业务需求调整 AOF 或 RDB 的配置,例如减少
fsync
频率。(从节点做持久化) - 监控性能:使用
SLOWLOG
或监控工具分析慢查询。
优化大 key
String类型
- 使用压缩格式
- 如果时对象序列化成的字符串,考虑减少对象中的属性
- 如果是json格式,考虑使用hash存储,需要哪个字段,就查哪个
List、Set、Zset类型
考虑方向:将1个key分散到多个节点
原始大 Key:
user:1000:orders
,存储了 100 万个订单拆分后:
user:1000:orders:1
、user:1000:orders:2
,每个 Key 存储 1 万个订单。
分片:使用一致性哈希算法,将
user:1000:orders
的数据分布到多个 Redis 实例
Pipeline
作用:将多个命令打包发送,减少网络开销。
package org.example;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;
import java.util.Arrays;
import java.util.List;
public class LuaTest {
private static final String KEY = "lock_test";
private static final RedissonClient redisson;
static {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://*****.redis.rds.aliyuncs.com:6379")
.setUsername("****")
.setPassword("******")
;
redisson = Redisson.create(config);
}
public static void main(String[] args) {
// 3. 创建 RBatch 实例
RBatch batch = redisson.createBatch();
// 4. 批量添加 String 类型数据
batch.getBucket("stringKey1").setAsync("value1");
batch.getBucket("stringKey2").setAsync("value2");
// 5. 批量添加 List 类型数据
RListAsync<Object> list1 = batch.getList("listKey1");
list1.addAllAsync(Arrays.asList("item1", "item2", "item3"));
RListAsync<Object> list2 = batch.getList("listKey2");
list2.addAllAsync(Arrays.asList("itemA", "itemB", "itemC"));
// 6. 执行 RBatch
batch.execute();
// 7. 验证结果
System.out.println("String Key1: " + redisson.getBucket("stringKey1").get());
System.out.println("String Key2: " + redisson.getBucket("stringKey2").get());
List<Object> listResult1 = redisson.getList("listKey1").readAll();
List<Object> listResult2 = redisson.getList("listKey2").readAll();
System.out.println("List Key1: " + listResult1);
System.out.println("List Key2: " + listResult2);
}
}