关注关系不只是「一张 follow 表」——它是一张有向社交图谱:谁关注了谁、共同关注了什么、内容沿着什么路径传播。图上的问题(「我的关注还关注了谁」「这条内容是怎么传到我这的」)决定了推荐关注、信息流、社区治理的质量。本文把这张图讲透:图模型怎么建、共同关注与二度关系怎么高效查询、推荐关注算法怎么做、转发传播怎么分析、存储选型与规模演进,以及最容易忽略的防刷。
前置:/miniblog-follow-timeline-push-pull/(关注关系与时间线)、/miniblog-architecture-design/(关系系统设计)、/miniblog-data-model-schema/(社交域表设计)、/miniblog-analytics-stats/(行为数据)。图数据库基础可参考 图数据库专题。
目录
- 1. 关注关系是图:有向图的建模
- 2. 邻接与反邻接:关注/粉丝的存储
- 3. 共同关注:交集查询的工程实现
- 4. 二度关系:间接关注与扩展推荐
- 5. 推荐关注算法:协同、相似与热门
- 6. 传播路径分析:转发链与影响力
- 7. 存储选型:关系表 vs 图数据库
- 8. 规模演进:从表到图服务的路径
- 9. 防刷与治理:关注行为风控
- 10. 速查表与一句话记忆
- 延伸阅读
1. 关注关系是图:有向图的建模
关注是「方向性」的关系——A 关注 B 不等于 B 关注 A:
图模型:
□ 节点(Node):用户
□ 有向边(Directed Edge):关注(follower → followee)
□ 自环:不允许(不能关注自己)
□ 反边:互相关注(双向)→ 好友/双向关系,可额外标记
图的形态:
邻接(关注的人):follower_id → followee_id(出边)
反邻接(粉丝):followee_id ← follower_id(入边)
规模直觉:
千万用户 → 亿级边 → 单用户度数(关注数/粉丝数)分布极度倾斜
两种「图视角」:
□ 行视角:我关注了谁(出边),决定我的时间线内容源
□ 列视角:谁关注了我(入边),决定我的粉丝与影响力
工程要点:关注图是有向、稀疏、幂律分布的图——大部分用户度数低,极少数大 V 度数极高。所有算法与存储都要考虑到「大 V 的超高扇入/扇出」,否则会在大 V 上爆炸。
2. 邻接与反邻接:关注/粉丝的存储
存储层面,关注/粉丝是两张视图(同一张表的两个索引视角):
物理存储(关系表):
follow(follower_id, followee_id, created_at)
+ 唯一索引 (follower_id, followee_id) → 关注视角(邻接)
+ 二级索引 (followee_id, follower_id) → 粉丝视角(反邻接)
缓存层:
□ 我的关注列表:follow:{uid} (Redis set/zset)
□ 我的粉丝列表:fan:{uid}(大 V 粉丝缓存在 Redis/专用存储)
□ 是否已关注:is_follow:{follower}:{followee}(布隆/缓存)
大 V 特殊性:
□ 大 V 粉丝数千万 → 粉丝列表不能全量入缓存
□ 只缓存「Top 粉丝」或分页读取,全量用专用存储
查询模式:
□ 「我关注了没」→ 唯一索引点查,O(1)
□ 「我的关注列表」→ 索引扫描,分页
□ 「谁关注了我」→ 反邻接扫描(大 V 走专用通道)
工程要点:关注存储的核心是**「一张表 + 两个索引视角」**,查询都变成「走索引的点查/范围查」。大 V 的粉丝列表是热点数据,必须「缓存 Top + 专用存储兜底」,不能全量塞缓存。
3. 共同关注:交集查询的工程实现
「我们共同关注了谁」「你们有哪些共同粉丝」是社交产品的常用能力:
共同关注 = 我关注的 ∩ 对方关注的
共同粉丝 = 我的粉丝 ∩ 对方的粉丝
实现(小集合求交):
□ 取两人关注 id 集合 → 求交集
□ 小集合直接内存求交(各取 Top 5000,交集即可用)
□ 大集合用布隆过滤器先过滤,再精确求交
热度排序:
□ 共同关注不只看「存在」,还要排「谁值得推荐」
□ 排序信号:共同关注者的粉丝数、活跃度、与你关注的时间
应用场景:
□ 「TA 也关注了」推荐(发现新内容源)
□ 「你们有 N 个共同关注」社交粘性提示
□ 关系判定:共同关注多 → 兴趣相似 → 值得推荐
工程要点:共同关注的工程本质是**「两个集合求交」**——在图上就是「两个节点的邻接交集」。小集合内存求交即可,大集合用布隆过滤。别把「全量求交」放到数据库层做(会扫描海量行)。
4. 二度关系:间接关注与扩展推荐
二度关系(朋友的朋友)是扩展社交图谱的关键——也是最容易计算爆炸的:
二度关系定义:
□ 我关注了 A,A 关注了 B(B ≠ 我,且我没关注 B)→ B 是我的二度候选
扩展路径:
□ 直接二度:我的关注 → 他们的关注(一跳扩展)
□ 热门二度:二度关系里被关注最多的 → 「大家都在关注」
□ 逆二度:粉丝的粉丝(潜在传播对象,营销场景)
计算约束:
□ 二度扩展是「扇出爆炸」重灾区:
我关注 100 人 × 每人关注 300 人 = 3 万候选 → 必须限量/加权
□ 只算「Top-K」:每个一度节点只贡献前 K 个二度候选
二度推荐示例:
候选 = 我的关注集合的关注(去重、去掉已关注/自己)
权重 = 共同关注数 / 被关注热度 / 新鲜度
→ 取 Top-N 作为「推荐关注」
工程要点:二度关系必须**「限量扩展」**——不做全量二度,而是「每个一度节点取 Top-K,合并去重排序」。全量二度计算在千万级图上会瞬间爆炸,限量是唯一可持续的做法。
5. 推荐关注算法:协同、相似与热门
推荐关注是社交图谱的「增长引擎」,主流三类算法:
1. 协同过滤(基于关系的协同):
我和用户 U 的共同关注越多 → U 值得关注
→ 直接基于共同关注计数,简单有效
2. 基于相似(用户兴趣相似):
画像相似的用户关注的东西 → 推荐给我
→ 用兴趣向量/内容偏好算相似度(见个性化篇)
3. 基于传播/热门:
「大家都在关注」的上升中作者
→ 全局热度 + 新鲜度,适合冷启动
组合策略:
候选池 = 协同(60%) + 相似(25%) + 热门(15%)
排序 = 权重 * (信号强度) + 新鲜度 + 多样性
冷启动与探索:
□ 新用户:热门作者为主,引导关注
□ 老用户:协同为主,保持「发现感」
□ 探索配额:给长尾优质作者曝光机会
工程要点:推荐关注的本质是**「发现新内容源」**——协同过滤(共同关注)是地基,兴趣相似是进阶,热门是冷启动兜底。推荐结果要「有解释」(「你和 32 人共同关注了 TA」),解释性显著提升关注转化。
6. 传播路径分析:转发链与影响力
转发(Repost)让内容沿社交图传播,分析传播路径能理解影响力:
传播数据结构:
□ 转发链:root_post_id → repost_id → repost_id → ...
□ 每层记录「谁转发的」「谁看到的」
□ 原始内容 + 转发树(有向树结构)
传播分析:
□ 传播深度/广度:多少层、多少节点触达
□ 关键传播者:把内容推向下一个社区的「桥梁」
□ 感染路径:从哪个粉丝群扩散出去的
□ 影响力分:粉丝数 × 活跃度 × 历史传播效率
工程用途:
□ 发现爆款内容的传播模式(哪类内容更容易扩散)
□ 反垃圾:识别「刷转发」的机器传播路径
□ 推荐:借传播路径做「你关注的人转发了」的社交推荐
工程要点:传播分析把「内容火不火」升级为「内容怎么火的」——记录转发树、识别关键传播者。转发树用「根 + 父子引用」存储(每条转发记录 parent_id),分析时沿树做 BFS,不必每次全量重算。
7. 存储选型:关系表 vs 图数据库
关注关系到底放关系表还是图数据库,取决于规模与查询模式:
关系表(PostgreSQL/MySQL):
□ 适合:单点查询、交集查询、分页(我们大部分场景)
□ 优点:生态成熟、事务、与业务表同库
□ 局限:多跳图查询(2-3 跳以上)SQL 复杂且慢
图数据库(Neo4j/ArangoDB/TigerGraph):
□ 适合:深度图查询、路径分析、图算法(社区发现/中心度)
□ 优点:多跳遍历快、图算法原生
□ 局限:运维成本、与业务系统分离
混合方案(主流):
□ 日常功能(关注/粉丝/共同关注)走关系表
□ 深度分析(传播路径/社区发现/影响力)定期导到图库批处理
选型判断:
□ 只要「点查 + 1 跳」→ 关系表足够
□ 需要「3+ 跳 / 图算法」且量大 → 图库或图批处理
□ 绝大多数社交产品的「推荐关注/共同关注」只需 1-2 跳 → 关系表够
工程要点:别急着上图数据库——社交产品的核心查询大多是 1-2 跳,关系表配合索引完全能扛。图数据库的价值在「深度图算法」,做成离线批处理分析平台,与在线关系服务解耦,是最划算的组合。
8. 规模演进:从表到图服务的路径
关注关系的规模演进是有路可循的:
阶段 1(万级用户):单 follow 表 + 索引
→ 全功能可用
阶段 2(百万级):缓存化
→ 关注/粉丝列表入 Redis,大 V 特殊处理
→ 共同关注缓存 + 布隆过滤
阶段 3(千万级):图服务化
→ 独立关系服务(Graph Service)
→ 读写分离、粉丝/关注分库(按用户 id 分片)
→ 布隆 + Top-K 缓存成标配
阶段 4(亿级):专用图存储 + 批处理分析
→ 图查询走专用引擎(自研/图库)
→ 传播/推荐算法离线批处理
演进信号:
□ 关注列表查询 P99 超过预算 → 缓存化
□ 共同关注/推荐关注计算超时 → 预计算 + 缓存
□ 关系服务与业务耦合 → 拆独立服务
工程要点:演进是**「跟着查询热点走」**——先把高频查询缓存化,再拆服务,最后上专用图存储。每阶段的判断标准是「P99 延迟与成本预算」,不是「规模数字」本身。
9. 防刷与治理:关注行为风控
关注关系是社交资产,也是刷量与垃圾的重灾区:
关注风控场景:
□ 批量刷粉(僵尸号互相关注/关注真人)
□ 关注后再取关(洗关注,涨粉骗局)
□ 恶意关注(骚扰、引战)
风控信号:
□ 关注频率异常(秒级关注数百人)
□ 关注/取关比例异常(关注后快速取关)
□ 关注对象的集中度(全关注同一批人)
□ 新号权重:注册时间短 → 关注可信度低
治理手段:
□ 限流:关注操作按用户维度限频(见限流篇)
□ 异步风控:批量关注行为进风控队列,命中即限/封
□ 惩罚:降权(其关注不计入对方粉丝数)、警告、封禁
实现示例:
关注请求 → 风控检查(频率/新号/集中度)→ 放行 or 限流
批量取关 → 触发洗关注检测 → 计入风控分
工程要点:关注不是「无成本动作」,要按资产治理——关注频率、取关比例、关注集中度是核心风控信号。批量刷粉一旦坐实,直接伤害真实用户的社交信任,必须「频率限流 + 异步风控」双管齐下。
10. 速查表与一句话记忆
| 问题 | 一句话答案 |
|---|---|
| 关注关系是什么 | 有向稀疏图,幂律分布 |
| 怎么存 | 一张表 + 关注/粉丝两个索引视角 |
| 共同关注怎么查 | 两个邻接集合求交,大集合布隆过滤 |
| 二度怎么算 | 限量扩展(每节点 Top-K)防扇出爆炸 |
| 推荐关注怎么做 | 协同(共同关注)+ 相似 + 热门组合 |
| 传播怎么分析 | 转发树记录 + 关键传播者识别 |
| 要不要图数据库 | 1-2 跳关系表够;深度分析走离线批处理 |
| 怎么防刷 | 频率限流 + 异步风控 + 新号权重 |
一句话记忆:关注图谱 = 有向稀疏图(表 + 双索引视角)+ 交集查询(共同关注)+ 限量二度扩展(防爆炸)+ 协同/相似/热门推荐(增长)+ 转发树传播分析(影响力)+ 异步风控(防刷)——把「关注功能」升级为「社交网络分析」。
延伸阅读
- /miniblog-follow-timeline-push-pull/ — 关注关系与时间线 Fanout
- /miniblog-data-model-schema/ — 社交域表设计与索引
- /miniblog-personalized-feed/ — 兴趣画像与候选召回
- /miniblog-rate-limiting-abuse/ — 关注行为限流
- /miniblog-analytics-stats/ — 行为数据与传播分析
- 图数据库专题 — 图模型与图算法
- 分布式系统专题 — 关系服务的水平扩展
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。