Redis高级数据类型

测试HyperLogLog的使用
//统计20万个数据的独立总数@Testpublic void testHyperLogLog(){String redisKey = "test:hll:01";for(int i = 1; i <= 100000; i++){redisTemplate.opsForHyperLogLog().add(redisKey,i);}for(int i = 1; i <= 100000; i++){int r = (int) (Math.random() * 100000 + 1);redisTemplate.opsForHyperLogLog().add(redisKey,r);}Long size = redisTemplate.opsForHyperLogLog().size(redisKey);System.out.println(size);}//size = 99553
//将三组数据合并,再统计合并重复数据的独立总数@Testpublic void testHyperLoglogUnion(){String redisKey2 = "test:hll:02";for (int i = 1; i <= 10000; i++) {redisTemplate.opsForHyperLogLog().add(redisKey2,i);}String redisKey3 = "test:hll:03";for (int i = 1; i <= 15000; i++) {redisTemplate.opsForHyperLogLog().add(redisKey3,i);}String redisKey4 = "test:hll:04";for(int i = 1; i <= 20000; i++){redisTemplate.opsForHyperLogLog().add(redisKey4,i);}String redisKeyUnion = "test:hll:union";Long size = redisTemplate.opsForHyperLogLog().union(redisKeyUnion,redisKey2,redisKey3,redisKey4);System.out.println(size);}
测试Bitmap的使用
//统计一组数据的布尔值@Testpublic void testBitMap(){String redisKey = "test:bm:01";//记录redisTemplate.opsForValue().setBit(redisKey,1,true);redisTemplate.opsForValue().setBit(redisKey,4,true);redisTemplate.opsForValue().setBit(redisKey,7,true);//查询System.out.println(redisTemplate.opsForValue().getBit(redisKey,0));System.out.println(redisTemplate.opsForValue().getBit(redisKey,1));System.out.println(redisTemplate.opsForValue().getBit(redisKey,2));//统计Object obj = redisTemplate.execute(new RedisCallback() {@Overridepublic Object doInRedis(RedisConnection redisConnection) throws DataAccessException {return redisConnection.bitCount(redisKey.getBytes());}});System.out.println(obj);}
网站数据统计

DataService
public class DataService {@Autowiredprivate RedisTemplate redisTemplate;private SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");public void recordUV(String ip){String redisKey = RedisKeyUtil.getUVKey(df.format(new Date()));redisTemplate.opsForHyperLogLog().add(redisKey,ip);}public long calculateUV(Date start, Date end){if(start == null || end == null){throw new IllegalArgumentException("参数不能为空");}//整理该日期内的keyList<String> KeyList = new ArrayList<>();Calendar calendar = Calendar.getInstance();calendar.setTime(start);while (!calendar.getTime().after(end)){String key = RedisKeyUtil.getUVKey(df.format(calendar.getTime()));KeyList.add(key);calendar.add(Calendar.DATE,1);}//合并这些天的 UVString redisKey = RedisKeyUtil.getUVKey(df.format(start), df.format(end));redisTemplate.opsForHyperLogLog().union(redisKey,KeyList.toArray());// 返回统计结果return redisTemplate.opsForHyperLogLog().size(redisKey);}/*** 将指定的 IP 计入当天的 DAU* @param userId*/public void recordDAU(int userId) {String redisKey = RedisKeyUtil.getDAUKey(df.format(new Date()));redisTemplate.opsForValue().setBit(redisKey, userId, true);}/*** 统计指定日期范围内的 DAU* @param start* @param end* @return*/public long calculateDAU(Date start, Date end) {if (start == null || end == null) {throw new IllegalArgumentException("参数不能为空");}// 整理该日期范围内的 keyList<byte[]> keyList = new ArrayList<>();Calendar calendar = Calendar.getInstance();calendar.setTime(start);while (!calendar.getTime().after(end)) {String key = RedisKeyUtil.getDAUKey(df.format(calendar.getTime()));keyList.add(key.getBytes());calendar.add(Calendar.DATE, 1); // 加1天}// 进行 or 运算return (long) redisTemplate.execute(new RedisCallback() {@Overridepublic Object doInRedis(RedisConnection redisConnection) throws DataAccessException {String redisKey = RedisKeyUtil.getDAUKey(df.format(start), df.format(end));redisConnection.bitOp(RedisStringCommands.BitOperation.OR,redisKey.getBytes(), keyList.toArray(new byte[0][0]));return redisConnection.bitCount(redisKey.getBytes());}});}}
DataController
@Controllerpublic class DataController implements CommunityConstant {@Autowiredprivate DataService dataService;/*** 进入统计页面* @return*/@RequestMapping(value = "/data", method = {RequestMethod.GET,RequestMethod.POST})public String getDataPage(){return "/site/admin/data";}/*** 统计网站 uv(独立用户访问)* @param start* @param end* @param model* @return*/@PostMapping("/data/uv")public String getUV(@DateTimeFormat(pattern = "yy-MM-dd")Date start,@DateTimeFormat(pattern = "yy-MM-dd")Date end,Model model){long uv = dataService.calculateUV(start, end);model.addAttribute("uvResult",uv);model.addAttribute("uvStartDate",start);model.addAttribute("uvEndDate",end);return "forward:/data";}/*** 统计网站 dau(日活跃用户数量)* @param start* @param end* @param model* @return*/@PostMapping("/data/dau")public String getDAU(@DateTimeFormat(pattern = "yyyy-MM-dd") Date start,@DateTimeFormat(pattern = "yyyy-MM-dd") Date end,Model model){long dau = dataService.calculateDAU(start,end);model.addAttribute("dauResult",dau);model.addAttribute("dauStartDAte",start);model.addAttribute("dauEndDate",end);return "forward:/data";}}
