场景
当我们需要存入一个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键值对分段存储内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://www.jb51.net/database/334834goy.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |