存储是Feed流系统的核心之一。Feed流系统中需要存储的内容分为两部分:账号关系(例如关注列表)、Feed消息内容。
设计思路
Feed流存储系统有几个问题是设计的关键:
- 如何能支持100TB,甚至PB级数据量?
- 数据量与成本成正比,如何能降低成本?
- 如何保证账号关系和Feed不丢失?
账号关系
账号关系特点
- 变长链表,长度可达亿级别。
- 数据量大,但关系简单。
- 性能敏感。直接影响关注、取关的响应速度。
- 有序性。不要求具有排序功能,只需要能按照主键排序即可。只要能按照主键排序,那么关注列表和粉丝列表的顺序就固定、可预期。
存储方案
根据以上特点,最适合存账号关系(关注列表)的方案应该是分布式NoSQL数据库,其中包括:
- 开源HBase
很多企业选择开源HBase来存储账号关系。开源HBase在满足了上述四个特征的同时可以把系统搭建起来,但是仍会有一些问题:
- 需要自己运维、调查问题、修复问题,运维成本高。
- GC会导致比较大的毛刺,影响用户体验。
- 表格存储
阿里云的表格存储也属于有序性的分布式NoSQL数据库,很多知名的系统选择了使用表格存储。表格存储具有以下优势:
- 单表支持10万亿行+、10PB+的数据量,再快的数据增长速度都无需担心。
- 数据按主键列排序,可保证有序性和可预期性。
- 单key读写延迟在毫秒级别,可保证关注、取关的响应时间。
- 是全托管的分布式NoSQL数据库服务,无需任何运维。
- 全部采用C++ 实现,彻底无GC问题,不会由于GC而导致较大的毛刺。
以上可见,使用表格存储来存储账号关系是一个比较好的选择。
Feed消息
Feed消息特点
- 数据量大,而且在Feed流系统的写扩散(推模式)模式下数据量会再膨胀几个数量级,所以数据量很容易达到100TB,甚至PB级别。
- 数据格式简单。
- 数据可靠性要求高,不能丢失数据。
- 需保证个人发的Feed的消息ID在个人发件箱中都是严格递增的,这样读取时只需要一个范围读取即可。由于个人发布的Feed并发度很低,用时间戳也能满足基本需求,但是当应用层队列堵塞,网络延迟变大或时间回退时,用时间戳还是无法保证严格递增。最好的方法是适用主键自增功能。
存储方案
根据Feed消息特点,Feed消息的最佳的存储系统应该是具有主键自增功能的分布式NoSQL数据库,但是在开源系统里面没有完全符合特点的数据库,所以有两种存储方法:
- 关系型数据库 + 分库分表
目前有很多用户选择了关系系数据库+ 分库分表。虽然这个架构可以运行,但是存在一些问题:
- 分库分表带来了运维复杂性。
- 分库分表带来了逻辑层和数据层的极大耦合性。
- 关系型数据库的主键自增功能性能差,例如开源MySQL数据库。不管是用MyISAM还是InnoDB引擎,要保证自增ID严格递增,必须使用表锁。表锁粒度大,会严重限制并发度,影响性能。
- 关系型数据库的可靠性低于非关系型。关系型数据库的可靠性通常最多6个9,远低于分布式数据库,低4到5个级别。
- 表格存储
基于上述原因,一些技术公司开始考虑使用表格存储。表格存储是一个具有自增主键功能的分布式NoSQL数据库,这样就只需要使用一种系统,除此之外表格存储还有以下优势:
- 单表可达10PB、10万亿行。
- 10个9的SLA保障Feed内容不丢失。
- 天然分布式数据库,无需分库分表
- 两种实例类型:高性能实例可提供极佳的读写性能;容量型实例可提供低存储成本。
- 主键自增功能性能佳。其他系统的自增功能都需要加锁,但表格存储完全不需要加锁,包括表锁和行锁。
通过对比分析,表格存储在功能、性能、扩展性以及成本方面都要更加适合存储Feed消息。
在文档使用中是否遇到以下问题
更多建议
匿名提交