论文-spinnaker

Spinnaker是IBM & Linkedin Team在2011年VLDB发布的一个k/v存储服务,其设计实现基本上就是典型的paxos/raft的rsm(replicated-state-machine)的典型应用,系统实现思路很清晰,比较值得一读。

Spinnaker主要针对一个datacenter内的数据同步,考虑到datacenter内的网络分区概率极低,Spinnaker严格上说是一个CA系统。它采用3-way replica,跟传统的最终一致性的存储系统做对比,Spinnaker在读操作上甚至要更快,而在写操作上,它也只是有5-10%的性能损失。

数据模型

Spinnaker的数据模型及API跟Bigtable及Yahoo PNUTS非常类似,数据基于row及table组织,基本是如下的pattern:

row key -> { col name : col val, ……}

Data Model

作为k/v存储,其数据格式显然也没有做预设的schema,基于col name & col val来进行schema的变更;由于其数据模型里没有column family,其查询便利性上较之Bigtable还是有些差别。

基本APIs

  • insert
  • delete
  • get
  • test_and_set

前三个api自不必说,基本就是常规的kv操作;对于test_and_set, 由于数据存在版本,client端可以基于version做conditionalPut、conditionalDel等操作,从而实现test_and_set语义;

比如conditionalDelete(key, colname, v),只有当前数据版本为v时,才进行delete操作。

架构

数据分布层面,Spinnaker基于key-range进行分布;一个range内的数据集的多个replica集合叫cohort,cohort基于chained-declustering方式进行replica逻辑关联。

上图就是一个典型的数据分布架构,为了系统简化直接基于Zookeeper来做meta-data管理;

Cluster

对于单个节点,节点通过模块话组织进行数据commit, membership管理, election等动作,具体如下图:

Node

Replication Protocol

Spinnaker协议跟Raft, Zab比较类似,采用基于选举的paxos-like方案,其协议分为两个阶段:

  • p1: leader election
  • p2: quorum (using multi-paxos)

简单来说就是,首先选出cohort leader(leader crash会重新选举), 然后log发送给cohort leader,leader基于multi-paxos协议进行quorum的log一致性同步(注意此时节点未做commit,也就是未commit到RSM中)。 多数派节点ack后,leader commit然后返回client,之后发出async commit操作通知节点进行commit操作。

Protocal

显然在这个时序里,leader返回之后时间点,client->get(),到follower节点是可能拿到过期数据的,而leader节点是可以拿到最新数据。这就是Spinnnaker里的timeline consistency。

恢复

每个节点为所有的partition数据维护一个共享log(规避随机写问题),类似write-ahead-log,确保数据的可恢复性。

如果follower挂掉后又重新加入

  • leader传输log给follower,follower会追进度
  • 直到追上后,follower投入运行

如果leader挂掉

  • 触发p1的election
  • leader会重新propose所有的uncommited消息
  • 如果是quorum,开始update

需要指出的是,重新选举后leader会将所有的uncommit log进行重新的分发,这一块跟Raft协议有了比较大的简化,不确定正确性是否理论严格。