高效存储大List对象到Redis的解决方案,使用分片存储和压缩技术

【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道! 10w+人浏览 1.6k人参与

  1. 采用分片存储策略,将大List拆分为多个Redis列表项存储
  2. 使用Deflater压缩算法减少存储空间占用
  3. 实现自动序列化/反序列化处理
  4. 通过前缀区分压缩数据,避免键冲突
  5. Maven配置包含Jedis依赖和可执行插件
  6. 处理百万级数据项时内存效率优化
  7. 提供完整的数据压缩/解压工具方法

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());
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值