目录
1、亿级系统中常见的四种统计
- 聚合统计
交集、并集、差集和聚合函数的应用
- 排序统计
按时间排序(正序、反序+分页),实时性
- 二值统计
集合元素取值只有0和1两种,常见于bitmap
- 基数统计
统计一个集合中不重复的元素个数,常见于hyperloglog
2、数据统计名词解释
-
UV
unique visitor,独立访客,一般理解为客户端IP
-
PV
page view,页面浏览量
-
DAU
daily active user,日活跃用户量
-
MAU
mouth active user,月活跃用户量
3、hyperloglog(去重基数统计)
Redis HyperLogLog 是一种数据结构,用于估计集合中的唯一元素的数量。它可以用来进行基数估计,在很少的内存使用下,能够高效地处理大规模的数据。它使用固定的内存空间来跟踪集合中的唯一元素的数量,而不是存储实际的元素。需要注意的是,HyperLogLog 估计的结果是一个接近实际值的近似值,有一定的误差范围(0.81%)。
在Redis里面,每个hyperloglog键只需要花费12kb内存,就可以计算接近2^64个不同元素的基数。
淘宝网站首页亿级用户的UV统计
package com.toonyoo.redis.hyperloglog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Random;
@Service
@Slf4j
public class HyperloglogService {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 开启一个新线程,模拟用户访问淘宝首页的ip地址
*/
@PostConstruct
public void initIP() {
new Thread(() -> {
String ip = null;
for (int i = 0; i < 200; i++) {
Random random = new Random();
// 随机模拟不同的ip
ip = random.nextInt(256)+"."+random.nextInt(256)+"."+random.nextInt(256)+"."+random.nextInt(256);
// 将此ip加入redis hyperloglog key中
Long hllKey = redisTemplate.opsForHyperLogLog().add("hll_key", ip);
log.info("当前用户ip:{},此ip访问次数为:{}", ip,hllKey);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "t1").start();
}
/**
* 返回淘宝首页的uv
* @return
*/
public long taoBaoUV(){
return redisTemplate.opsForHyperLogLog().size("hll_key");
}
}
package com.toonyoo.redis.hyperloglog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HyperloglogController {
@Autowired
private HyperloglogService hyperloglogService;
@RequestMapping("/uv")
public long taoBaoUV(){
return hyperloglogService.taoBaoUV();
}
}
一段时间后,查询Redis,统计结果如下:
第一次访问次数29,第二次访问次数66。