当前位置: 代码网 > it编程>数据库>Redis > Redis统计访问量的3种实现方式

Redis统计访问量的3种实现方式

2025年06月10日 Redis 我要评论
一、你是否遇到过这些统计难题?高并发场景下内存爆炸:用hash统计日活时,单键内存占用飙升到10mb?独立访客重复计数:用户多次访问被重复统计,导致uv数据虚高?近似值误差过大:百万级pv统计时,误差

一、你是否遇到过这些统计难题?

  • 高并发场景下内存爆炸:用hash统计日活时,单键内存占用飙升到10mb?
  • 独立访客重复计数:用户多次访问被重复统计,导致uv数据虚高?
  • 近似值误差过大:百万级pv统计时,误差率超过5%?

这些问题,redis的3种核心方案能帮你解决!

二、方案一:hash结构实时统计

适用场景:

  • 实时统计独立用户(如日活/周活)
  • 需要精确计数(如商品点击次数)

核心代码:

# 场景:记录用户访问时间戳(防重复计数)
pipeline.hset("user:visits:202310", user_id, time.time())
pipeline.expire("user:visits:202310", 86400)  # 每天清理一次

# 统计当前活跃用户数
current_uv = redis.hlen("user:visits:202310")

参数说明:

  • hset:哈希表存储用户id和最后访问时间
  • expire:自动清理过期数据,避免内存泄漏
  • 痛点解决:通过时间戳去重,精确统计独立用户

内存优化技巧:

  • 问题:10万用户id存储需约100kb * 10^5 = 10gb
  • 方案:使用user_id:md5缩短键名,内存占用可降低至**<1mb/万用户**

三、方案二:bitmap统计独立访客

适用场景:

  • 亿级用户规模的uv统计
  • 内存敏感场景(如单机统计全站访问量)

核心代码:

# 场景:统计本月访问过的用户(假设用户id为整数)
user_id = 123456
redis.setbit("uv:202310", user_id, 1)

# 获取本月uv总数
total_uv = redis.bitcount("uv:202310")

参数说明:

  • setbit:将用户id对应位设为1,每个用户仅占1bit内存
  • bitcount:统计所有置位位数,时间复杂度o(1)

内存对比:

方法

100万用户内存占用

精度

hash

~100mb

100%

bitmap~125kb100%

四、方案三:hyperloglog估算uv

适用场景:

  • 超大规模近似统计(如全网日活)
  • 可接受误差的场景(误差率<0.8%)

核心代码:

# 场景:统计全站日活(误差率0.5%)  
redis.pfadd("uv:202310", user_id)
estimated_uv = redis.pfcount("uv:202310")

参数说明:

  • pfadd:将用户id加入hyperloglog结构
  • pfcount:返回近似值,内存占用仅<1kb/百万用户

性能对比:

方法

1000万用户内存

统计误差

bitmap

1.25mb

0%

hyperloglog<1kb0.5%

五、实战选择指南

对比表格:

方案

内存占用

精度

适用场景

hash

中(mb级)

100%

小规模精确统计

bitmap极低(kb级)

100%

大规模精确去重

hyperloglog超低(kb级)

<1%

超大规模近似统计

优化建议:

  • 混合方案:用hash统计小时级数据,用hyperloglog汇总日级数据
  • 数据分片:对亿级用户id按user_id % n分片存储,降低单键内存压力
  • 冷热分离:历史数据定期转储到mysql,redis仅保留活跃数据

六、总结

redis统计访问量的本质是内存优化+算法选型的平衡。

  • 痛点场景:用bitmap解决内存爆炸,用hyperloglog应对超大规模
  • 实时需求:hash结构仍是精确统计的首选

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com