Redis实现用户浏览商品的历史记录
思路: 用户每次浏览商品时, 向后台发送请求, 携带商品ID, 然后在 Redis中存储: 用户ID和浏览的商品ID,以时间排序. 来实现存储用户浏览历史记录.
其比较复杂的是redis选用数据结构(有序Set)
// redis存用户浏览记录,根据浏览时间, 只存8条
// redis key上线 2.5亿
// key: userId value: skuId
public void addRecentHistory(Long userId, Long skuId) {
ZSetOperations<String, String> zSetOperations = this.redisTemplate.opsForZSet();
// //zset内部是按分数来排序的,这里用当前时间做分数
zSetOperations.add(KEY_HISTORY + userId, skuId.toString(), System.currentTimeMillis());
// 例子: 只保留5个元素
// //环形结构 -6, -5, -4, -3, -2, -1 (负数索引)
// 0 , 1 , 2 , 3 , 4, 5 (正数索引)
// 只要5个元素, 移除0 ~ -6之间的元素,只保留-1~ -5元素
zSetOperations.removeRange(KEY_HISTORY + userId, 0, -9); // 保留8个skuId
}
// 从redis中拿到对应用户的SkuId
public List<Long> getRecentHistorySkuId(long userId) {
if (userId <= 0) {
return Collections.emptyList();
}
// 获取用户最近浏览的SkuId
Set<String> skuIds = this.redisTemplate.opsForZSet().reverseRange(KEY_HISTORY + userId, 0, 7);
List<Long> skuId = new ArrayList<>();
skuIds.forEach(item -> {
skuId.add(Long.valueOf(item));
});
return skuId;
}
这里有一个removeRange函数, 其目的是为了保证redis中只存储8个元素.
如下图:
右侧位redis中索引( 正数索引从0开始表示第一个元素, 负数索引从-1开始表示最后一个元素 ), 因此removeRange(KEY_HISTORY + userId, 0, -6); 这个函数的目的是移除索引0 ~ -6之间的元素, 也就是把value为1000 这个元素移除掉了.