SpringBoot进阶-Redis亿级流量UV统计解决方案(六)
网站运营数据
我们知道对于一个网站而言运营数据很重要,他直接关系到你可以拉到多少投资,以及网站以后的优化方向。
常见的运营指标有UV(Qnique Visitor,独立访客),PV(Page View,页面浏览量), DAU(Daily Active User,日活用户量),MAU(Monthly Active User 月活用户量).
一般UV是如何统计的呢?主要通过请求ip来计算,一个独立ip算一个访客,需要去重统计。
该如何存储呢?mysql?这个可以直接忽略了,很难扛住亿级流量。
redis的set类型呢?ip类型可以转成8字节的long型数字,存储一亿个需要762MB内存,貌似可以接受,但是要知道一个网站不止一个网页,要统计所有网页的UV的话就无法接受了。
bitmap类型呢?亿级访问需要12MB内存,1000个网页12G内存,还算可以,但不是最优方案。接下来就是我们的主角HyperLogLog登场了。
HyperLogLog类型
HyperLogLog的优点是可以用来做基数统计,所谓基数就是会去重。而且它只需要花费12KB的内存,就可以计算接近2^64个不同的基数,缺点是会有0.81%的误差,不像bitmap是精确统计,但节省的内存和运行速度不是一个数量级的,PS: bitmap的bitcount命令的时间复杂度是O(N),也就是说数据越多速度越慢。亿级流量大概几十万的误差,可以接受,综合考虑下来无疑是最优方案。
HyperLogLog原理很复杂,使用起来却超级简单,常用的就两个命令
添加元素:
pfadd key element
统计元素个数:
pfcount key
理论加实践,我们直接上代码:
public class HyperLogLogController extends BaseController {
@Autowired
private RedisTemplate redisTemplate;
@PostMapping
@ApiOperation(value = "模拟访问")
public Result visit() {
for (int i = 1; i <= 200; i++) {
String ip = RandomUtils.nextInt(256) + "." + RandomUtils.nextInt(256) + "." + RandomUtils.nextInt(256) + "." + RandomUtils.nextInt(256);
//放入ip
redisTemplate.opsForHyperLogLog().add("UV", ip);
}
return resultOk();
}
@GetMapping
@ApiOperation(value = "统计UV")
public Result total() {
long total = redisTemplate.opsForHyperLogLog().size("UV");
return resultOk(total);
}
}
对于HyperLogLog原理感兴趣的可以参考这篇文章: https://juejin.cn/post/6844903785744056333
参考项目(模块: SpringBoot-HelloWorld): https://gitee.com/huatin/java-test
相关文章
- redis实战笔记(10)-第10章 扩展Redis
- redis实战笔记(2)-第2章 使用 Redis构建Web应用
- Docker最全教程——Redis容器化以及排行榜实战(十三)
- Spring Boot demo系列 :Redis缓存
- Redis开发与运维. 3.9 本章重点回顾
- 终于把Redis中7千万个Key删完了
- SpringBoot集成Redis
- Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>
- Spring Boot 2 实战:利用Redis的Geo功能实现查找附近的位置
- springboot redis发布与订阅
- springboot学习之三(整合redis)
- 浅析redis setIfAbsent的用法及在分布式锁上的应用及同步锁的缺陷
- Redis基础:特点(内存运行、原子性、持久化)、5种基本数据类型与3种特殊数据类型、redis命令、发布订阅机制、事务(单条命令原子性事务不是原子性)、数据备份与恢复、安全
- 【redis故障处理】redis omm问题
- spring-data-redis 使用
- 曹工说Redis源码(6)-- redis server 主循环大体流程解析
- 曹工说Redis源码(1)-- redis debug环境搭建,使用clion,达到和调试java一样的效果
- Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝,无法连