论文阅读《No compromises: distributed transactions with consistency, availability, and performance》

分布式事务的一个研究型系统(不是已经落地的工程实现)

与spanner不同之处在与 spanner可以跨数据中心,论文中的FaRM系统只能在单数据中心,但是性能非常高。

高性能的硬件

首先高性能的原因来自于两个不同的硬件:

  • 非易失性的DRAM
  • RDMA(remote direct memory access)

非易失性内存的意思大概是普通的DRAM外挂了电源,在机器断电的情况下,外挂电源会生效(但是可能仅能支持很短一段时间,也许是几分钟),在外挂电源生效时,进程会停止工作,将DRAM中的数据全部落盘,然后关掉机器(等待电力恢复),所以仅能对断电进行容错(程序crash这种不太行)

RDMA要借助特殊的设备,具体原理不懂,可以按照DMA去理解,即读取远端数据可以不走复杂的网络协议,直接读取远端机器中内存数据(内核 by pass)

基于OCC的分布式事务

读数据直接走RDMA(读数据和版本号),写数据全部buffer在本地。本地commit了,才开启二阶段事务。流程如下:

  1. lock。客户端(协调者)发起请求给所有对应的region,给写数据加锁。(如果锁冲突了会失败,如果加锁数据的版本号和之前读的版本不一样,也会失败)
  2. validation。给只读事务的优化,通过RDMA来读数据,检测之前只读未写的数据版本号是否变化,是否有锁存在,如果有变化或者有锁,这一步会失败
  3. 开始commit,先commit到所有region的backup上,等待所有的backup返回成功
  4. 再commit到所有region的primary上,等待一个region返回成功即算事务提交成功
  5. truncate日志。事务成功提交后,客户端发起截断日志的请求,之前的事务日志就可以丢了。

脑补细节:每个object的存放方式,有个header,后面是数据,header里面最前面有个标记位表示是否加锁,后面是版本号。这样在lock或者validation阶段非常容易通过cas来判断。

事务的正确性分析。关于写事务都是加锁的,冲突的写事务之间肯定是串行化的。读事务不加锁,但是在开始提交的时候会validation,如果在此之前读取的数据变化了(加锁正在被写或者已经提交了新版本),那该事务会失败(读到旧数据了,lost update?)。如果成功validation了,那该事务就进入到提交阶段了,读取的数据之后要被修改或者加锁的话,肯定是后续事务进入到了lock阶段,那这个后续事务的commit肯定是晚于之前这个纯读事务的,看不到比自己更晚commit的事务的修改,是符合预期的。

先提交备份所有backup才能提交primary,这样可以达到论文中提到的故障容忍(任意region只剩1副本,系统也可以正常工作,不会丢数据)

任意primary返回后才能向application返回成功提交,这是为了防止所有副本宕机,协调者也宕机,这样事务状态就丢了,无法实现容忍region的任意f个副本宕机。

多副本备份

根据文中描述,每个region(数据集)都有f个backup,加上primary一共有f+1份数据。从上述的事务提交流程可以看到,每次提交时要求先在f个backup上提交了,才能在primary上面提交。

论文中描述使用f+1个副本就能实现容忍f个副本宕机,效果优于paxos和raft(2f+1才能容忍f宕机)。

论文中的这种主备也做不到自举,所以其实是靠中心节点借助lease来管理的,每个机器向CM(配置管理)节点申请lease,靠心跳连接进行续约,故障恢复逻辑如下:

  1. 某个节点lease超时后,CM节点会发起reconfiguration。如果是非CM机器怀疑是CM宕机了,那么会尝试和CM的backup进行连接,询问配置是否有变化,如果一段时间无变化,那么该机器也会发起reconfiguration。
  2. 发起reconfiguration的节点会向所有机器发起探测。收到过半机器回复后,进入下一步(保证了新CM节点一定位于majority内,新配置一定包含majority,也防止了脑裂)
  3. 发起reconfiguration的节点尝试修改zk中的集群配置,【c+1,s,f,id】,c是当前的配置版本号,s是新配置的机器,所有回复了阶段2探测的节点都在其中,f是故障隔离域,id是CM的编号,即本机id。借助zk的功能可以实现cas功能,即只有在当前配置为c版本号时才能修改成功,防止了并发问题,最终只能选出一个新的CM节点
  4. 新CM节点remap region分布,对于确实的region副本进行补充,让所有region都有f+1个副本(具体怎么补充没说,就是给副本数不足的region在存活的机器上补充副本,然后从幸存的副本上同步数据)
  5. 给所有节点发送新的配置。
  6. 收到新配置的节点比较配置版本号,采用更大版本号的配置,并给CM节点回复ok。并且阻塞客户端请求
  7. 收到所有节点的ok后,等待所有节点的旧lease到期,然后给所有节点发送commit。收到commit的节点可以开始接受新请求。

5,6,7的过程中CM会顺带和所有机器重建lease。文中的lease是双向lease,即CM持有每个机器的lease,每个机器也持有自己的lease,需要三次握手完成,5,6,7刚好完成三次握手。

事务恢复

暂时还看不明白,不太能理解

思考

问题1:为什么用了OCC不用2PL

回答:系统中使用OCC协议实现了分布式事务。先思考一个问题,为什么用OCC,为什么不用锁?因为系统中使用了RDMA,来读取数据,很难实现加锁这么复杂的逻辑(加锁是要一个rpc请求发给server,这就没法用RDMA了,也许会有更智能的RDMA能实现cas这样的操作,那样就能使用锁来实现了)

问题2:f+1个就能容错f个副本宕机,和raft、paxos相比,各有什么优劣势
回答:f+1其实就是普通的主备策略,和raft相比,好像更简单,也更省资源,但是相较于raft和paxos这类一致性协议来说,缺点是不能自举(没法自己选出主备份)。所以在备份恢复时需要靠CM节点来对region进行remap,而CM节点需要通过ZK来进行确定。ZK是用ZAB协议(类似raft)达到强一致的,可以自举。所以感觉raft paxos这类协议更复杂,是因为他们是能够自举的多副本。普通的主备复制,链式复制(CRAQ)等,实现更简单,但是不能自举,通常需要一个外部的组件来控制集群中的成员,比如redis的sentinel,本文中的ZK

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值