bfs:支撑Bilibili的小文件存储系统

编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由毛剑在高可用架构群分享。转载请注明来自高可用架构公众号「 ArchNotes 」。


0?wx_fmt=png毛剑,就职于 Bilibili(B 站),成为了一名二次元同志(哔哩哔哩)。负责 UGC 平台,基础架构相关工作。Golang 践行者。bfs 是为了在 B 站遇到的一个急需解决的小问题开发的项目。

自主研发 bfs 的背景

0?wx_fmt=png

B 站从一个比较小众的社区,慢慢发展到今天,技术一开始的实现必然是求快为主,所以前不久发生过一次事故,自建的 CDN 因为一些故障导致图片、静态资源大量回源打到源站,源站 MongoDB 扛不住挂了。当时第一反应是:

MongoDB 不合适存储小文件图片?GridFS 场景更像是为大文件存储实现?

于是尝试了 FastDFS,搭建 TFS 等进行升级和替换。第一版用了 FastDFS,其线上的稳定性、故障情况以及扩展来说表现不佳;而 TFS 编译复杂,运维相对比较困难。后续有其他扩展需求还不知道是否好实现,因为行业特殊不太合适用公有云,所以选了一个最差解决方案:自己造轮子

当时想到了参看 Facebook 这种海量图片的公司是怎么实现小文件存储,于是找到了 Haystack 的论文一探究竟。


到底什么样存储系统适合 B 站呢?需求大概是:


  • 写非常多、读相对多(访问长尾效应)、从不修改、很少删除

  • 非常稳定、高可用、可扩容、可运维部署

  • 为图片定制优化的系统

整体架构

0?wx_fmt=png

图片静态资源外围必然会加上 CDN,让大部分 “热” 图片尽可能在 CDN 边缘节点命中,最快的返回给用户。源站核心要解决就是 CDN 穿透以后回源的压力,所以设想的架构是:

0?wx_fmt=jpeg

(点击图片全屏缩放)

把请求从上往下看


  • OSPF LVS:解决四层的负载均衡。

  • Tengine:7 层负载、作为 L1 cache proxy_cache,缓存热图。

  • Image Server:当 L1 cache miss 时,IS 进一步作为 L2 cache。因为上一层使用了 URI 一致性 hash,同一张图片一定会命中具体某一台 Server。如果运气再不好,请求就会打到请求真正的原图。考虑到移动端、PC 端各种尺寸要求的图片都有,因此使用实时缩略,进一步减少原图存储多版本浪费空间。我们用 Lua opencv C binding 的方式结合 nginx,实现了一整套 Image Server。

  • bfs 作为最终请求结束节点,也就是对象存储。


考虑到 CDN 可能的故障,最终还在 CDN 回源增加了一个二级缓存节点,一方面还避免暴露核心机房的 IP 给第三方 CDN,另外二级缓存节点可以大带宽,比核心机房便宜。


这样看来,整个请求的走向是 CDN -> L2 源站 -> L1 源站 -> 源站内部 L1、2 缓存。这样设计后,系统比以前的版本会更稳定。


bfs 模块

0?wx_fmt=png

bfs 架构包含四个模块,分别是 proxy、directory、store、pitchfork


bfs 依赖 ZooKeeper 存储 store 的元数据信息,依赖 HBase 存储用户自定义数据。

大体的数据请求走向都是从 proxy 开始,proxy 负责屏蔽内部协议的复杂性,后续也可以在 proxy 做一些异步任务。经过 proxy 后,请求会转发给各个模块。

总的设计目标来讲,希望 bfs 架构非常简单,这样在扩展、维护、bug 查找和编码都会有很多优势,为了这个目标也需要牺牲一些特性,后面会提到。

bfs 架构如下:

0?wx_fmt=jpeg(点击图片全屏缩放)

将请求从下往上看


Store:负责所有图片数据存储。


每个用户的图片可能会分布在任何一个 store 节点,store 是核心存储,代码和架构必须要非常谨慎。


和其他基于 Haystack 论文实现的开源存储不一样,bfs 的 store 模块只有简单的增、删、读操作,复制、健康检查、节点心跳一概没有,甚至可以只使用单个 store 直接提供服务,没有任何依赖。


为了能和集群通讯,唯一依赖一个外部设施就是 ZooKeeper,但是也非常简单,在初始化阶段本地的 volume(卷轴,后面会详细介绍这个术语,类似盘符)索引(volume 对应的文件路径)和 ZooKeeper 完成一次双向同步。


Pitchfork:心跳检测模块。


Pitchfork 会监控所有 store 节点,定期做 probe 探针检查。比如尝试读取一个文件,当出现异常就会去对应的 ZooKeeper 上 store 节点的路径更新状态。还会定时上报一些信息给 ZooKeeper ,方便其他依赖模块使用。监控还会从各个 store 模块内部收集平均延迟 delay、剩余空间、写入 IOPS 等。


因为需要监控的 store 节点可能非

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值