1. 使用Pipeline批量操作:Redis Sorted Set的ZADD、ZINCRBY等操作可以通过Pipeline批量提交,大幅减少网络RTT开销。代码示例:
pipeline = redis.pipeline()
for i in range(1000):
pipeline.zadd('score:leaderboard', {f'user{i}': i})
pipeline.execute()CSDN博客
2. 选择合适的Score精度:使用整数Score而不是浮点数,避免浮点精度问题,同时提升排序效率。Score范围控制在Long.MAX_VALUE内,确保排序稳定性。
Redis官方文档实践
3. 分片设计避免热点Key:单Key存储用户数超过1千万时,分成多个Sorted Set,如user_score_001~user_score_999,使用一致性Hash分配。
阿里云Redis最佳实践
4. 延迟删除+定时清理:ZREM操作昂贵,使用标记删除+ZREMRANGEBYSCORE定期清理过期Score,减少即时删除开销。
腾讯云开发者社区
5. 使用Lua脚本原子化操作:ZINCRBY+ZRANK组合用Lua脚本实现,避免竞态条件:
local current = redis.call('ZSCORE', KEYS[1], ARGV[1])
if current then
local newscore = current + ARGV[2]
redis.call('ZADD', KEYS[1], newscore, ARGV[1])
return redis.call('ZRANK', KEYS[1], ARGV[1])
end
知乎高赞回答
6. 内存优化-设置maxmemory-policy:使用allkeys-lru策略,结合ZUNIONSTORE聚合排行榜,避免内存溢出导致Score丢失。
Redis中国社区
7. 读写分离+Sentinel:主库负责Score更新,从库处理ZREVRANGEBYSCORE排行榜查询,实现读写分离提升QPS。
掘金实战文章
FAQ
Q: Sorted Set单Key能存多少用户Score?
A: 建议控制在500万以内,超过使用分片。
Q: ZRANGE查询慢怎么优化?
A: 使用ZREVRANGE 0 99 WITHSCORES,只查TopN,避免全量扫描。
Q: Score更新频率高时卡顿?
A: 异步更新+Pipeline批量提交,每秒控制在1万次以内。
Q: 跨服排行榜怎么实现?
A: ZUNIONSTORE临时Key聚合各服榜单,每5分钟刷新一次。