疑问在于用什么维度做数据库、表拆分,这种数据极不平均,大 R 几千万粉丝,普通人几百粉丝,按传统 uid 这种做 hash 行不通,应该如何设计呢?
1
WeaPoon 2018-01-18 16:19:07 +08:00
等大佬回答,排队学习.
|
2
xAx 2018-01-18 16:21:50 +08:00
具体是怎么实现不清楚。
但这类场景,如果是用关系型数据库,那么不管哪种解决方案,思路都差不多。 用代理层对业务屏蔽数据库细节。 数据库上可能把大 V 和普通用户分库或分表。这怎么分都是无所谓。 分库分表不一定非 uid 什么的,随便哪个字段都行,是不是 vip,是不是政企,注册时间,活跃度...都可以用作分库分表的依据。 甚至可以把不同用户的数据散布在不同的数据中心。 业务含意的逻辑分完后,还可以进行数据库底层的物理分。 其实重点是怎么做汇总查。 很多项目都处理不好分表分库时的汇总查,所以喜欢搞微批系统,以批量出非实时统计结果 |
4
puritania OP @xAx 然后为什么说要按 uid 分,就是为了降低查询的复杂度,按你说的随便哪个字段那代理层可能需要查无数个数据库、表才能获得我到我的粉丝列表。
|
5
xwhxbg 2018-01-18 16:53:19 +08:00
如果把用户关系看做有向图,似乎可以通过图的疏密来分区,查找可能是两步,先从分区键查分区,再用 uid 查具体哪个用户
以上全是 YY 的哈,没做过这个量级的 |
6
kimchan 2018-01-18 17:08:43 +08:00
排队学习+1
|
7
jzds001 2018-01-18 17:28:59 +08:00
排队学习+1
|
8
grimpil 2018-01-18 17:30:30 +08:00 via Android
排队围观,暂时学不了这种高科技
|
9
chenyj 2018-01-18 17:32:15 +08:00
好奇观摩
|
10
jy02534655 2018-01-18 17:35:16 +08:00
排队学习+1
|
11
clino 2018-01-18 17:43:19 +08:00
"大 R 几千万粉丝,普通人几百粉丝"
我现想的抛个砖,我想虽然这里面大 V 有好多粉丝,但是并没有需要有地方能把这些粉丝都显示出来,所以我只要保证前多少个粉丝(比如 500)能快速查询出来就可以了,多的另外的表来存放,这样是不是相当于把大 V 和普通人分开了. 而一个用户 fo 的人一般不会太多,这部分也冗余地存放起来 我觉得比较难的部分是快速过滤出某些用户的微博,比如我 fo 的所有用户的微博,各种 tag 的用户的列表,要能看这些列表的微博,这部分我觉得要做到高效挺难的...不知道怎么做的 |
13
clino 2018-01-18 17:55:26 +08:00
@puritania #12 你是说每个人的 feed 都是自己一份? 那比如我有 20 个用户分组,那么每个组的 feed 是从前面这份全的 feed 和分组信息关联查询出来的?
|
15
clino 2018-01-18 18:08:45 +08:00
@puritania #14 如果每个人的 feed 都自己一份,那就是说比如说有 1 千万粉丝的大 V 发一条,就要给这些粉丝的 feed 增加一条记录,就要一下增加 1 千万条这样吗?
|
16
fcten 2018-01-18 18:12:55 +08:00
用户的关注关系是一个访问极端频繁的数据,是必然要缓存在内存里的。所以即使需要用关系型数据库做持久化,在设计上也不必太考虑性能的问题。
估计会针对大 V 和非活跃用户做一些特殊处理。 |
17
rogwan 2018-01-18 18:22:05 +08:00 via Android 1
以前微博的技术 yang 分享过,就是推拉结合。具体谁推谁拉算法肯定是一直在变的,根据用户的活跃情况调整。
|
21
Universe 2018-01-18 18:47:15 +08:00 via Android
不止一种数据库,关系型数据库和图数据库混用,这个是图数据库的经典例子了,相关的讨论非常多
|
22
klxq15 2018-01-18 18:49:54 +08:00 via Android
我尝试用过 dgraph 图数据库,但是性能什么的没测试过
|
23
fcten 2018-01-18 18:51:42 +08:00
@puritania 我不是说数据库特殊处理,我是说缓存特殊处理。
这种数据用 NoSQL 存储,根本没有分库分表的问题。用关系型数据库存储,必然达不到性能要求,必然要上缓存。数据库进行特殊处理,恐怕收益非常有限。 |
25
1ku 2018-01-18 19:03:28 +08:00
等会,我去泡好茶,搬好凳子...瓜子零食已到位,好了,开始吧!
|
26
Kilerd 2018-01-18 19:09:19 +08:00
排队学习
|
27
Immortal 2018-01-18 19:09:35 +08:00
微博应该大量用了 redis 以前有技术分析的文章 找一下网上应该有不少 大 B 百万关注那种都是特殊处理了 单独使用一个实例 或者 啥的,和普通用户分开了 还有就是前面大佬说的推拉结合
|
29
owenliang 2018-01-18 19:33:33 +08:00 via Android
不要用条数轮性能,知道 log based 存储吗 越大的批量写入收益越高。
当你性能不行的时候,想想批量两个字。 |
30
Zzde 2018-01-18 20:08:37 +08:00
排队学习
|
32
owenliang 2018-01-18 20:50:55 +08:00 via Android
@puritania 大家一般认为 feed 流就是拷贝千万次,实际上对于 hbase 这种日志存储来说,批量提交 1m 的 batch 可能包含数万条 feed 关系,这是大家觉得不可思议最本质的一个问题。
就像有人疑惑弹幕服务器如何承载百万人在线一样,认为 1 条弹幕要推送 100 万次,不可思议。其实大家没想过,完全可以攒几秒秒再批量推送下去,瓶颈转移到带宽而不是 cpu。 只是告诉你两个字,批量。 |
33
bsidb 2018-01-19 09:45:13 +08:00 2
微博的技术大拿在网上有技术分享 PPT,应该还能搜到。
我印象中,当时的 PPT 是这样说的(约至少 2 年前),如果说的有问题,还请拍砖: 1. 微博信息数据(即微博的具体内容等)是存储在关系型数据库中的。使用标准的分库分表技术就能水平扩展。 2. 微博的关系数据(即 Follow 关系)和 Feed 流数据,我记得没有细说。但是每个用户是会维护自己的 Feed 流,这个 Feed 流应该只保存了微博 ID 编号,不保存具体微博内容。等用户浏览自己的 Feed 流的时候,再从关系数据库中取出微博内容,并将网页返回给用户。 3. 微博的通知数据(你有 XX 新粉丝,有 XX 新回复,有 XX 新点赞等信息),因为体积不大而且经常变动,是保存在 Redis 中。 当一个用户发了一条新微博之后,后续的更新动作一般是推拉结合: 1. 对于普通用户(粉丝数小于某个值)的微博更新,用“推”的方式比较划算。当一个用户更新微博后,把新微博的 ID 信息写入他的粉丝的 Feed 流存储之中。 2. 对于大 V 用户(粉丝数大于某个值)的微博更新,用“拉”的方式比较划算。当大 V 更新微博后,并不会将新微博 ID 推送到粉丝的 Feed 流。而是在粉丝查看自己的 Feed 流的时候,现场去查询其关注的大 V 的最新动态,并加入 Feed 流。这种“拉”的好处是减少了大 V 更新微博时的一系列数据库操作代价,而且大 V 微博的时效性很强,能很好地进行热缓存。 |