在我们日常工作中,有许多这种逻辑

例如需要得到最近三分钟的cache list. 例如我们监控系统需要查询最近一分钟的数据。

总结说来就是 需要一个list存储对象,并且这个对象会无限制增长,需要设置过期.

普遍做法有两种: 
1.一种就是简单的list,存储的对象带有expireTime,然后定时任务不停的拿到整个list并去除过期的member.

2.一种是把整个list的每个成员都当做一个key来存,然后分别设置超时时间,虽然解决了超时问题,但是显然这样实在太过于浪费,而且很多操作都需要得到size或者整个list,那么就需要keys “usercache_”。一旦成员过多,key太多,keys消耗非常大,不推荐.


使用sorted set实现

redis有一个sorted set,就是一个根据score排序的set。仔细一看,极为契合我们的需求! 
话不多说,直接上代码!

/**
* 聚合器
* @author Mingchenchen
*
*/
public class Aggregator {
private RedisTemplate<String, Event> redisTemplate;
private ZSetOperations<String, Event> zSetOperations; /**
* constructor
* @param redisTemplate
* @param expireMillions
*/
public Aggregator(RedisTemplate<String, Event> redisTemplate){
this.redisTemplate = redisTemplate;
redisTemplate.setKeySerializer(new Serializer());
redisTemplate.setValueSerializer(new EventSerializer());
this.zSetOperations = redisTemplate.opsForZSet();
} /**
* 存入一条数据到sorted set
* @param key
* @param event
*/
public boolean zset(String key, Event event){
long now = System.currentTimeMillis();
return zSetOperations.add(key, event, now);
} /**
* 取出整个set的所有记录
* @param key
* @return
*/
public Set<Event> zgetAll(String key, long expireSec){
long now = System.currentTimeMillis();
long tts = now - expireSec * 1000; //下标用-1才能表示最大值 score和count要用-inf和+inf
//return zSetOperations.rangeByScore(key, tts+1, -1); return zSetOperations.rangeByScore(key, tts+1, Long.MAX_VALUE);
} /**
* 查看匹配数目
* @param key
* @param expire:过期时间 单位是秒
* @return
*/
public long zCount(String key, long expireSec){
long now = System.currentTimeMillis();
long tts = now - expireSec * 1000; //下标用-1才能表示最大值 score和count要用-inf和+inf
//return zSetOperations.count(key, tts+1, -1); return zSetOperations.count(key, tts+1, Long.MAX_VALUE);
} /**
* 删除一整个policyCache
* @param zsetKey
*/
public void removeCache(String zsetKey){
redisTemplate.delete(zsetKey);
} /**
* 缓存清理者
*/
@SuppressWarnings("unchecked")
public void cacheCleaner(){
Cache<String, InstantPolicy> cache = SpringContextUtil.getBean("policyCache", Cache.class);
if (cache==null || cache.getAll().isEmpty()) {
return;
} for (InstantPolicy policy : cache.getAll().values()) {
String keyPref = policy.buildKeyPref(); Set<String> policyCacheKeys = redisTemplate.keys(keyPref);
if (policyCacheKeys==null || policyCacheKeys.isEmpty()) {
return;
} //移除过期数据
long now = System.currentTimeMillis();
long tts = now - policy.getDuration() * 1000;
for (String key : policyCacheKeys) {
zSetOperations.removeRangeByScore(key, 0, tts);
}
}
} private class Serializer implements RedisSerializer<String> {
public byte[] serialize(String s) {
if (s == null) {
return null;
}
return s.getBytes();
} public String deserialize(byte[] bytes) {
if (bytes == null) {
return null;
}
return new String(bytes);
}
} private class EventSerializer implements RedisSerializer<Event> {
public byte[] serialize(Event event) {
if (event == null) {
return null;
}
return JSONObject.toJSONBytes(event);
} public Event deserialize(byte[] bytes) {
if (bytes == null) {
return null;
}
return JSONObject.parseObject(bytes, Event.class);
}
}
}

附: 
sorted set学习资料

http://www.cnblogs.com/stephen-liu74/archive/2012/03/23/2354994.html

http://doc.redisfans.com/sorted_set/zrangebyscore.html

显示推荐内容

使用Redis sorted set实现集合设置member过期的更多相关文章

  1. Redis之Sorted Set 有序集合

    Redis Sorted Set 有序集合 Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分 ...

  2. Redis的Sorted Set有序集合命令

    Sorted Set是Set的一个升级版本,它在Set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序.可以理解为有两列的mysql表, ...

  3. Redis中7种集合类型应用场景&redis常用命令

    Redis常用数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redis内部 ...

  4. redis:php-redis中有序集合 zset的使用

    ZSET(stored set) 和 set 一样是字符串的集合,不同的是每个元素都会关联一个 double 类型的 score .实现使用的是 skip list 和 hash table , sk ...

  5. redis中插入用户集合的语句,有四个属性

    一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...

  6. Redis Sorted Set

    Redis Sorted Set Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合 ...

  7. Redis sorted set 常用命令介绍

    Redis sorted set 使用: Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个 ...

  8. redis对set(无序集合)的相关操作

    redis对set类型(无序集合)操作的相关命令以及如何在python使用这些命令 redis对set类型操作的命令: 命令 语法 概述 返回值 Redis Sadd 命令 sadd key memb ...

  9. 快速整明白Redis中的整数集合到底是个啥

    整数集合简介 整数集合(intset)是Redis集合数据类型的内部编码之一,当集合数据类型中的元素都是整数并且元素数量较少的时候,Redis就使用整数集合作为内部编码. 整数集合(intset)中可 ...

随机推荐

  1. Django_rest_framework分页

    分页基本流程及配置 1.基于LimitOffsetPagination做分页,根据配置 from rest_framework.pagination import LimitOffsetPaginat ...

  2. Vivado cordic IP求模求角教程

    前言 当需要对复数求模的时候,用FPGA怎么求呢?怎么开根号? 方法1:先求幅值平方和,再使用cordic IP开根号.(蠢办法) 方法2:直接用cordic求取模值. 此处只介绍方法2,资源占用更少 ...

  3. 微信小程序开发demo

    自己写的小程序,欢迎下载 https://gitee.com/lijunchengit/chengZiShengHuoBang

  4. ping IP 带时间戳循环显示并写入日志(windos版+linux版)

    在工作中,判断网络是否通畅,首选命令就是ping,但有时候我们需要持续ping一个或多个地址时,需要加 -t 即可,但有时候需要在ping的时候加入时间戳并把ping记录写入到日志里面,方法如下: w ...

  5. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certificatio

    场景:Java调用PHP接口,代码部署在服务器上后,调用报错,显示PHP服务器那边证书我这边服务器不信任(我猜的). 异常信息: 2019-08-06 14:00:09,102 [http-nio-4 ...

  6. JAVA笔记整理(九),JAVA中的集合

    在工作中,我们经常需要将多个对象集中存放,可以使用数组,但是数组的长度一旦固定之后是不可变的,为了保存数量确定的数据,我们可以使用JAVA中的集合. 在我看来,JAVA中的集合可以看作是一个特殊的数据 ...

  7. TLS1.3 握手协议的分析

    1.LTS支持的三种基本的密码交换模式 (EC)DHE (Diffie-Hellman both the finte field and ellptic curve varieties) PSK-on ...

  8. 剖析gcc -v输出

    分析gcc -v的详细信息的意义 首先我们需要清楚一点,我们并不能完全弄清楚gcc -v的所有信息,因为毕竟我们并不是GCC编译器集合的实现者,对于这些信息,他们才是最清楚的.由于我们不能将所有的信息 ...

  9. ubuntu 修改环境变量(PATH)

    1.什么是环境变量(PATH) 在Linux中,在执行命令时,系统会按照PATH的设置,去每个PATH定义的路径下搜索执行文件,先搜索到的文件先执行. 我们知道查阅文件属性的指令ls 完整文件名为:/ ...

  10. 【经典/基础BFS+略微复杂的题意】PAT-L3-004. 肿瘤诊断

    L3-004. 肿瘤诊断 在诊断肿瘤疾病时,计算肿瘤体积是很重要的一环.给定病灶扫描切片中标注出的疑似肿瘤区域,请你计算肿瘤的体积. 输入格式: 输入第一行给出4个正整数:M.N.L.T,其中M和N是 ...