绪论
Spanner与FaRM
Spanner的主要特点:
- 一个实际的系统部署方案
- 专注于全球范围内的容错部署
- 使用TrueTime来解决read-only transaction
- 性能:read-write transaction大致需要10-100ms
- 瓶颈:网络延迟
FaRM的主要特点:
- 探索性质的原型系统,挖掘了RDMA的潜能
- 所有replica部署在一个data center中
- RDMA的特性导致了只能使用Optimistic Concurrency Control
- 性能:read-write transaction 58微妙,百倍于Spanner!
- 瓶颈:CPU性能
FaRM取得高性能的因素:
- 大量的data sharding
- 数据存储在NVRAM中
- 单边RDMA操作
RDMA
Socket数据传输流程
一次典型的Socket通信过程的可以如下图所示:
一次客户端和服务器发送和接收过程的步骤如下:
- 客户端和服务器通过Socket库提供的接口建立链接,并分别在内存中申请好发送和接收Buffer。
- 客户端通过Socket接口陷入内核态,待发送数据经过TCP/IP协议栈的一层层封装,最后被CPU复制到Socket Buffer(WriteBuffer)中。
- 客户端通过网卡驱动,告知网卡可以发送数据了,网卡将通过DMA从WriteBuffer中复制封装好的数据包到内部缓存中,然后将其发送到物理链路。
- 服务器网卡收到数据包后,将数据包放到Socket Buffer(ReadBuffer)中,然后CPU将通过内核中的TCP/IP协议栈对报文进行层层解析,取出有效的数据。
- 服务器通过Socket接口陷入内核态,CPU将数据从内核空间复制到用户空间。
RDMA数据传输流程
一次客户端和服务器发送和接收过程的步骤如下:
- 服务器通知硬件准备接收数据,告诉硬件将接收到的数据放在哪片内存中。
- 客户端通知硬件发送数据,告诉硬件待发送数据位于哪片内存中。
- 客户端RDMA网卡从内存中搬移数据,组装报文发送给对端。
- 服务器收到报文,对其进行解析并通过DMA将有效载荷写入内存。然后以某种方式通知上层应用,告知其数据已接收并妥善存放到指定位置。
在RDMA中,数据收发绕过了内核并且数据交换过程并不需要CPU参与,报文的组装和解析是由硬件完成的。
Optimistic Concurrency Control
FaRM使用OCC的原因:FaRM使用单边RDMA操作,CPU不参与,无法进行加锁。
FaRM OCC的具体流程可以参考我的这篇博客。
FaRM OCC流程可以保证一致性的两个措施:
- version number验证检测了在事务提交前是否执行了其它事务
- lock phase保证了出现冲突时的隔离性
FaRM对only read操作的优化:
- 没有log record写入操作,无需上锁
- 需要额外的valid阶段验证其是否冲突
这里我们给出几个上课时使用的例子来加深对OOC流程的理解。
例子1:
假设事务T1和T2的执行内容如下,x初始值为0
T1:
x = x + 1
T2:
x = x + 1
第一种执行顺序
T1: Rx Lx Cx
T2: Rx Lx Cx
执行结果:T1和T2在Lx阶段发生冲突,只能有一个事务执行成功, x = 1
第二种执行顺序
T1: Rx0 Lx Cx
T2: Rx0 Lx Cx
执行结果:T1执行成功,T2在Lx阶段的版本号错误,x = 1
第三种执行顺序
T1: Rx0 Lx Cx
T2: Rx0 Lx Cx
执行结果:都执行成功,x = 2
例子2:
假设事务T1和T2的执行内容如下,x,y初始值为0
x为只读操作,y为写操作
T1:
if x == 0:
y = 1
T2:
if y == 0:
x = 1
第一种执行顺序
T1: Rx Ly Vx Cy
T2: Ry Lx Vy Cx
执行结果:T1和T2都会在valid阶段失败,x = 0, y = 0
第二种执行顺序
T1: Rx Ly Vx Cy
T2: Ry Lx Vy Cx
执行结果:T1执行成功,T2在valid阶段失败,x = 0, y = 1
FaRM中commit-backup的作用:
- 保证当出现primary crash时,log record不会丢失
- 出现priamry crash时,backup可以接任
- 所有backup返回ack后,才进行primary commit,保证了容错率