推送方案分两种模式拉模式(读扩散)和推模式(写扩散)。本章节主要对比拉模式和推模式,并介绍搭建推送系统的数据库选择。
设计思路
Feed流系统最大的特点是读写严重不平衡,一般读写比例都在10:1,甚至100:1之上。并且刷新Feed时的延时本质上由推送方案决定,其他的任何操作都只能是优化。设计推送系统具有以下关键点:
- 如何才能提供千万的TPS和QPS?
- 如何保证读写延迟在10ms,甚至2ms以下?
- 如何保证Feed的必达性?
推模式和拉模式对比
拉模式和推模式在很多方面完全相反,并且对Feed流产品的用户而言,刷新Feed流(读取)时的延迟敏感度要远远大于发布(写入)。推模式和拉模式的对比请参见下表。
对比项 | 拉模式(读扩散) | 推模式(写扩散) |
---|---|---|
发布 | 个人页Timeline(发件箱) | 粉丝的关注页面(收件箱) |
阅读 | 所有关注者的个人页Timeline | 自己的关注页Timeline |
网络最大开销 | 用户刷新时 | 发布Feed时 |
读写放大 | 放大读,读写比例到10000:1 | 放大写,减小读,读写比例到50:50 |
个性化 | 不支持 | 支持 |
定向广告 | 不支持 | 支持 |
以上对比可以看出,推模式要远优于拉模式,但是推模式也有一个缺点:数据会极大膨胀。针对这个缺点,可以从两个方面考虑:
- 以后存储成本会随着硬件技术升级、软件性能优化等继续降低。数据量越大价格越低。
- 如仍需减少成本,可以继续优化,可以对大V采用拉模式,普通用户使用推模式。对活跃粉丝采用推模式,非活跃粉丝采用拉模式(这种方式可以较好的避免大流量对平台的冲击)。
适用场景
以下是不同模式的适用场景。
模式 | 适用场景 |
---|---|
拉模式(读扩散) | 很多Feed流产品的第一版会采用这种方案,但很快就会抛弃。如采用拉模式+图计算,重心就会转换为图计算。 |
推模式(写扩散) |
|
推拉结合 | 大部分用户的账号关系都是几百个,但是有个别用户是1000万以上,例如微博。 |
数据库选择
如果要实现一个千万量级的Feed流产品,那么推送系统需要具备:
- 千万TPS/QPS的能力。
- 读写链路延迟敏感。读写直接会影响用户发布,刷新Feed流时的延迟,尤其是极其敏感的刷新时的延迟。
- Feed消息的必达性高。
- 主键自增功能,保证用户收件箱中的Feed ID是严格递增的,保证可以通过Scan(上次读取的最大ID --->MAX)读取到最新未读消息。
- 最好能为用户存储Timeline中所有的Feed。
从上述特点来看,搭建推送系统最优的选择是使用高性能、高可靠,且有自增功能的NoSQL系统:
- 开源Redis
如果选择开源系统,通常会在选择了关系型数据库作为存储系统的基础上,选择开源Redis,这样既能覆盖上述的几个特征,还能保证Feed流系统正常运行起来,但是也会带来一些其他问题:
- 纯内存系统,内存价格极高,导致整体成本高。
- 属于单机系统,为了支持千万TPS和保证消息必达性,需要使用cluster和replica模式,这样不仅带来了运维的复杂性,而且还需要增加机器,导致成本再次上升。
- 成本上升了以后,需要考虑如何降低成本。要节省成本只能是减少开源Redis里面存储的数据量,一般有两种做法:在开源Redis中存储Feed ID、不存储Feed内容。采用这两种方法,整体数据量会大量减少,但是在读取的时候需要先读Feed ID,然后在到存储系统里面去读取Feed内容,网络开销增长了一倍,而且是串行的,对用户的刷新延迟有较大影响。只对普通用户或者活跃用户使用推模式,对大V和非活跃用户直接使用拉模式。
- 上述两个方案虽然可以节省成本,但是是以牺牲用户体验为代价的,最终需要在成本和用户体验之间权衡。
-
表格存储
除了使用开源系统外,还可以使用阿里云的表格存储,有不少用户选择表格存储作为推送系统的原因无非下面几点:
- 天然分布式,单表可支持千万级TPS/QPS。
- LSM存储引擎极大优化写,高性能实例极大优化读。
- 写入成功即保证落盘成功,数据可靠性提供10个9的SLA保障。
- 磁盘性数据库,费用比内存性的要低几个量级。
- 单表可存储十万亿行以上的数据,价格又低,轻松保存用户Feed流中的所有Feed数据。
上面分析了使用开源Redis和阿里云表格存储的异同,如果使用开源数据库可以用Redis,如果选择阿里云NoSQL数据库,可以选择使用表格存储。
在文档使用中是否遇到以下问题
更多建议
匿名提交