事实上,关注列表、粉丝列表只是需求的一部分。抖音上人与人的关系是一种弱关系,可以单方向进行关注,这一点与微博、twitter类似。作为对比,微信上人与人的关系是强关系,必须是对等的。
如果打开抖音,我们可以看到三个标签:朋友、关注、粉丝。
这三个标签分别对应:
查询自己的朋友列表,并支持搜索(互相关注)查询自己的关注列表。并支持搜索(关注的用户)查询自己的粉丝列表,并支持搜索(关注你的用户)除了这三类读操作之外,还有一些写操作:
关注取消关注拉黑取消拉黑等等数据分布凭经验来看,每个用户关注的用户数是有限的,大概率不会超过5000; 一个普通用户的粉丝数也是有限的,能超过5000至少说明精心运营过。
但超级大v的粉丝数可以远远超出这个量级,比如在抖音上搜索“刘德华”、“邓紫棋”、“王一博“等,粉丝数都是千万级别的。精心运营过的刘德华粉丝数达到了惊人的7600w,这个量级可以给他定制化一张MySQL表了,表名就叫liudehua_followers
当然,定制化一张MySQL表只是一个玩笑。但一个事实是,刘德华的粉丝数是我的100w倍;我们没有渠道得知抖音用户的粉丝数分布,马太效应肯定是超级明显。
存储架构关注关系本质上是一种关系,但业务上体现为两种:粉丝列表和关注列表。朋友是粉丝列表和关注列表的交集。如果设计一种存储架构,需要满足一些条件:
持久化存储: 关注关系存起来以后,不能丢数据一致性: 粉丝列表和关注列表的数据必须一致高性能: 查询和更新都必须快,比如内网服务接口响应100ms以内架构简单、资源占用可接受先不考虑数据量,如果用一张MySQL表存储关注列表,那么结构大概是这样的:
按照功能拆表、对表进行分片,这两个操作完事以后,我们满足了持久化和高性能两个指标,但如何保证两张表数据的一致性呢?
我们简单聊一下CAP理论:
Consistency 一致性Availablity 可用性Partition Toloerance 分区容错性在一个大型分布式系统中,这三点不可能同时完成。我们看CAP理论如何应用到粉丝场景。
在粉丝场景中,我们需要纠结的是C和A选哪个。
如果选C,那么就需要依赖分布式锁,保证两张表都写入以后,才返回结果给客户端;这里的缺点很明显: 一是引入外部依赖(分布式锁),锁挂了怎么兜底;而且性能差;
如果选A,就是最终一致性方案。当关注行为被触发时,优先将数据写入“关注表”(没有马太效应、性能可控),通过消费Binlog更新数据到“粉丝表”;
权衡到业务场景的要求、技术实现的成本、服务的稳定性,选A更优。
业务支持场景1: 朋友列表
通过uid获取“关注列表”,list<following_uid>通过folloing_uid + uid,反查“粉丝列表”场景2: 通过名字搜索
先找到粉丝或关注的 uid list用 list + 名字搜索user表(或存放用户信息的ElasticSearch)这两个场景下,如果是普通用户,基本上没啥问题。
如果我是刘德华,场景1倒是没啥问题,场景2如果搜索的是粉丝,那么性能上也会有问题,怎么解决呢?解决办法就是不让大V搜索。
胖客户端的一点联想客户端和服务端的分界线从来都不是那么清晰,随着历史的演进,
大学那会儿,教科书上会说浏览器是瘦客户端,桌面应用是胖客户端。
上面提到的存储设计,或者上层的接口设计,都是服务端做的事情。抖音需要服务这么大的用户群体,本身已经需要很多机器。每个看起来微不足道的请求,QPS一旦上来,需要的机器数量都不会少。那么有没有一种方法,可以减少机器占用呢?
当然有,由于目前手机的配置普遍都比较高,很多原本在服务端的信息,都可以缓存到手机内置存储里。只需要一定的更新机制,保证服务端和客户端的数据一致即可。不然手机端的app怎么都这么大呢?
因此,粉丝列表、关注列表这类数据对都可以缓存到App端。粉丝列表的变更从服务端定期拉取更新;关注列表的变更由App端触发,只需要保证服务端接口调用成功后,更新本地缓存即可。
用本地缓存的数据支持复杂的查询,大大压缩了数据量,解决大表JOIN的问题,模糊搜索玩出花也可以!
以上就是抖音超过一万在哪里看粉丝量的全部内容,希望能够对大家有所帮助。