1、storm处理数据,数据准备。
@Override
public void execute(Tuple input) {
Date date = new Date();
LinkedList<String> redisKeyList = new LinkedList<>();
try {
// 主题id
topicId = input.getStringByField("topicId");
// 城市
cityCode = input.getStringByField("cityCode");
// 用户唯一标识
userKey = input.getStringByField("userKey");
// 用于辅助表的key
tempMapKey = userKey + "_" + topicId;
// 生成近7天的key(每次生成当前天数往前推7天的key的集合)
for (int i= 0; i < 7 ;i++){
String key = cityCode+"_uv_"+DateUtil.getDayN(date,i)+"_mostPopularTopic";
redisKeyList.add(key);
}
// 写入数据到redis
EsfTopNService.saveEsfTopNDataToRedis(redisKeyList,tempMapKey,topicId);
}catch (Exception e) {
e.printStackTrace();
}finally {
this.collector.ack(input);
}
}
2、把数据保存到redis中
/**
* @功能描述: 保存topN的数据
* @使用对象: 对外接口数据落地
* @接口版本: 2.0.0
* @创建作者: <a href="mailto:xxxx">zys</a>
* @创建日期: 2019-11-20 10:00:41
* @方法参数: [redisKeyList, tempMapKey, paramId]
* @返回类型: void
*/
public static void saveEsfTopNDataToRedis(List<String> redisKeyList,String tempMapKey,String paramId){
Jedis jedis = CodisUtil.getClient();
try{
for (String baseKey : redisKeyList) {
// 用于去重数据
String tempEsfKey = "temp_esf_" + baseKey;
// 保存最终的数据
String finalEsfKey = "esf_" + baseKey;
// 判断数据是否存在
Boolean exists = jedis.hexists(tempEsfKey, tempMapKey);
if (exists){
// 存在直接加1
jedis.hincrBy(tempEsfKey,tempMapKey,1);
}else {
// 不存在,先创建辅助数据,用于去重
jedis.hset(tempEsfKey,tempMapKey,"1");
// 设置数据过期时间,因为这里是统计近7天某个主题UV的topN,所以设置有效时间8天,避免浪费内存
jedis.expire(tempEsfKey,8*60*60*24);
// UV 数据加1,这里使用 zset类型的存储,方便获取topN的数据,不用自己去单独排序,充分利用redis的特性
// 先判断是否有数据,没有新增,否则直接相加
Double zscore = jedis.zscore(finalEsfKey, paramId);
if (null != zscore && zscore > 0){
jedis.zincrby(finalEsfKey,1,paramId);
}else {
// 不存在的数据,直接加1
jedis.zadd(finalEsfKey,1,paramId);
// 设置过期时间
jedis.expire(finalEsfKey,8*60*60*24);
}
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(null != jedis){
jedis.close();
}
}
}
3、数据落地后对外提供使用:
Jedis jedis = null;
try {
jedis = CodisUtil.getClient();
Set<Tuple> tuples = jedis.zrevrangeWithScores(redisKey, 0, 4);
for (Tuple tuple : tuples) {
System.out.println("主题id:"+tuple.getElement()+";topN的值:"+tuple.getScore());
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (null != jedis){
jedis.close();
}
}