redis的zset使用(java)——存取List< Object>
1 需求要往redis存取List< Object>。2 条件1)Object:是一个UserEvent对象,对应3个字段:Integer productId;String eventCode;Long timestamp;2)要求存取个数不超过xx个。超过xx个,则剔除早期加入的数据。备注:存之前的每个userEvent对象都是不一样的。3)使用zset实现。3 zset使用原理1)
1 需求
要往redis存取List< Object>。
2 条件
1)Object:是一个UserEvent对象,对应3个字段:
Integer productId;
String eventCode;
Long timestamp;
2)要求
每个key里存取对象个数不超过xx个。
超过xx个,则剔除早期加入的对象数据。
备注:存之前的每个userEvent对象都是不一样的。
3)使用zset实现。
3 zset使用原理
1)zset是有一个score参数,这个分数是zset存储结构的顺序依据。可以按分数从小到大查询,也可以逆序查询。
2)因为当前场景,UserEvent对象的timestamp参数是一个时间戳,是对象产生的时间,可以用来做剔除早期数据的规则使用。使用这个参数作为zest的分数。
4 代码实现——存
1)思路
把对象的三个字段进行拼接,作为一个String类型的value。示例:productId,eventCode,timestamp
108634,1,1623136194
使用时间戳作为分数,主要分数是double类型。long型时间戳可以进行转换成double。
ps:2038年前时间戳都是可以使用的。:p
/**
* 测试redis的zset
*/
@Test
public void testRedisZset() {
JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
Jedis jedis = jedisPool.getResource();
Map<String, Double> map = Maps.newHashMap();
Map<String, Double> map2 = Maps.newHashMap();
Map<String, Double> newMap = Maps.newHashMap();
map.put("121624,1,1623136190", 1623136190.0);
map.put("105916,2,1623136191", 1623136191.0);
map2.put("107770,1,1623136192", 1623136192.0);
map2.put("105916,2,1623136193", 1623136193.0);
map2.put("105917,2,1623136193", 1623136193.0);
jedis.zadd("user12", map);
jedis.zadd("user12", map2);
//查询添加后的总个数 5个
int oldCount = jedis.zcard("user12").intValue();
newMap.put("108634,1,1623136194", 1623136194.0);
newMap.put("108634,3,1623136195", 1623136195.0);
newMap.put("108635,3,1623136195", 1623138109.0);
newMap.put("108638,3,1623136195", 1623138120.0);
//需要新加入 4个
int newCount = 4;
//要求value容量是6个
int size = 6;
int diff = oldCount + newCount - size;
if (diff > 0) {
//移除得分最小的前3个 第0-2个
jedis.zremrangeByRank("user12", 0, diff - 1);
//再追加新的
jedis.zadd("user12", newMap);
} else {
//还没有加满,直接追加
jedis.zadd("user12", newMap);
}
//查询value zrange得分从小到大排序 取size个
Set<String> user12 = jedis.zrange("user12", 0, size);
}
5 代码实现——取
1)另外一个项目需要取这些数据。
取出来之后stringToUserEvent方法进行切割还原成List< UserEvent>
@Test
public void redisGetZSet() {
//取3个
int size=3;
List<UserEvent> userEvents = Lists.newArrayListWithExpectedSize(size);
//reverseRange按从大往小取size个,也就是取最新的
Set<String> range = stringRedisTemplate.opsForZSet().getOperations().boundZSetOps("user12").reverseRange(0, size);
if (range != null && range.size() > 0) {
userEvents = range.stream().map(a -> stringToUserEvent(a)).filter(userEvent -> userEvent != null).collect(Collectors.toList());
}
System.out.println(userEvents);
}
6 小乌龙
阿里云数据库查看key的数据,发现左侧的序号不对应得分排序。奇怪?没排序好吗?
原来左侧的序号不是排序号。
毕竟zset的查询,是通过分数score来排序来查询结果的,不要以为左侧的序号是排序号!
不过云数据库结果呈现的顺序是什么依据呢?只是方便看总的个数吧!
更多推荐
所有评论(0)