- 采用分片存储策略,将大List拆分为多个Redis列表项存储
- 使用Deflater压缩算法减少存储空间占用
- 实现自动序列化/反序列化处理
- 通过前缀区分压缩数据,避免键冲突
- Maven配置包含Jedis依赖和可执行插件
- 处理百万级数据项时内存效率优化
- 提供完整的数据压缩/解压工具方法
import redis.clients.jedis.Jedis;
import java.util.*;
import java.util.zip.*;
import java.io.*;
public class RedisLargeListStorage {
private static final String REDIS_HOST = "localhost";
private static final int CHUNK_SIZE = 500_000; // 每个分片最大字节数
private static final String COMPRESS_KEY_PREFIX = "list:compressed:";
private Jedis jedis;
public RedisLargeListStorage() {
this.jedis = new Jedis(REDIS_HOST);
}
// 压缩并分片存储List
public void storeLargeList(String key, List<Object> largeList) throws IOException {
byte[] serialized = serialize(largeList);
byte[] compressed = compress(serialized);
// 分片存储
int chunks = (int) Math.ceil((double) compressed.length / CHUNK_SIZE);
jedis.del(key); // 清除旧数据
for (int i = 0; i < chunks; i++) {
int start = i * CHUNK_SIZE;
int end = Math.min(start + CHUNK_SIZE, compressed.length);
byte[] chunk = Arrays.copyOfRange(compressed, start, end);
jedis.rpush((COMPRESS_KEY_PREFIX + key).getBytes(), chunk);
}
}
// 获取并解压List
public List<Object> getLargeList(String key) throws IOException, ClassNotFoundException {
List<byte[]> chunks = jedis.lrange((COMPRESS_KEY_PREFIX + key).getBytes(), 0, -1);
if (chunks.isEmpty()) return null;
// 合并分片
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (byte[] chunk : chunks) {
baos.write(chunk);
}
byte[] decompressed = decompress(baos.toByteArray());
return deserialize(decompressed);
}
private byte[] serialize(Object obj) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(obj);
return bos.toByteArray();
}
}
private List<Object> deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis)) {
return (List<Object>) ois.readObject();
}
}
private byte[] compress(byte[] data) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (DeflaterOutputStream dos = new DeflaterOutputStream(bos)) {
dos.write(data);
}
return bos.toByteArray();
}
private byte[] decompress(byte[] data) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (ByteArrayInputStream bis = new ByteArrayInputStream(data);
InflaterInputStream iis = new InflaterInputStream(bis)) {
byte[] buffer = new byte[1024];
int len;
while ((len = iis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
}
return bos.toByteArray();
}
public static void main(String[] args) throws Exception {
RedisLargeListStorage storage = new RedisLargeListStorage();
// 测试数据
List<String> largeList = new ArrayList<>();
for (int i = 0; i < 1_000_000; i++) {
largeList.add("Item-" + i);
}
// 存储和读取
storage.storeLargeList("testList", largeList);
List<String> retrieved = (List<String>) storage.getLargeList("testList");
System.out.println("Retrieved items: " + retrieved.size());
}
}