微博的用户关系数据库应该如何设计? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内
puritania
V2EX    程序员

微博的用户关系数据库应该如何设计?

  •  
  • puritania 2018-01-18 15:58:11 +08:00 6038 次点击
    这是一个创建于 2899 天前的主题,其中的信息可能已经有所发展或是发生改变。

    疑问在于用什么维度做数据库、表拆分,这种数据极不平均,大 R 几千万粉丝,普通人几百粉丝,按传统 uid 这种做 hash 行不通,应该如何设计呢?

    第 1 条附言    2018-01-18 18:41:21 +08:00
    刚才看了一下 大 v 的粉丝列表只给看 5 页
    第 2 条附言    2018-01-18 19:22:15 +08:00
    http://www.infoq.com/cn/articles/weibo-relation-service-with-redis
    找到了一篇文章,具体解决方案没说
    33 条回复    2018-01-19 09:45:13 +08:00
    WeaPoon
        1
    WeaPoon  
       2018-01-18 16:19:07 +08:00
    等大佬回答,排队学习.
    xAx
        2
    xAx  
       2018-01-18 16:21:50 +08:00
    具体是怎么实现不清楚。
    但这类场景,如果是用关系型数据库,那么不管哪种解决方案,思路都差不多。
    用代理层对业务屏蔽数据库细节。
    数据库上可能把大 V 和普通用户分库或分表。这怎么分都是无所谓。
    分库分表不一定非 uid 什么的,随便哪个字段都行,是不是 vip,是不是政企,注册时间,活跃度...都可以用作分库分表的依据。
    甚至可以把不同用户的数据散布在不同的数据中心。

    业务含意的逻辑分完后,还可以进行数据库底层的物理分。

    其实重点是怎么做汇总查。
    很多项目都处理不好分表分库时的汇总查,所以喜欢搞微批系统,以批量出非实时统计结果
    puritania
        3
    puritania  
    OP
       2018-01-18 16:37:04 +08:00
    @xAx 数据库上可能把大 V 和普通用户分库或分表。这怎么分都是无所谓。
    你直接就把我的问题无所谓了。。
    puritania
        4
    puritania  
    OP
       2018-01-18 16:47:39 +08:00
    @xAx 然后为什么说要按 uid 分,就是为了降低查询的复杂度,按你说的随便哪个字段那代理层可能需要查无数个数据库、表才能获得我到我的粉丝列表。
    xwhxbg
        5
    xwhxbg  
       2018-01-18 16:53:19 +08:00
    如果把用户关系看做有向图,似乎可以通过图的疏密来分区,查找可能是两步,先从分区键查分区,再用 uid 查具体哪个用户
    以上全是 YY 的哈,没做过这个量级的
    kimchan
        6
    kimchan  
       2018-01-18 17:08:43 +08:00
    排队学习+1
    jzds001
        7
    jzds001  
       2018-01-18 17:28:59 +08:00
    排队学习+1
    grimpil
        8
    grimpil  
       2018-01-18 17:30:30 +08:00 via Android
    排队围观,暂时学不了这种高科技
    chenyj
        9
    chenyj  
       2018-01-18 17:32:15 +08:00
    好奇观摩
    jy02534655
        10
    jy02534655  
       2018-01-18 17:35:16 +08:00
    排队学习+1
    clino
        11
    clino  
       2018-01-18 17:43:19 +08:00
    "大 R 几千万粉丝,普通人几百粉丝"
    我现想的抛个砖,我想虽然这里面大 V 有好多粉丝,但是并没有需要有地方能把这些粉丝都显示出来,所以我只要保证前多少个粉丝(比如 500)能快速查询出来就可以了,多的另外的表来存放,这样是不是相当于把大 V 和普通人分开了.

    而一个用户 fo 的人一般不会太多,这部分也冗余地存放起来

    我觉得比较难的部分是快速过滤出某些用户的微博,比如我 fo 的所有用户的微博,各种 tag 的用户的列表,要能看这些列表的微博,这部分我觉得要做到高效挺难的...不知道怎么做的
    puritania
        12
    puritania  
    OP
       2018-01-18 17:49:01 +08:00
    @clino 你说的 feed 数据每个人都有自己的 feed 列表,一般都是推拉结合来做的。
    clino
        13
    clino  
       2018-01-18 17:55:26 +08:00
    @puritania #12 你是说每个人的 feed 都是自己一份? 那比如我有 20 个用户分组,那么每个组的 feed 是从前面这份全的 feed 和分组信息关联查询出来的?
    puritania
        14
    puritania  
    OP
       2018-01-18 18:00:49 +08:00
    @clino 那肯定,没有必要为了分组多冗余数据。
    clino
        15
    clino  
       2018-01-18 18:08:45 +08:00
    @puritania #14 如果每个人的 feed 都自己一份,那就是说比如说有 1 千万粉丝的大 V 发一条,就要给这些粉丝的 feed 增加一条记录,就要一下增加 1 千万条这样吗?
    fcten
        16
    fcten  
       2018-01-18 18:12:55 +08:00
    用户的关注关系是一个访问极端频繁的数据,是必然要缓存在内存里的。所以即使需要用关系型数据库做持久化,在设计上也不必太考虑性能的问题。
    估计会针对大 V 和非活跃用户做一些特殊处理。
    rogwan
        17
    rogwan  
       2018-01-18 18:22:05 +08:00 via Android   1
    以前微博的技术 yang 分享过,就是推拉结合。具体谁推谁拉算法肯定是一直在变的,根据用户的活跃情况调整。
    puritania
        18
    puritania  
    OP
       2018-01-18 18:34:01 +08:00 via iPhone
    @clino 所以说是推拉结合的 可以考虑只给再现用户推 部在线用户 上线时拉取
    puritania
        19
    puritania  
    OP
       2018-01-18 18:35:52 +08:00
    @fcten 问题就是特殊处理应该如何处理。。
    puritania
        20
    puritania  
    OP
       2018-01-18 18:38:35 +08:00
    @clino feed 也是很难的设计
    Universe
        21
    Universe  
       2018-01-18 18:47:15 +08:00 via Android
    不止一种数据库,关系型数据库和图数据库混用,这个是图数据库的经典例子了,相关的讨论非常多
    klxq15
        22
    klxq15  
       2018-01-18 18:49:54 +08:00 via Android
    我尝试用过 dgraph 图数据库,但是性能什么的没测试过
    fcten
        23
    fcten  
       2018-01-18 18:51:42 +08:00
    @puritania 我不是说数据库特殊处理,我是说缓存特殊处理。
    这种数据用 NoSQL 存储,根本没有分库分表的问题。用关系型数据库存储,必然达不到性能要求,必然要上缓存。数据库进行特殊处理,恐怕收益非常有限。
    puritania
        24
    puritania  
    OP
       2018-01-18 19:00:08 +08:00
    @fcten 数据库肯定是要有完整数据的,缓存的话每个大 v 几千万的粉丝都缓存感觉不太现实吧。
    1ku
        25
    1ku  
       2018-01-18 19:03:28 +08:00
    等会,我去泡好茶,搬好凳子...瓜子零食已到位,好了,开始吧!
    Kilerd
        26
    Kilerd  
       2018-01-18 19:09:19 +08:00
    排队学习
    Immortal
        27
    Immortal  
       2018-01-18 19:09:35 +08:00
    微博应该大量用了 redis 以前有技术分析的文章 找一下网上应该有不少 大 B 百万关注那种都是特殊处理了 单独使用一个实例 或者 啥的,和普通用户分开了 还有就是前面大佬说的推拉结合
    fcten
        28
    fcten  
       2018-01-18 19:15:56 +08:00
    @puritania 几千万粉丝其实数据量并不大。对于微博来说,上 TB 的内存集群都没啥问题吧。
    owenliang
        29
    owenliang  
       2018-01-18 19:33:33 +08:00 via Android
    不要用条数轮性能,知道 log based 存储吗 越大的批量写入收益越高。

    当你性能不行的时候,想想批量两个字。
    Zzde
        30
    Zzde  
       2018-01-18 20:08:37 +08:00
    排队学习
    puritania
        31
    puritania  
    OP
       2018-01-18 20:30:45 +08:00
    @owenliang 不明白你什么意思 数据库存储结构跟批量写入有什么关系
    owenliang
        32
    owenliang  
       2018-01-18 20:50:55 +08:00 via Android
    @puritania 大家一般认为 feed 流就是拷贝千万次,实际上对于 hbase 这种日志存储来说,批量提交 1m 的 batch 可能包含数万条 feed 关系,这是大家觉得不可思议最本质的一个问题。

    就像有人疑惑弹幕服务器如何承载百万人在线一样,认为 1 条弹幕要推送 100 万次,不可思议。其实大家没想过,完全可以攒几秒秒再批量推送下去,瓶颈转移到带宽而不是 cpu。

    只是告诉你两个字,批量。
    bsidb
        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 微博的时效性很强,能很好地进行热缓存。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     859 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 21:49 PVG 05:49 LAX 13:49 JFK 16:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86