1. 背景
Facebook Messenger 用户超10亿,可以即时分享文字、图片、视频,产品自身不断的发展,背后的系统也在不断改变,开始是一个单体服务,后来变为有专门的缓存服务支持读、Iris 系统来队列化写、存储服务来保存历史消息。
为了更好的提升 Messenger 的用户体验,Facebook 对底层存储进行了本质性优化,主要包括:
- 重新设计并简化了数据 schema
- 从 HBase 改为 MyRocks(Facebook 开源的一个MySql存储引擎)
- 把存储介质从旋转式磁盘改为最新的闪存
结果带来了更好的用户体验,也提高了系统灵活性,减少了延迟,减少了存储的消耗,升级过程是无缝的,没有停机。
2. 大规模迁移的挑战
MyRocks 可以带来很多优势,例如:
- 可以应用 Facebook 的开放式计算项目
- 可以使用闪存
- 更好的使用 Facebook 成熟的 MySql 运维管理经验
- 可以减少物理数据节点的数量,并获得更好的可用性
存储系统的迁移是必要的,但 HBase 中数据量巨大,而且迁移过程中不能影响 Messenger 系统的运行。
迁移过程需要对 HBase 集群进行读取,这对产品来讲是个额外的负载,如果迁移动作过猛,会严重影响 HBase 的性能,甚至产生错误,影响用户体验。
迁移涉及的数据量非常大,是 PB 级别的,而且因为修改了数据 schema,必须仔细分析现有数据、处理大量的遗留数据、解决冲突,以保证用户看到和之前一致的数据。
所以,如何不影响10亿用户实现无缝迁移是个有趣的挑战。
3. 迁移方案
Facebook 设计了2个迁移流程,一个是正常流程,用于处理 99.9% 的账户,另一个流程用于处理剩下的特殊账户。
迁移过程会进行严格的数据验证,提前准备好回退方案,并做好检查工作,保证没有漏掉任何一个账户,当一切都没有问题后,老系统下线。
3.1 正常迁移流程
迁移前后的数据必须是强一致的,迁移一个账户时有一个前提假设:迁移过程中,此账户没有数据写入。
为了保证这点,定义了状态机制和监控工具,当迁移开始时,会记录下来此账户在旧系统中数据的最后位置,然后把数据迁移到新系统,完成后,检查旧系统中数据的最后位置是否变化,如果没变,此账户在新系统就可用了,开始新旧系统双写,否则,此账户迁移失败,清除新系统的数据,等待下一次的迁移工作。
在双写阶段,迁移器会执行双重验证:
(1)数据验证
确认 HBase 和 MyRocks 中的数据是匹配。
(2)API验证
在读取数据时同时从两个系统中一起读,然后比较结果数据是否一致。
如果数据验证发现了问题,就进行回退,继续从旧系统读数据,清除新系统中的数据。
3.2 使用缓存迁移流程
有些账户比较特殊,比正常的账户要大很多(例如企业的客服机器人账户),不能使用正常的迁移流程,所以设计了缓存机制。
在某个时间点对账户数据进行快照,保存快照到缓存中,然后把缓存中的数据迁移到 MyRocks。
迁移过程中有新的写操作怎么办?Iris 会对写操作入队(Iris 可以使数据在队列中保存数周,支持海量数据的写入),当缓存中的数据迁移完成后,新系统从 Iris 队列中消费积累下来的写操作,消费完成后,就追赶上了旧系统,两个系统就一样了,之后的流程与正常迁移流程相同。
4. 迁移后的好处
- 存储空间
简化后的数据 schema 使存储空间大大减少,而且因为 MyRocks 和 HBase 架构的不同,使得用于复制的资源减少了一半,所以,总体来看,存储上的消耗减少了90%。
- 延时
MyRocks 在读和写都进行了优化,并且使用了闪存,在数据延迟上比旧系统减少了50倍,用户可以感知到,例如回看旧消息时快了很多。
- 维护成本
相比于 HBase,MyRocks 在 Facebook 更加成熟,有更加智能的机制来处理灾难恢复,不需要人工的操作。
- 对产品的支持
新系统的架构和性能也使得产品更容易添加新特性,例如移动消息内容搜索,之前使用 HBase 时较难实现,在新系统中就比较容易。
以上内容翻译整理自Facebook官方文章
https://code.fb.com/data-infrastructure/migrating-Messenger-storage-to-optimize-performance