You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Spring Boot与Lettuce的Redis每日时间序列数据存储方案咨询

需求可行性与实现思路

完全可行,Redis的结构特性刚好匹配你的需求,以下是具体实现思路:

数据结构选型

  • 用Hash存储每日数值列表:固定前缀+标准日期作为Hash的field(比如2024-10-12),对应的value存当日的数值列表(借助RedisTemplate的序列化能力直接存Java List即可),Hash的key统一设为daily_values,所有日期的数据集中管理更方便。
  • 用Sorted Set维护日期索引:把日期转成当日零点的时间戳作为score,日期字符串作为member,既能快速按时间范围筛选日期,也能轻松定位到最早的过期日期。

每日数据存储流程

每次新增当日数据时:

  1. 将当日的数值列表存入Hash的对应field中。
  2. 将当日日期的时间戳和字符串添加到Sorted Set索引里。

自动过期与清理逻辑

每次新增数据后(或每日定时执行),执行以下操作:

  1. 计算28天前的日期,转成当日零点的时间戳作为阈值。
  2. 从Sorted Set中取出所有score小于该阈值的日期(即过期日期)。
  3. 批量删除Hash中这些过期日期对应的field。
  4. 从Sorted Set中移除这些过期的日期member。

如果业务量较大,建议用定时任务(比如Spring的@Scheduled)每日凌晨执行清理,避免每次新增数据都触发操作。

范围查询实现

查询x日到y日的数据时:

  1. 将x日和y日分别转成当日零点的时间戳。
  2. 从Sorted Set中获取score在这两个时间戳之间的所有日期。
  3. 遍历这些日期,从Hash中取出对应的数值列表,汇总后返回即可。

基于RedisTemplate的代码示例

存储当日数据

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

// 格式化当日日期为标准格式
String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
List<Double> todayValues = Arrays.asList(1.0, 2.0, 3.0);

// 存入Hash
redisTemplate.opsForHash().put("daily_values", today, todayValues);

// 添加到日期索引Sorted Set
long todayTimestamp = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toEpochSecond();
redisTemplate.opsForZSet().add("date_index", today, todayTimestamp);

清理过期数据

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Set;

// 计算28天前的时间戳阈值
LocalDate cutoffDate = LocalDate.now().minusDays(28);
long cutoffTimestamp = cutoffDate.atStartOfDay(ZoneId.systemDefault()).toEpochSecond();

// 获取所有过期日期
Set<String> expiredDates = redisTemplate.opsForZSet().rangeByScore("date_index", 0, cutoffTimestamp);
if (expiredDates != null && !expiredDates.isEmpty()) {
    // 批量删除Hash中的过期数据
    redisTemplate.opsForHash().delete("daily_values", expiredDates.toArray());
    // 从索引中移除过期日期
    redisTemplate.opsForZSet().removeRangeByScore("date_index", 0, cutoffTimestamp);
}

范围查询数据

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

// 定义查询的起止日期
LocalDate startDate = LocalDate.of(2024, 10, 12);
LocalDate endDate = LocalDate.of(2024, 10, 13);

long startTimestamp = startDate.atStartOfDay(ZoneId.systemDefault()).toEpochSecond();
long endTimestamp = endDate.atStartOfDay(ZoneId.systemDefault()).toEpochSecond();

// 获取范围内的日期
Set<String> targetDates = redisTemplate.opsForZSet().rangeByScore("date_index", startTimestamp, endTimestamp);
Map<String, List<Double>> resultMap = new HashMap<>();

if (targetDates != null) {
    for (String date : targetDates) {
        @SuppressWarnings("unchecked")
        List<Double> values = (List<Double>) redisTemplate.opsForHash().get("daily_values", date);
        if (values != null) {
            resultMap.put(date, values);
        }
    }
}
// resultMap就是查询范围内的日期与对应数值列表的映射

内容的提问来源于stack exchange,提问作者user1555190

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:53:26