这一篇也算是Append only file system系列的论文了,一些东西和之前重复的比较多,这里就看一下diff了
Introduction/Facebook’s Previous Storage Infrastructure
早期FB的Blob存储构建在Haystack, f4上,数仓则是构建在HDFS上。
* Haystack专门用了存储新的blob,瓶颈在IOPS,而disk capacity比较多。以副本的方式存储数据
* f4用来存储老的blob,瓶颈在capacity,而IO capacity剩余比较多。以EC的方式存储数据
还有一个问题是HDFS的元数据在一台机器上,所以整个集群可存储的最大数据量是有限制的。而一个数仓经常超过HDFS的存储限制,导致数据需要在不同的HDFS集群之间存储,导致计算引擎的逻辑变得比较复杂
Architecture and Implementation
* 每个Tectonic Cluster都是在一个DC内的,tenant需要自己处理geo-replication
* Tectonic是支持多租户的,一般单个集群支持大约10个租户
* Tectonic支持任意数量,任意大小的namespace,以及文件系统的目录层级
* 文件是Append-only的
* Chunk store,负责存储chunk
* Metadata store,负责管理Namespace等相关元数据。由scalable kv store组成。这个感觉目前比较常见,比如字节内部的场景,FoundationDB
* 外侧是client library,也就是sdk
* 后台有一些无状态的服务
细节看一下每个模块需要关注的点:
* Chunk Store:
* 平面的,存储chunk的服务。chunk内部是由block组成的
* chunk通过XFS存储
* chunk store还有SSD cache,就是FB提出的cache lib
* Metadata Store:
*
* 上面说了是通过KV store组织,KV store的名字是ZippyDB。通过哈希做分片
* name layer用来维护每一个directory到内部文件列表的映射
* file layer用来维护file到block的映射
* block layer则用来维护block的位置。(这里应该都是chunk store的chunk)
* 哈希分配可以避免有热点directory的问题
* 允许client缓存seal的数据,tectonic允许directory/file/block的seal
* Client Library
* 只允许单写者。每次add block的时候,都需要去metadata store上校验token。新的写者可以通过创建新的token,并覆盖写之前文件的token,来保证单个文件的单写。新的写者会seal住之前写者的文件
* Background Services
* Garbage collector负责清理数据,以及处理元数据的不一致。因为ZippyDB没有分布式事务,所以Tectonic的一些元数据操作需要设计成特殊的多步操作,在这种多步操作失败后,就需要清理掉残留的状态
* rebalancer/repair server负责移动数据,以及修复数据。这里他们维护了disk->list of block的映射,用来确定一个disk挂掉后,哪些block需要被补齐。还根据block做了shard。(个人感觉必要性不大)
* copysets at scale,这里就是所有副本的数量,比如RS(10, 4)就是14个。如果比较多的话,会导致数据损坏的概率更大。比如极端情况下,每个盘都有一个条带,那么任意一个盘坏了都会影响数据。而如果copyset过小的话,会导致条带过大,load balance的能力差一些。
Multitenancy
tectonic花了比较多的功夫说这个多租户的做法
- Types of resources:Tectonic区分了两种类型的资源,non-ephemeral和ephemeral。storage capacity是non-ephemeral resource,不会涉及到多个租户的共享,没有弹性可言。Ephemeral的资源有Storage IOPS,metadata query capacity,会涉及共享
- Distributing ephemeral resource:
- 因为tectonic上的application过多,所以根据application来管理资源会比较复杂,并且开销比较大
- Ephemeral resource会根据application group被划分成若干个traffic group。一般一个集群有50个
- 每一个traffic group会被分到一个traffic class下,traffic class下代表了对延迟的需求程度。有Gold,Silver,Bronze,对应了对延迟敏感的业务,以及normal和background
- 分配quota的时候,每个tenant首先获得一批quota,然后在他的traffic group中划分。如果tenant有多余的资源,会先给同traffic group下的其他traffic class用,然后再给其他的traffic group/tenant
- Global resource sharing:这个是在client侧做的quota的限制,用了一个distributed counter
- Local resource sharing:
- 贪心优化:如果有请求可以在他后面的高优先级请求的结束后执行完,他就会让位给后面的请求
- 限制inflight non-Gold IO的数量,避免无法保证Gold IO的优先级
- 因为disk可能自己排序不同的IO,所以如果Gold IO等待时间过久,会避免调度新的non-gold IO
- 从这里可以看出来,一个集群的Gold IO的数量是有限制的,然后把Gold IO划分给不同的tenant以及内部的traffic group
Tenant-Specific Optimizations
这里主要是一些在client侧做的配置调整:
* 根据配置做一些前台EC
* Hedging,是预先预留资源,避免出现浪费。比如15副本写14成功,最后一个失败的话认为都失败就比较亏
* quorom写,即3写2成功就返回成功。这种就是要做一些校验,避免后续出现数据不一致。
剩下还有一些小点提一提:
* RS-encoded data可以用条带,或者做连续存储。对于条带来说,则要reconstruction-load的开销
* 一些系统迁移到tectonic后发现元数据的操作变慢了,应为HDFS上是内存操作,而tectonic则是一个分布式KVS
* Tectonic也提到了数据的校验,大规模系统上出现内存踩坏的现象比较多,所以Tectonic在每次处数据前后都加入了checksum。同样为了保证数据转化的正确性,也会加上校验。比如做EC的时候,会先执行EC,然后计算EC的checksum,再通过EC重构数据,保证checksum和之前相同。
* 做EC的时候,可以做条带的EC,也可以是大块的block写入(感觉主要区别是条带大小),如果条带小的话,并行读取的性能会高一些,但是会有Reconstruction的开销。而大block则可以直接读。
* Reconstruction的开销是哪里来的?比较奇怪
文章评论