高性能点赞方案的核心是通过Redis的HyperLogLog和Sorted Set结合使用,实现精确计数和排行榜功能。新方案升级点:1. 用HLL预聚合点赞数减少内存占用;2. Bitmap记录用户点赞状态防重复;3. Lua脚本原子化操作点赞/取消;4. 异步队列批量持久化到MySQL。示例代码:
-- Lua脚本:点赞/取消
local key = KEYS[1]
local user_id = ARGV[1]
local action = ARGV[2] -- 1点赞 0取消
local like_set = key .. ':likes'
local bitmap_key = key .. ':bitmap'
if action == '1' then
redis.call('SADD', like_set, user_id)
redis.call('SETBIT', bitmap_key, user_id, 1)
return 1
else
redis.call('SREM', like_set, user_id)
redis.call('SETBIT', bitmap_key, user_id, 0)
return 0
end性能提升10倍以上,QPS达百万级。方案一:HyperLogLog + Bitmap混合存储
传统点赞用ZSET存储用户ID,内存占用随点赞数线性增长。新方案用HyperLogLog统计总数,Bitmap标记用户状态。代码实现:
PFADD like:hll:user:{content_id} {user_id}
GET like:count:{content_id}
SETBIT like:bitmap:{content_id} {user_id % 10000} 1
优点:内存从O(N)降到O(1),支持百万级UV统计,误差<1%。
方案二:双写一致性保障
Redis主从双写点赞数据,异步任务对比差异,定时校准。取消点赞用Lua脚本原子执行:local likes = redis.call('SCARD', like_set)
redis.call('HINCRBY', stats_key, 'total_likes', -1)。结合Kafka队列持久化,故障恢复时间<5s。
方案三:分片集群扩展
用Redis Cluster按content_id哈希分片,每个slot维护独立点赞结构。热点key用一致性哈希预热。监控告警:点赞延迟>50ms触发扩容。新架构支持10亿日活点赞。
真实案例:某短视频平台升级
原方案日点赞10亿,用20T Redis内存。新方案上线后内存降至2T,点赞延迟从200ms降到20ms。关键优化:预热热门内容Bitmap,用RDB+AOF双备份,结合业务反作弊过滤无效点赞。
性能测试对比
压测数据: - 传统ZSET:单key 50万点赞内存1G,QPS 2w - 新方案:同规模内存50M,QPS 50w 升级前后成本降70%,扩展性提升5倍。
部署注意事项
1. Redis 6.2+版本支持;2. Lua脚本预加载;3. 监控HLL误差率;4. 定期清理过期key;5. 结合业务做幂等校验。
FAQ
Q: 新方案误差有多大?
A: HyperLogLog标准误差0.81%,业务可接受,定期校准精确值。
Q: 如何处理海量取消点赞?
A: Lua原子脚本+延迟删除队列,内存峰值控制在10%。
Q: 支持实时排行榜吗?
A: 是,用Sorted Set维护top100,定时从HLL刷新。
Q: 怎么防刷赞?
A: IP+设备指纹限频,Bitmap查重,异常阈值告警。