基于Redis、Storm的实时数据查询实践
通过算法小组给出的聚合文件,我们需要实现一种业务场景,通过用户的消费地点的商户ID与posId,查询出他所在的商圈,并通过商圈地点查询出与该区域的做活动的商户,并与之进行消息匹配,推送相应活动信息到用户手机。
那么整个流程分为两步,第一步,将整个聚合文件刷入缓存,文件数据格式如下:
29 1:1 102100156910958 10015691 X有限公司 0 1
29 1:1 102100156910958 10015691 X有限公司 0 1
字段含义分别是 地区编号、商圈编号、商户编号、Pos编号、商户名称、合作商户标志。那么我们可以通过 商户编号+Post编号 来定位 其所在的商圈, 可以通过 地区编号+商圈编号 来获取该商圈的所有商户信息(Redis中直接set)。于是导入Redis是可使用key:商户编号+Post编号 value:地区编号+商圈编号 。 随之第二个key 为 地区编号+商圈编号 从而得到 该商圈的所有商户(Redis中使用hset)。
将聚合文件导入Redis,,部分代码如下
String merchantId = StringUtils.join("V_",content[2].trim(),content[3].trim()); String areabiz = StringUtils.join(content[0].trim(),content[1].trim()); String merchantName = StringUtils.join(content[4].trim()); String flag = StringUtils.join(content[5].trim()); Map<String,String> MerchantMap = new HashMap<String,String>(); MerchantMap.put(merchantName, merchantId); try { for (int i = 0; i < jedisvPools.size(); i++) { JedisPool jp = jedisvPools.get(i); Jedis jedis = null; try { jedis = jp.getResource(); //key为商户编号+PosId value为地区编号area+商圈编号bizAreaId jedis.set(merchantId, areabiz); //key为商圈编号+PosId value为商户名称,使用sadd添加相同商圈编号+PosId的商户 if("1".equals(flag)){ jedis.hmset(areabiz, MerchantMap); } } catch (Exception e) { logger.error("", e); } finally { jedis.close(); } }
将需要匹配的活动商户文件及信息导入redis,,部分代码如下
if (StringUtils.isEmpty(content[4]) || StringUtils.isEmpty(content[5]) ||StringUtils.isEmpty(content[6])) { logger.warn("数据格式有误,内容为:{}", line); return; } String merchantId = ""; String posIds = StringUtils.join(content[5]); String address = StringUtils.join(content[3]); String[] posIdArray = posIds.split("、"); String url = content[6]; Map<String,String> MerchantUrlAdress = new HashMap<String,String>(); MerchantUrlAdress.put(address,url); for(String posId : posIdArray){ merchantId = StringUtils.join("Vir_",content[4].trim(),posId.trim()); try { for (int i = 0; i < jedisPools.size(); i++) { JedisPool jp = jedisPools.get(i); Jedis jedis = null; try { jedis = jp.getResource(); //key为商户编号+PosId value为地区编号area+商圈编号bizAreaId jedis.hmset(merchantId,MerchantUrlAdress); } catch (Exception e) { logger.error("", e); } finally { //jedis.close(); jp.returnResourceObject(jedis); } }
接入用户实时刷卡消费信息,流入storm,匹配该用户所在商圈的活动商户,并匹配获取该活动商户的地址及url信息 通过http的形式推送至支付宝或微信渠道,部分代码如下:
String bizAreaName = ""; String bizAreaUrl = ""; String address = ""; //根据活动商户ID与postId 查询所在商圈 String areabiz = virtualBusinessService.getAreaBiz(MerchantId); if(null == areabiz){ resultSets.addValue(ResultSets.OpType.INSERT,"BIZAREALISTNAME",bizAreaName); resultSets.addValue(ResultSets.OpType.INSERT, "BIZAREAURL", bizAreaUrl); resultSets.addValue(ResultSets.OpType.INSERT, "BIZADDRESS", address); logger.info("VirtualTradeAreaAlgorithm="+MerchantId); return resultSets; } //根据活动ID,获取该活动配置的商户Id String activityMerchantCode = virtualBusinessService.getActivityConf(activityConfId); //查询所在商圈的所有商户信息 Map<String,String> bizAreaNameMap = virtualBusinessService.getbizAreaNameSet(areabiz); if(!bizAreaNameMap.isEmpty()){ //匹配活动配置的商户 for(String bizName : bizAreaNameMap.keySet()){ String mapvalue = bizAreaNameMap.get(bizName).replace("V_", ""); if(activityMerchantCode.contains(mapvalue)){ bizAreaName = bizName; //根据活动商户名称查询该商户对应的商户ID activityMerchantId = bizAreaNameMap.get(bizName).replace("V_","Vir_"); //根据活动商户Id,查询该活动商户的url Vir_89811144816144501080209 Map<String,String> bizAreaUrlAdree = virtualBusinessService.getBizUrl(activityMerchantId); if(null == bizAreaUrlAdree){ address = ""; bizAreaUrl = ""; }else{ for(String bizAdress : bizAreaUrlAdree.keySet()){ address = bizAdress; bizAreaUrl = bizAreaUrlAdree.get(bizAdress); } } break; } } }
具体还在整理,后续将其补全~