2026-06-22 23:14:46
对于新浪微博关注功能这类海量关注关系的存储,推荐使用NoSQL数据库,如Redis,采用zset或set数据结构进行高效存储和管理。 以下是具体方案及分析:
一、数据结构选择zset(有序集合):
优势:
支持权重排序:可基于排序值(如关注时间、互动频率等)存储关注关系,便于按时间或权重排序获取关注列表。
高效排序与范围查询:通过分数(score)快速获取最新关注、最早关注或特定时间范围内的关注关系。
适用场景:
存储用户之间的双向关注关系(如A关注B,B关注A),分数可记录关注时间戳或互动权重。
需按时间、权重等维度排序的场景。
set(无序集合):
优势:
实现简单:直接存储用户ID集合,无需额外排序逻辑。
查询与更新高效:支持快速判断用户是否被关注、添加/删除关注关系。
适用场景:
存储每个用户的关注者集合(如用户A的所有粉丝),便于快速查询粉丝列表。
需高频查询但无需排序的场景。
方案1:zset存储双向关注关系 + set存储关注者集合
zset存储:
键(key):user:follow:A:B(表示用户A关注用户B)。
值(member):用户B的ID。
分数(score):关注时间戳(如Unix时间戳)。
操作示例:
添加关注:ZADD user:follow:A:B <timestamp> B。
查询最新关注:ZREVRANGE user:follow:A:B 0 10(获取A最新关注的10个用户)。
set存储:
键(key):user:followers:B(表示用户B的所有粉丝)。
值(member):粉丝用户ID集合。
操作示例:
添加粉丝:SADD user:followers:B A。
查询粉丝数:SCARD user:followers:B。
方案2:纯zset存储(简化版)
若无需单独维护关注者集合,可仅用zset存储:
键(key):user:follows:A(表示用户A的所有关注)。
值(member):被关注用户ID。
分数(score):关注时间戳。
操作示例:
添加关注:ZADD user:follows:A <timestamp> B。
查询关注列表:ZRANGE user:follows:A 0 -1(按时间升序)。
并发访问控制:
使用Redis事务(MULTI/EXEC)或Lua脚本保证原子性,避免并发修改导致数据不一致。
示例:同时更新zset和set时,通过Lua脚本确保操作同步。
数据一致性:
采用最终一致性模型:允许短暂不一致,通过异步消息队列(如Kafka)同步数据到其他存储(如MySQL)。
或使用强一致性方案:如Redis集群的WATCCH/MULTI命令,但可能影响性能。
分片与扩容:
按用户ID哈希分片:将用户数据分散到不同Redis节点,避免单节点压力过大。
动态扩容:通过Redis Cluster自动扩展节点。
缓存策略:
热点数据缓存:对高频查询的关注列表(如明星用户)使用本地缓存(如Guava)。
失效机制:设置合理的TTL(如5分钟),平衡实时性与性能。
关注关系表可能达千亿级,JOIN操作性能差。
排序、分页查询效率低(如按时间排序需全表扫描)。
横向扩展能力:Redis集群可支持PB级数据。
低延迟:zset/set的O(1)或O(log N)复杂度满足实时需求。
使用MySQL分表存储关注关系,但面临扩展性问题。
后期迁移至FlockDB(基于MySQL的定制化方案),仍需优化排序性能。
采用Redis集群存储关注关系,zset记录关注时间,set维护粉丝列表。
通过异步队列同步到HBase供离线分析。
权重设计:分数字段可扩展为复合值(如时间戳+互动权重)。
监控指标:QPS、延迟、内存使用率。
灾备方案:定期备份Redis数据到持久化存储(如S3)。
通过上述方案,可高效存储和管理海量关注关系,同时保障系统性能与可扩展性。