Facebook最近公布了Apollo,它是Facebook的一种类似于Paxos的NoSQL数据库。Apollo构建于Apache Thrift 2 RPC框架,采用C++11开发,是一种分层存储系统,所有数据被划分到Shard,非常类似于HBase中的区域服务器。它最大的好处是在线低延迟存储,特别是在Flash和内存中。

区别于面向文档和键值的存储,Apollo是一种修改的数据结构,允许你存储Map、队列、树以及键值等等。系统中每个单独的数据块都非常小,从1字节到1MB,而所有的总大小则从1MB到10+PB。它支持的服务器从最少三台到数千台之多。

每个Shard有四个组件。

第一个是Quorum一致性协议

第二个组件是存储。目前主存储基于RocksDB,是一种构建于Google LevelDB的Key/Value存储结构。虽然它是Key/Value存储,Facebook使用它来模拟其它数据结构。Apollo被设计为可以存储未知的结构,开发团队也正在增加对MySQL的支持以作为一种替代存储引擎。

第三个组件是客户端API,它拥有read()和write()方法。Apollo在Shard层执行的所有操作都是原子操作,因此你可以描述前置条件,如果满足,它返回reads或writes。代码示例如下:

read(conditions : {map(m1).contains(x)}, 

     reads : {deque(d2).back()})

上面的代码表示“如果Map m1包含x,就返回双端队列(Deque)d2的back上的值。”

你能将任意多个条件和任意数量的Read结合在一起。

Write也非常类似,同样允许你描述条件:

write(conditions : {ver(k1) == v}, reads : {}, 

      writes : {val(k1) := x})

最后一个组件是容错状态机(Fault Tolerant State Machine,FTSM)。它们主要由系统代码使用,但也可以被用户代码使用。每个FTSM都属于Shard,例如,在一个有三台机器的Shard中,它们全部同时执行相同的代码。它们能存取每台机器的持久化存储。最重要的是,如果一个节点故障,代码将按所有节点都同意的正确顺序继续执行。

状态机还被用于负载均衡、数据迁移、Shard创建和销毁,以及协调跨Shard事务。状态机也存在外部副作用,例如它们能发送RPC请求到远程机器,但不论何时它们要变更持久化状态,都必须提交给Raft以取得所有服务器的同意。

Facebook目前将Apollo用于替换Memcached的一些应用场景,Facebook目前大规模地使用了Memcached。该公司同时正在尝试使用它作为一种可靠的队列系统,用于发送Facebook消息到iOS、Android和运营商SMS。它也可能用于更快速的分析。

Apollo仍处于开发阶段,还没有开源,不过在不就之后将发布给所有人,拭目以待咯!

本博客相关参考资料请查看:http://mingkr.com/facebook-nosql-apollo