百度云Atlas key-value系统设计

jopen 9年前
 

MSST 2015的论文( 论文在这里PPT在这里 )介绍百度云使用的key-value存储系统atlas的设计,思路相当赞。简单总结一下,建议想深入学习的同学直接阅读论文。

存储场景

  1. 百度云94%的文件在[128KB-256KB]之间,所以atlas主要针对小文件存储
  2. 百度云前面有CDN,到达atlas的请求基本都是随机访问,atlas是随机访问的存储引擎,不支持range操作

总体架构

百度云Atlas key-value系统设计

atlas主要由PIS和RBS两个部分组成,下面将分别介绍

PIS存储接口

百度云Atlas key-value系统设计

atlas的PIS模块(patch and index slice)直接面向用户,与其他KV存储引擎类似,暴露put/get/delete接口,不同的是atlas的key是规定长度128字节的GUID。

PIS以slot(slice)为单位进行数据管理,用户的key-value会分散存储到多个slot里,put时atlas的客户端会根据key计算hash,并对slot数量取模,将key路由至某个slot,每个slot单独进行数据管理。

百度云Atlas key-value系统设计

PIS的primary副本接收到用户的put请求,会将请求转发至多个secondary副本,每个副本都将value追加至本地 patch(类似于log文件),并记录key的value在patch里的位置信息(offset、length),当patch到达64MB 时,patch将不再写入数据,PIS会产生一个新的patch文件用于写,同时会将写满的patch以block的形式存储到RBS里,patch存储 至RBS时,RBS会分配一个唯一的blockid,此时PIS将key==>(blockid、length、offset)的映射关系写入 index模块(一个类似于google leveldb的系统)。

PIS接收到get请求时,首先在patch里查找key是否存储,如果存在则直接从patch读取value,返回给用户;如果key在 patch里不存在,则在index里查找,如果index里未找到,则说明atlas并没有存储这个key;如果在index里找到,则根据 (blockid、length、offset)从RBS里读取value,返回给用户。

PIS处理delete请求与leveldb类似,会新写入一条该key的记录,标示为key已删除。

RBS接口

百度云Atlas key-value系统设计

RBS(raid-like block storage)提供block的读写删接口,block长度固定为64MB,RBS里block只能整个写入和删除,但支持部分读取。

RBS包含一个中心管理节点(master-slave结构),以及一组存储节点(part-server),写入block时,RBS不再使用传统的多副本来保证数据可靠性,而是通过erasure-code来保证,极大的节省存储成本。

64MB的block会被RBS的客户端切分成8个8MB的part,通过8+4的erasure code计算出4个4MB的part,总共12个part;写入时,首先从中心节点请求分配一个唯一的blockid,同时分配12个 part-server用于写入12个part(实际上给了15个part-server信息,3个是备用的,如果存储12个part时,有某些part 存储失败,直接使用备用的part-server,而不用重新向中心节点发送新的请求,减少了与中心节点的交互次数);当12个part存储成功后,将 part与part-server的对应关系更新至中心节点。

当需要访问某个block时,RBS客户端向从中心管理节点查询block所在的part-server,然后从part-server读取数 据;如果读取的part-server当时处于故障状态,会读取block内其他至少8个part,来恢复该part-server里的数据。

删除空间回收

PIS里index里的key==>(block, length, offset)信息、RBS里的block==>create-time信息会被推送到离线的hadoop集群,每天计算哪些block是比较老的 (比如2周以前创建的),并且有效的使用空间低于某个阈值(比如80%),这批block被认为是需要回收的,atlas将block里有效的数据(没被 删除或覆盖)重新写入一份,即可将block删除掉。