可以看到,不同的Replica之间key的数量有差别, 比如key2在Replica2上不存在,key3在Replica3上不存在。为了解决这些差别,我们引入修复模块(先不考虑Delete的情况),用来修复不同副本之间的差异。
修复工作流程:
- 修复模块定期的扫描集群中的所有的shard
- 对每个shard,获取shard的所有的replica的key列表
- 计算这些Replica间的diff,将缺失的key读取出来,并进行回填
新的架构
今天的架构演化到如下状态:
总结一下今天的工作:
- 对后端的存储节点重新进行了划分,引入资源池和可用区的概念
- 引入副本的概念, 一个shard由多个副本组成,这些副本分布在不同的可用区。
- 对一个shard的写入,实际上转化为对多个副本的写入,这些副本只需要写入到大多数成功即可。
- 加入离线修复模块,用于修复一个shard多个副本间的数据不一致问题。
BLOB(binary large object)存储,通常也被称为对象存储(OSS, object storage service)。一般用来存储文件,如视频文件、音频文件等。目前,各个云计算厂商都对外提供对象存储服务,其中以亚马逊的S3系统最著名,S3系统也成为行业的事实标准。各个云计算厂商推出的对象存储服务,也纷纷兼容S3标准。
B站由于其内容的独特性(视频网站),对象存储也有着非常多的需求。下面我们会介绍B站的对象存储的设计与实现。为了便于大家理解,会采用由简单到复杂的过程进行。我们称这个对象存储系统为BOSS(Bilibili Object Storage Service)。目标13天精通超大规模分布式对象存储系统的架构与设计。前6天的内容详见:十三天精通超大规模分布式存储系统架构设计——浅谈B站对象存储(BOSS)实现(上)。
Day7拓扑信息(路由信息)单点问题
经过前几天的努力,目前后端存储已经具有多副本,sharding的功能。观察我们的系统,路由数据存放于MySQL中,成为存储后端的单点。今天我们来解决这个单点问题。如下图所示,为了提升集群拓扑信息的安全和可用性,有两种方案:
方案1
- 将数据存储于etcd中,通过etcd的3副本来保证数据安全
- 在etcd之前,加入路由信息缓存层,将路由信息全部镜像到内存中
- 新加入管理节点,负责拓扑信息的变更操作
方案2
- 方案2实际上是方案1的简化版本
- 不再依赖于etcd,而是使用braft实现一个简单的KV结构。也拥有三副本,由braft完成3副本之间的数据复制。
- 在leader节点上集成集群管理逻辑,由这个管理逻辑对集群进行管理。(每个节点都有相同的逻辑,但只有处于leader状态时,才开始工作)
- 路由信息缓存层和方案一类似,区别在于:
- 使用round robin的方式从元数据服务节点(Metaserver)同步数据。
- 同步的时候,利用raft log index只增不减的特性,作为拓扑信息的版本,避免同步到旧的信息。
- 即使metaserver2个节点宕机,拓扑信息也能正常获取到。
元数据
集群中(metaserver中)需要存储的元数据主要包括:
- 表相关(shard, replica等)
- 存储节点相关(IP、磁盘、可用区、资源池等)
表相关元数据
表的元数据主要包括:
- 表的基本属性(创建时间,shard数量,每个shard的replica数量)。
- shard的属性:有哪些replica,该shard在这张表中属于第几个partition(即取mod后的下标)。
- replica的属性:需要描述其对应存储节点的信息,以及位于对应节点的具体哪块磁盘上
我们采用如下的proto文件进行描述,通过id和uuid可以建立起对应的关联信息
存储节点相关元数据
存储节点的元数据主要包括:
- resource pool的基础信息
- 每个resource pool有几个可用区
- 每个可用区由哪些节点组成
- 每个节点有几块磁盘构成
使用如下proto文件进行描述,构建后端集群的分布情况