Redis缓存分页方案咨询:实现分页取数与24小时数据自动过期
Redis缓存最近24h数据并实现分页的设计方案
方案一:Sorted Set + 定时清理脚本(最适配需求)
利用Sorted Set的天然排序特性实现分页,用定时任务解决元素过期问题,完全匹配你的场景:
- 数据存储结构:
- 用一个Sorted Set(例如
recent_objects)存储对象唯一标识(ID),将对象创建时间的epoch时间戳设为score,确保数据按时间倒序排列。 - 对象详情单独存入Hash结构(例如
object:<object_id>),字段对应对象的各个属性,方便批量获取详情。
- 用一个Sorted Set(例如
- 写入逻辑:
新增对象时执行以下命令:ZADD recent_objects <创建时间戳> <object_id> HMSET object:<object_id> key1 value1 key2 value2 ... EXPIRE object:<object_id> 86400 - 分页查询逻辑:
- 获取最新10条:
ZREVRANGE recent_objects 0 9 # 取排名前10的ID(最新的10条数据) HMGET object:<id1> object:<id2> ... # 批量获取对象详情 - 从指定对象后取10条:
先获取指定对象的时间戳:
再查询该对象之后(更旧)的10条数据:ZSCORE recent_objects <target_object_id>
(注:ZREVRANGEBYSCORE recent_objects <时间戳-1> -inf LIMIT 0 10时间戳-1用于排除指定对象本身,若需包含则直接使用原时间戳)
- 获取最新10条:
- 过期清理:
配置定时任务(如Linux Cron、Redis自带CRON),每隔1小时执行清理命令:
(可选:批量获取待删除的ID,执行ZREMRANGEBYSCORE recent_objects -inf $((`date +%s` - 86400))DEL命令清理对应Hash键,避免冗余数据)
方案二:Redis Stream(适合高写入场景)
Redis Stream天然支持按时间排序和范围查询,自带数据修剪功能,无需额外存储对象详情:
- 数据存储结构:
用Stream(例如object_stream)存储对象完整数据,Redis自动生成的消息ID格式为时间戳-序列号,天然按时间倒序排列。 - 写入逻辑:
新增对象时使用XADD并设置近似最大长度,自动修剪旧数据:
(XADD object_stream MAXLEN ~ <预估24h内总条数> * key1 value1 key2 value2 ...~表示近似修剪,避免阻塞写入;预估条数可按每秒写入量计算,例如每秒10条则设为864000) - 分页查询逻辑:
- 获取最新10条:
XREVRANGE object_stream + - COUNT 10 - 从指定对象后取10条:
先获取指定对象的Stream消息ID(需在写入时记录到业务库或缓存),再执行:
(若仅知道对象创建时间,可构造ID为XREVRANGE object_stream <目标ID-1> - COUNT 10(创建时间戳-1)-0进行查询)
- 获取最新10条:
- 过期清理:
定时执行修剪命令,保留最近24小时的数据:XTRIM object_stream MAXID $((`date +%s` - 86400))-0
优化建议
- 优先批量操作:所有查询尽量使用批量命令(如
HMGET、XREVRANGE COUNT),减少Redis网络往返次数,提升性能。 - 回源处理:当Redis中无请求的分页数据(如超过24小时),直接查询业务数据库,无需将结果写入Redis(符合仅缓存24h数据的需求)。
- 时间一致性:确保所有写入Redis的时间戳来自同一服务器时钟,避免排序混乱。
内容的提问来源于stack exchange,提问作者ihsanser
相关产品推荐
相关产品推荐

