分段存储Redis键值对的方法详解

 更新时间:2025年01月24日 10:40:17   作者:何中应  
Redis是一种开源的、基于内存的数据结构存储系统,它可以用作数据库、缓存和消息中间件,Redis最常用的功能之一就是其键值对数据模型,本文介绍针对一个value过长的键值对,如何分段存储,需要的朋友可以参考下

场景

当我们需要存入一个String类型的键值对到Redis中,如下:

(缓存接口)

public interface CacheService {

    /**
     * 添加一个字符串键值对
     * @param key 键
     * @param value 值
     */
    void setString(String key, String value);
}

(Redis实现)

import com.hezy.service.CacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class RedisServiceImpl implements CacheService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Override
    public void setString(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }
}

(使用)

import com.hezy.service.impl.RedisServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class RedisServiceImplTest {

    @Autowired
    private RedisServiceImpl redisService;

    @Test
    public void test1() {
        String key = "content";
        String value = "这是一段分非常大非常大的字符串…………………………非常大";
        redisService.setString(key, value);
    }
}

(查看Redis)

有时候,我们存入的字符串可能过长,过大,有可能来自于一个大对象的序列化。这时候存入的key-value,会造成value过大,会触发一些预警。

可以采用我下面这种分段存储的方法。

优化

思路:将字符串分段,每一段生成一个key,然后将这些分段key再用Redis的List类型存储;获取时就先获取这些分段key,再循环去get对应的字符串,拼接起来就是完整的字符串。

如下:分段存,增加一个参数,设置每段字符串的长度

(缓存接口)

    /**
     * 分段存储
     * @param key 键
     * @param value 值
     * @param chunkSize 每个分段大小
     */
    void setStrSub(String key, String value, int chunkSize);

(Redis实现)

    @Override
    public void setStrSub(String key, String value, int chunkSize) {
        // 将value,按照length,分成多个部分
        int totalChunks = (int) Math.ceil((double) value.length() / chunkSize);
        // 定义一个分段数据key集合
        List<String> subKeys = new ArrayList<>(totalChunks);
        // 将字符串分成多段
        for (int i = 0; i < totalChunks; i++) {
            // 计算分段起止位置
            int startIndex = i * chunkSize;
            int endIndex = Math.min(startIndex + chunkSize, value.length());
            // 获取对应分段数据
            String chunkValue = value.substring(startIndex, endIndex);
            // 拼接分段key
            String subKey = key + "_" + i;
            // 存储分段数据
            setString(subKey, chunkValue);
            // 将分段key添加到集合
            subKeys.add(subKey);
        }
        // 分段key添加到集合
        setList(key, subKeys);
    }

(添加一个集合到Redis)

    @Override
    public void setList(String key, List value) {
        redisTemplate.opsForList().rightPushAll(key, value);
    }

启动,测试

    @Test
    public void test2() {
        String key = "content";
        String value = "这是一段分非常大非常大的字符串…………………………非常大";
        redisService.setStrSub(key, value, 5);
    }

查看Redis

然后,要取数据,也很简单;

(缓存接口)

    /**
     * 获取字符串(分段)
     * @param key
     * @return
     */
    String getStrSub(String key);

(Redis实现)

    @Override
    public String getStrSub(String key) {
        // 先把分段key获取出来
        List<String> list = getList(key);
        // 字符串拼接,用StringBuilder,线程安全
        StringBuilder stringBuilder = new StringBuilder();
        for (String subKey : list) {
            String subValue = getString(subKey);
            // 这里要跳过null,不然最后输出会把null转为字符串
            if (subValue == null) {
                continue;
            }
            stringBuilder.append(subValue);
        }
        // 如果没有数据,返回null
        return "".contentEquals(stringBuilder) ? null : stringBuilder.toString();
    }

(Redis获取一个List)

    @Override
    public List getList(String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }

(使用)

    @Test
    public void test3() {
        String content = redisService.getStrSub("content");
        System.out.println(content);
    }

(打印)

总结

本文介绍了Redis分段存储一个大键值对(String)的一种方式,看下来,实现并不复杂。使用上也可以很方便,可以考虑把分段的存取和普通的存取都兼容起来,这样对于使用者,只需要加一个参数(分段大小)。

到此这篇关于分段存储Redis键值对的方法详解的文章就介绍到这了,更多相关Redis键值对分段存储内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python交互Redis的实现

    Python交互Redis的实现

    本文主要介绍了Python交互Redis的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Redis实现订单过期删除的方法步骤

    Redis实现订单过期删除的方法步骤

    本文主要介绍了Redis实现订单过期删除的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Redis高并发分布锁的示例

    Redis高并发分布锁的示例

    在分布式系统中,实现分布式锁是一项常见的需求,本文主要介绍了Redis高并发分布锁的示例 ,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Redis哨兵机制的使用详解

    Redis哨兵机制的使用详解

    文章讲解了Redis哨兵机制的基本原理、主库和从库自动切换的过程、如何减少误判、哨兵集群的组成和通信机制,以及哨兵在故障发生时如何选举Leader进行主从切换
    2025-01-01
  • redis中key使用冒号分隔的原理小结

    redis中key使用冒号分隔的原理小结

    Redis是一种高性能的键值对非关系型数据库,通过redis不同类型命令可以为其中的键指定不同的数据类型,其中每个键的命名规范通常使用冒号符号分隔字符串,本文主要介绍了redis中key使用冒号分隔的原理小结,感兴趣的可以了解一下
    2024-01-01
  • Redis Cluster的图文讲解

    Redis Cluster的图文讲解

    今天小编就为大家分享一篇关于Redis Cluster的图文讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Redis中什么是Big Key(大key)问题?如何解决Big Key问题?

    Redis中什么是Big Key(大key)问题?如何解决Big Key问题?

    大key并不是指key的值很大,而是key对应的value很大,下面这篇文章主要给大家介绍了Redis中什么是Big Key(大key)问题?如何解决Big Key问题的相关资料,需要的朋友可以参考下
    2023-03-03
  • Redis报错“NOAUTH Authentication required”两种解决方案

    Redis报错“NOAUTH Authentication required”两种解决方案

    Redis提供了一个命令行工具redis-cli,它允许你直接连接到Redis服务器,如果你知道Redis服务器的密码,你可以在连接时直接提供它,本文给大家介绍连接了Redis报错“NOAUTH Authentication required”两种解决方案
    2024-05-05
  • 详解redis big key 排查思路

    详解redis big key 排查思路

    本文主要介绍了详解redis big key 排查思路,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Redis性能监控的实现

    Redis性能监控的实现

    本文使用 redis_exporter + prometheus +grafana 实现对Redis服务进行监控,原因:成本低,人工干预少,感兴趣的可以了解一下
    2021-07-07

最新评论