抖音的粉丝怎么显示不完整(高并发系统设计(1))

首页教程更新时间:2023-05-25 04:48:39

抖音作为国民短视频社交应用,有数据显示总用户数量已超过8亿,每日活跃用户达7亿,人均单日使用时长超过2小时。在这样庞大的用户基数下,一个小小的功能,背后可能需要复杂的设计。以用户服务为例,单单存储8亿用户,已经远远超出单库单表MySQL的极限。本文中我们的问题是如何在这样的用户基数上,实现关注列表、粉丝列表功能。

需求分析

事实上,关注列表、粉丝列表只是需求的一部分。抖音上人与人的关系是一种弱关系,可以单方向进行关注,这一点与微博、twitter类似。作为对比,微信上人与人的关系是强关系,必须是对等的。

如果打开抖音,我们可以看到三个标签:朋友、关注、粉丝。

抖音的粉丝怎么显示不完整,高并发系统设计(1)(1)

这三个标签分别对应:

  1. 查询自己的朋友列表,并支持搜索(互相关注)
  2. 查询自己的关注列表,并支持搜索(关注的用户)
  3. 查询自己的粉丝列表,并支持搜索(关注你的用户)

除了这三类读操作之外,还有一些写操作:

  1. 关注
  2. 取消关注
  3. 拉黑
  4. 取消拉黑等等
数据分布

凭经验来看,每个用户关注的用户数是有限的,大概率不会超过5000; 一个普通用户的粉丝数也是有限的,能超过5000至少说明精心运营过。

但超级大v的粉丝数可以远远超出这个量级,比如在抖音上搜索“刘德华”、“邓紫棋”、“王一博“等,粉丝数都是千万级别的。精心运营过的刘德华粉丝数达到了惊人的7600w,这个量级可以给他定制化一张MySQL表了,表名就叫liudehua_followers

抖音的粉丝怎么显示不完整,高并发系统设计(1)(2)

当然,定制化一张MySQL表只是一个玩笑。但一个事实是,刘德华的粉丝数是我的100w倍;我们没有渠道得知抖音用户的粉丝数分布,马太效应肯定是超级明显。

存储架构

关注关系本质上是一种关系,但业务上体现为两种:粉丝列表和关注列表。朋友是粉丝列表和关注列表的交集。如果设计一种存储架构,需要满足一些条件:

  1. 持久化存储: 关注关系存起来以后,不能丢
  2. 数据一致性: 粉丝列表和关注列表的数据必须一致
  3. 高性能: 查询和更新都必须快,比如内网服务接口响应100ms以内
  4. 架构简单、资源占用可接受

先不考虑数据量,如果用一张MySQL表存储关注列表,那么结构大概是这样的:

1. uid bigint 2. follower_uid bigint 3. status tinyint 4. create_time tiimestamp 5. modify_time tiimestamp

在 uid 和 follower_uid 都加上索引,用Go写个服务封装成接口,就可以用了。

但是,这是8亿用户,分库分表肯定是少不了的。一旦做了分库分表,关注列表和粉丝列表都必须分开存储了,因为:

  1. 如果用uid做分片,通过 follower_uid 取关注列表时,数据分散在不同的分片上,读写的效率都会很低,还不支持分页
  2. 如果用 follower_uid 做分片,通过 uid 读取粉丝列表时,会遇到同样的问题

所以,粉丝列表仍然使用上面的表结构,uid是用户ID,follower_uid是粉丝ID,对uid进行分片;

关注列表则采用稍微不同的表结构,uid是用户ID,following_uid是被关注用户的ID,对uid进行分片:

1. uid bigint 2. following_uid bigint 3. status tinyint 4. create_time tiimestamp 5. modify_time tiimestamp

按照功能拆表、对表进行分片,这两个操作完事以后,我们满足了持久化和高性能两个指标,但如何保证两张表数据的一致性呢?

我们简单聊一下CAP理论:

在一个大型分布式系统中,这三点不可能同时完成。我们看CAP理论如何应用到粉丝场景。

在粉丝场景中,我们需要纠结的是C和A选哪个。

如果选C,那么就需要依赖分布式锁,保证两张表都写入以后,才返回结果给客户端;这里的缺点很明显: 一是引入外部依赖(分布式锁),锁挂了怎么兜底;而且性能差;

如果选A,就是最终一致性方案。当关注行为被触发时,优先将数据写入“关注表”(没有马太效应、性能可控),通过消费Binlog更新数据到“粉丝表”;

权衡到业务场景的要求、技术实现的成本、服务的稳定性,选A更优。

业务支持

场景1: 朋友列表

  1. 通过uid获取“关注列表”,list<following_uid>
  2. 通过folloing_uid uid,反查“粉丝列表”

场景2: 通过名字搜索

  1. 先找到粉丝或关注的 uid list
  2. 用 list 名字搜索user表(或存放用户信息的ElasticSearch)

这两个场景下,如果是普通用户,基本上没啥问题。

如果我是刘德华,场景1倒是没啥问题,场景2如果搜索的是粉丝,那么性能上也会有问题,怎么解决呢?解决办法就是不让大V搜索。

胖客户端的一点联想

客户端和服务端的分界线从来都不是那么清晰,随着历史的演进,

大学那会儿,教科书上会说浏览器是瘦客户端,桌面应用是胖客户端。

上面提到的存储设计,或者上层的接口设计,都是服务端做的事情。抖音需要服务这么大的用户群体,本身已经需要很多机器。每个看起来微不足道的请求,QPS一旦上来,需要的机器数量都不会少。那么有没有一种方法,可以减少机器占用呢?

当然有,由于目前手机的配置普遍都比较高,很多原本在服务端的信息,都可以缓存到手机内置存储里。只需要一定的更新机制,保证服务端和客户端的数据一致即可。不然手机端的app怎么都这么大呢?

抖音的粉丝怎么显示不完整,高并发系统设计(1)(3)

因此,粉丝列表、关注列表这类数据对都可以缓存到App端。粉丝列表的变更从服务端定期拉取更新;关注列表的变更由App端触发,只需要保证服务端接口调用成功后,更新本地缓存即可。

用本地缓存的数据支持复杂的查询,大大压缩了数据量,解决大表JOIN的问题,模糊搜索玩出花也可以!

,
图文教程
相关文章
热门专题
推荐软件
奇热小说
奇热小说
下载
QQ2019手机版
QQ2019手机版
下载
王者荣耀
王者荣耀
下载
百度浏览器迷你版
百度浏览器迷你版
下载
2345浏览器手机版
2345浏览器手机版
下载
网易邮箱
网易邮箱
下载
爱奇艺
爱奇艺
下载
网易云音乐
网易云音乐
下载
WPSOffice
WPSOffice
下载
优酷
优酷
下载
谷歌浏览器(Chrome)
谷歌浏览器(Chrome)
下载
迅雷看看播放器
迅雷看看播放器
下载
UC浏览器
UC浏览器
下载
QQ音乐
QQ音乐
下载
阿里旺旺买家版v9.12.10C官方版
阿里旺旺买家版v9.12.10C官方版
下载
360安全卫士v12.1官方版
360安全卫士v12.1官方版
下载
猜你喜欢
淘惠优选app
淘惠优选app
下载
儿歌精灵电脑版
儿歌精灵电脑版
下载
录音机管家
录音机管家
下载
弹字视频神器
弹字视频神器
下载
工银现金快线
工银现金快线
下载
仨掌柜
仨掌柜
下载
QQ拼音输入法精简版V6.1.5306.400官方版
QQ拼音输入法精简版V6.1.5306.400官方版
下载
思迅天店v2.28.91基础版
思迅天店v2.28.91基础版
下载
像素滑板2欢迎来到奥莱坞游戏修正补丁
像素滑板2欢迎来到奥莱坞游戏修正补丁
下载
畅行福州
畅行福州
下载
一剑空城
一剑空城
下载
绳索块状英雄
绳索块状英雄
下载
传奇合成版
传奇合成版
下载
御灵手游ios版
御灵手游ios版
下载
SpringBootAdminv2.2.3官方版
SpringBootAdminv2.2.3官方版
下载
四川公务员
四川公务员
下载