上一篇
【最新动态】2025年8月,Redis Labs宣布其最新版本Redis 7.6在计数器性能上实现了15%的提升,特别是在高并发场景下的原子操作效率显著增强,这为需要高性能计数服务的应用提供了更强大的支持。
在开发过程中,我们经常需要实现各种计数功能——网站访问量统计、用户点赞数、商品库存计数、实时在线人数等,传统数据库虽然也能实现这些功能,但在高并发场景下往往成为性能瓶颈。
Redis作为内存数据库,其计数器功能具有三大核心优势:
import redis # 连接Redis r = redis.Redis(host='localhost', port=6379, db=0) # 初始化计数器 r.set('page_views', 0) # 增加计数 r.incr('page_views') # +1 r.incrby('page_views', 10) # 增加指定数值 # 减少计数 r.decr('page_views') # -1 r.decrby('page_views', 5) # 减少指定数值 # 获取当前值 current_views = r.get('page_views') print(f"当前页面访问量: {current_views}")
# 设置初始值并添加30天过期时间 r.setex('daily_active_users', 30*24*60*60, 0) # 用户活跃时增加计数 r.incr('daily_active_users') # 获取剩余过期时间 ttl = r.ttl('daily_active_users') print(f"计数器将在{ttl}秒后自动清除")
from datetime import datetime def record_activity(user_id): today = datetime.now().strftime("%Y%m%d") # 用户日活跃 r.incr(f"user:{user_id}:activity:{today}") # 全局日活跃 r.incr(f"global:activity:{today}") # 同时维护一个30天的集合 r.zadd("recent_activity", {today: int(datetime.now().timestamp())}) # 保留最近30天数据 r.zremrangebyscore("recent_activity", 0, int(datetime.now().timestamp())-30*24*60*60)
当需要统计UV(独立访客)这类去重计数时,可以使用HyperLogLog:
# 添加用户访问 r.pfadd("daily_uv", "user1", "user2", "user3") # 获取估算的UV数 uv_count = r.pfcount("daily_uv") print(f"今日独立访客数(估算): {uv_count}")
# 用户完成某个行为时 def user_completed_action(user_id, points): r.zincrby("leaderboard", points, user_id) # 获取排行榜前10 top_users = r.zrevrange("leaderboard", 0, 9, withscores=True) print("排行榜TOP10:") for rank, (user, score) in enumerate(top_users, 1): print(f"{rank}. 用户{user.decode()}: {int(score)}分")
键名设计规范
service:metric:time
持久化考虑
性能优化
# 使用pipeline批量更新多个计数器 pipe = r.pipeline() pipe.incr("counter1") pipe.incrby("counter2", 5) pipe.decr("counter3") pipe.execute()
-- 计数器增加的Lua脚本示例 local current = redis.call('GET', KEYS[1]) if not current then redis.call('SET', KEYS[1], ARGV[1]) else redis.call('INCRBY', KEYS[1], ARGV[1]) end return redis.call('GET', KEYS[1])
问题1:计数器重置
问题2:计数不准确
# 使用事务保证准确性 with r.pipeline() as pipe: while True: try: pipe.watch('my_counter') current_value = int(pipe.get('my_counter') or 0) pipe.multi() pipe.set('my_counter', current_value + 1) pipe.execute() break except redis.WatchError: continue
问题3:热点Key问题
# 将单个计数器拆分为10个分片 def incr_counter(counter_name, num_shards=10): shard = hash(counter_name) % num_shards r.incr(f"{counter_name}:shard_{shard}") def get_counter(counter_name, num_shards=10): total = 0 for i in range(num_shards): val = int(r.get(f"{counter_name}:shard_{i}") or 0) total += val return total
根据2025年Redis技术路线图,计数器功能将会有以下改进方向:
Redis计数器虽然简单,但在实际应用中却能解决许多复杂的业务场景,掌握这些技巧,你的应用将能轻松应对从百万到亿级的计数需求,好的技术方案不在于复杂,而在于恰到好处地解决问题。
本文由 犹康震 于2025-08-02发表在【云服务器提供商】,文中图片由(犹康震)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/518651.html
发表评论