无论是信息流、论坛、信箱,还是私聊、群聊、通知,推拉模型是内容型(包括:社交型)产品架构的核心。做出正确选择的关键在于对 产品形态 和系统组件 清晰的认识
模型
推模型(写扩散)
为每个内容消费者维护订阅列表,记录订阅的内容索引(一般为内容ID、类型、发表时间等索引数据)。每当内容生产者发布内容时,都会写入所有内容消费者的订阅列表。
- 优点:读很轻。仅需要读取订阅列表即可。
- 缺点:写很重。内容生产者每发布一条内容,会导致大量的写操作。
拉模型(读扩散)
为每个内容生产者维护一个内容列表,记录该用户所有生产的内容索引。
- 优点:写很轻,节省空间。内容生产者每发布一条内容,仅需写入自己的内容列表。
- 缺点:读很重,计算量大。假设内容消费者订阅了 1k 个生产者,则每次读取都需要从 1k 个生产者的内容列表拉取内容,以获得最新的 n 条内容。
产品形态
产品形态 | 粉丝数量上限 | 时间线 | 排序方式 |
---|---|---|---|
微博 | 无 | 秒~分 | 时间 |
短视频推荐,例如 TikTok | 无 | 秒~分 | 推荐 |
社交分享,例如 微信朋友圈 | 5000 | 秒级 | 时间 |
私信,例如 微信聊天 | 1 | 秒级 | 时间 |
所有该类型的产品,都有三个核心的角色:内容生产者、内容、内容消费者。后台系统要做的事情就是保障内容从内容生产者快速、可靠的分发给内容消费者。系统架构的难点在于:
- 将一条内容投递给一个消费者,还是投递给亿级的消费者(例如,微博、抖音)
- 投递数条内容,还是投递数亿条内容(例如,微信群聊)
产品形态不同,会放大一些技术方案的缺点,最终导致难以扩展或者成本难以接受。对于推模型
- 订阅上限过高,则会放大写扩散的问题
- 内容顺序不确定,写扩散同样毫无意义
存储系统
内容生成之后要首先通过写入落地到存储系统中,然后当内容消费者需要的时候再读取出来。不同的存储系统使用了不同的存储模型,首先看下常见的存储模型:
- B-tree:读取友好,数据有序。LIRS算法,将缓冲池分为两级,数据首先进入第一级,如果数据在较短的时间内被访问两次或者以上,则成为热点数据进入第二级,每一级内部还是采用LRU替换算法。例如:关系型数据库
- Bitcask:写入友好,数据无序。在内存中存储了主键和value的索引信息,磁盘文件中存储了主键和value的实际内容。需要定期执行合并(Compaction)操作以实现垃圾回收。Bitcask通过索引文件(hint file)来提高重建哈希表的速度。例如:Beandb
- LSM:写入友好,数据有序。将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操作批量写入磁盘,读取时需要合并磁盘中的历史数据和内存中最近的修改操作,需要定期执行合并(Compaction)操作以实现垃圾回收。例如:LevelDB、RocksDB、Bigtable
回过头再看推模型和拉模型,两者对读写性能的要求大不相同:
类型 | 推模型 | 拉模型 | 推-拉模型 |
---|---|---|---|
读延迟 | 毫秒 | 秒 | 秒 |
读写比 | 1:99 | 99:1 | 50:50 |
系统要求 | 健壮的写入能力 | 健壮的读取能力 | 平衡的读写能力 |
常见系统 | 采用 LSM 架构的分布式 NoSQL,如 Bigtable | 缓存系统如 Redis 和 Memcached 或 搜索系统(推荐场景) | 两者结合 |
架构复杂度 | 简单 | 复杂 | 更复杂 |
除此之外,由于数据量快速增涨,内容存储还需要方便进行快速的扩容,而不同的存储系统对扩展性的支持存在较大的差异:
特点 | 分布式 NoSQL | 关系数据库 (分库/分表) |
---|---|---|
扩展性 | 线性 | 需要重构 |
扩展速度 | 毫秒 | N/A |
常见系统 | Table Store、Bigtable | MySQL |
总结
选择推模型还是拉模型,需要考虑产品特征,以及存储系统。放眼业界
微信朋友圈使用写扩散:
- 产品层面:订阅者最多只有5000 (最多 5000 好友)
- 存储层面:分布式 NoSQL QuorumKV、PaxosStore
微博使用读扩散:
- 产品层面:订阅数没有上限
- 存储层面:Redis + MySQL
推特
- 产品层面:订阅数没有上限
- 存储层面:MySQL + Redis,中间一度迁移到 Cassandra,最后又回来。(《Cassandra at Twitter Today》)
最终,微信很多时间都花费到在了写扩散带来的成本问题;微博很多时间都在应对关系型数据库导致的扩展性问题,以及读扩散导致的”挂了又挂”。Twitter 很多时间都在“纠结”,前期使用写扩散,最后不得不结合读扩散,拥抱 Nosql 最终又回到 MySQL。
推拉模型对于互联网产品的影响至此,重要程度可见一斑
本文作者 : cyningsun
本文地址 : https://www.cyningsun.com/04-19-2021/content-products-push-or-pull.html
版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!