架构师-读写扩散

读扩散,指牺牲了读的性能,去提升写的性能。也叫拉取模型,描述对数据进行读取操作时,有更多的读取动作

而写扩散,一般指牺牲了写的性能,去提升读的性能。也叫推送模型,描述对数据进行写入操作时,有更多的写入动作。

当一个群成员的数量是 10 或 100 时,我们可以使用 “写扩散模型” 解决方案,当群成员数量是 1000 或 10000 时,写扩散模型会因为冗余写导致非常高的写延时,这肯定是不可取的,此时可以使用 “读扩散模型” 方案

比如群发消息的场景,就有两种方案:

  • 方案一:往每个群员的收件箱中发一个消息,这样虽然要写很多冗余的数据,但是当每个群员阅读消息时,性能会好很多(因为只需要查询自己的收件箱)。所谓 "写扩散";

    在写扩散模型中,每一个群成员都有自己独立的 “信箱”(即消息存储);当产生一条群消息时,需要分别投递(写入)到每个成员的信箱中;每个成员对群消息进行读取时,只需要从自己的信箱中拉取消息即可。

    写扩散模型最大的优点就是读取逻辑非常简单,尤其是在大规模用户高并发读取时,避免了锁操作,有较大的性能优势;同时,因为存储隔离,方便了消息的定制化处理。

    写扩散模型最大的缺点就是消息的存储成本很大,发送消息操作较为耗时,思考一下,为什么微信群成员数量的上限是 500? 同时,写扩散队列在落地实现时有非常高的技术复杂度。

    写扩散模型通常应用在群成员数量不高,读多写少的业务场景中。

    该方式为每个用户维护一个订阅列表,记录该用户订阅的消息索引(一般为消息ID、类型、发表时间等一些元数据)。每当用户发布消息时,都会去更新其follower的订阅列表。
    优点:读很轻。初始化时仅需要读取自己的inbox即可。
    缺点:写很重。每发布一个消息,会导致大量的写操作。
    注:一般来说,用户发布消息,并不会更新所有followers的订阅列表,仅更新在线followers即可。                     

  • 方案二: 只往群聊中写一条数据,每个群员都去群聊中拉取最新消息,此时没有数据冗余,写性能非常好,但是读却很容易产生热点. 所谓 "读扩散";该方式为每个用户维护一个发送列表,记录该用户所有发表过的消息索引。
    优点:写很轻,节省空间。用户每发布一条消息,仅需更新自己的outbox。
    缺点:读操作很重,计算量大。假设你收听了1k用户,则初始化时,需要从1k个用户的outbox拉取消息,然后计算获得最新的n条消息。


从目前现在网上的一些资料来看,Twitter是写扩散,腾讯微薄是读扩散,新浪微薄则是二者结合。

下面我们就结合群聊和朋友圈的场景来看一下读写扩散是怎么使用的。

这里要知道微信每个人的好友有上限,群聊的人数也有上限,所以这就限制了微信的设计复杂度没有新浪微博那样复杂,因为群聊是个耗时的操作,所以可以采用异步队列写扩散的方式来实现消息的发送。

当A用户在群里发送了一条消息(在outbox)以后,会在群中其他所有人的inbox中添加一条这条消息的索引,即使你并没有在线,当离线用户上线的时候,只需要检查自己的inbox列表就能收到“离线消息”。

换句话说就是:消息扩散写到每个人的消息存储(消息收件箱)后,接收者到后台同步数据时,只需要检查自己收件箱即可,同步逻辑跟单聊消息是一致的,这样可以统一数据同步流程,实现起来也会很轻量。

至于为什么不采用读扩散,一是因为一个群聊的人数相对较少,利用写扩散更加合适,二是如果采用读扩散,微信群聊每秒钟都可能有消息产生,那么用户会执行大量的读操作,这个过程并不是完全可靠的,很可能发生数据丢失。

朋友圈例子
下面再看一个微信朋友圈的例子

比如有两个用户小王和Mary。小王和Mary各自有各自的相册,可能在同一台服务器上,也可能在不同的服务器上。现在小王上传了一张图片到自己的朋友圈。上传图片不经过微信后台服务器,而是直接上传到最近的腾讯CDN节点,所以非常快。图片上传到该CDN后,小王的微信客户端会通知微信的朋友圈CDN:这里有一个新的发布(比如叫K2),这个发布的图片URL是什么,谁能看到这些图片,等等此类的元数据,来把这个发布写到发布的表里。

在发布的表写完之后,会把这个K2的发布索引到小王的相册表里。所以相册表其实是很小的,里面只有索引指针。相册表写好了之后,会触发一个批处理的动作。这个动作就是去跟小王的每个好友说,小王有一个新的发布,请把这个发布插入到每个好友的时间线里面去。

然后比如说现在Mary上朋友圈了,而Mary是小王的一个好友。Mary拉自己的时间线的时候,时间线会告诉到有一个新的发布K2,然后Mary的微信客户端就会去根据K2的元数据去获取图片在CDN上的URL,把图片拉到本地

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫1982

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值