6.824-lecture11

6.824 讲座10:FaRM

我们为什么要阅读这篇论文?
很多人想要分布式交易
但他们被认为是缓慢的
本文提出的建议不一定非要如此-非常令人惊讶的表现!

大业绩图
每秒9000万个复制 持久 事务(图7)
每台机器每秒100万笔交易
每个都有一些消息,用于复制和提交
非常令人印象深刻
其他一些系统则每台机器每秒获得100万次操作,例如memcached
但不是事务+复制+持久性(通常这些都不是!)
9000万的观点:
每秒10,000条推文
每秒2,000,000封电子邮件

他们如何获得高性能?
数据必须适合总RAM(因此无法读取磁盘)
非易失性RAM(因此不写磁盘)
单面RDMA(快速跨网络访问RAM)
快速访问NIC的用户级别
利用单侧RDMA的事务+复制协议

NVRAM
FaRM写入RAM而不是磁盘-消除了巨大的瓶颈
可以在200 ns内写入RAM,但是写入硬盘需要10毫秒,SSD需要100 us
ns =纳秒,ms =毫秒,us =微秒
但是RAM会在电源故障时丢失内容!本身并不持久。
为什么不只写f + 1机器的RAM来容忍f故障?
如果失败总是独立的,可能就足够了
但是电源故障不是独立的-可能会损坏100%的机器!
所以:
每个机架中的电池可以使机器运行几分钟
主电源发生故障时,电源硬件通知软件
软件停止所有事务处理
s / w将FaRM的RAM写入SSD。可能要花几分钟
然后机器关闭
重新启动后,FaRM从SSD读取已保存的内存映像
“非易失性RAM”
如果崩溃使软件无法写SSD怎么办?
例如FaRM或内核中的错误,或CPU /内存/硬件错误
FaRM通过复制数据来应对单机崩溃
从机器副本的RAM到其他机器
确保总是f + 1份
崩溃(电源故障除外)必须是独立的!

为什么网络经常成为性能瓶颈?
通常的设置:

应用程序
--

​ 套接字缓冲区
​ TCP TCP
​ NIC驱动程序驱动程序
​ 网卡--------------------网卡
许多昂贵的CPU操作:
​ 系统调用
​ 复制邮件
​ 打断
​ 如果RPC,则全部两次
慢:
​ 难以构建RPC,无法提供超过100,000 /秒的传输速度
​ 黑白线(例如10吉比特/秒)很少是短RPC的限制
​ 这些每数据包的CPU成本是小消息的限制因素

内核旁路
简化了对NIC硬件的应用程序访问
应用程序直接与NIC交互-无需系统调用,无需内核
应用程序和NIC之间的共享内存映射
发送方向NIC发送RDMA命令
对于RPC,接收器软件轮询RDMA写入的内存

FaRM的网络设置
[主机,56 Gb NIC,昂贵的交换机]
NIC执行“单面RDMA”:内存读/写,而不是数据包传递
发件人说“在此地址写入此数据”,或“读取此地址”
NIC 硬件在远端执行
返回“硬件确认”
远端无中断,内核,复制,read()和&c
一台服务器的吞吐量:10+百万/秒(图2)
延迟:5微秒(摘自其NSDI 2014论文)
FaRM通过三种方式使用RDMA:
在事务执行期间单面读取对象(也有效)
RPC由对主日志或消息队列的单面写入组成
单面写入备份日志

重大挑战:
如何使用单面读/写进行事务和复制?
我们已经看到的协议要求接收器CPU主动处理消息
例如筏和两相提交

让我们回顾一下分布式交易

记住这个例子:
x和y是银行余额,可能在不同的服务器上
T1:T2:
add(x,1)tmp1 = get(x)
add(y,-1)tmp2 = get(y)
打印tmp1,tmp2
x和y开始于$ 10
我们想要可序列化性:
结果应该好像交易以某种顺序一次运行一次
只能下两个订单
T1然后T2产生11,9
T2然后T1产生10,10
可序列化性没有其他结果

如果T1完全在T2的两个get()之间运行怎么办?
如果交易协议允许,它将打印10,9
但这是不允许的!
如果T2完全在T1的两个add()之间运行怎么办?
如果交易协议允许,它将打印11,10
但这是不允许的!

事务的两类并发控制:
悲观:
等待锁定对象的首次使用;保持直到提交/中止
称为两相锁定
冲突导致延误
乐观的:
访问对象而不锁定;提交“验证”以查看是否正常
有效:写
无效:中止
称为乐观并发控制(OCC)

FaRM使用OCC
原因:OCC允许FaRM使用单面RDMA读取
由于OCC,存储对象的服务器不需要设置锁
FaRM如何验证?我们将在一分钟内查看图4。

每个FaRM服务器都运行应用程序事务并存储对象
应用程序事务是其自己的事务协调器(TC)

FaRM交易API(简体):
txCreate()
o = txRead(oid)-RDMA
的+ = 1
txWrite(oid,o)-纯粹是本地的
ok = txCommit()-图4

txRead
一侧的RDMA可以直接从主数据库的内存中获取对象-快了!
还获取对象的版本号,以检测并发写入

txWrite
必须在txRead之前
只是写本地副本;没有沟通

什么是oid?
<地区编号,地址>
region#将映射索引到[primary,backup1,…]
目标NIC可以直接使用地址来读取或写入RAM
因此目标CPU不必参与

服务器内存布局
区域,每个区域都是对象数组
对象布局
具有版本号和锁的标头
对于彼此的服务器
(由RDMA编写,通过轮询读取)
传入日志
传入消息队列
所有这些都在非易失性RAM中(即在断电时写入SSD)

每个区域在一个主要的f个备份上复制-f + 1个副本
[一些地区的图表,主要/备用]
仅主要服务读取;所有f + 1见commits + writes
如果<= f个失败,复制将产生可用性
即,只要一个副本保持活动状态就可用;比筏更好

没有失败的事务执行/提交协议-图4
让我们一一考虑一下图4中的步骤
现在就考虑并发控制(不是复制)

LOCK(提交协议中的第一条消息)
TC发送到每个书面对象的主体
TC使用RDMA在每个主数据库处附加其日志
LOCK记录包含oid,版本号xaction读取,新值
主软件轮询日志,查看LOCK,验证,发送“是”或“否”回复消息
注意LOCK都记录在主数据库的NVRAM和RPC交换中

主CPU在收到LOCK后会做什么?
(对于每个对象)
如果对象已锁定,或者版本!= xaction读取了什么,则回答“否”
用原子比较和交换实现
“锁定”标志是版本号中的高位
否则设置锁定标志并返回“是”
注意:如果对象已经被锁定,不会阻塞

TC等待所有LOCK回复消息
如果有“否”,则中止
将ABORT发送给主要对象,以便他们可以释放锁
从txCommit()返回“否”

让我们暂时忽略VALIDATE和COMMIT BACKUP

TC将COMMIT-PRIMARY发送到每个写入对象的主对象
使用RDMA附加到主要日志
TC仅等待硬件确认-不等待主要对象处理日志输入
TC从txCommit()返回“是”

primary在处理其日志中的COMMIT-PRIMARY时会做什么?
将新值复制到对象的内存中
增加对象的版本号
清除对象的锁定标志

例:
T1和T2都想递增x
都说
tmp = txRead(x)
tmp + = 1
txWrite(x)
好的= txCommit()
x应该以0、1或2结尾,与成功提交的数量一致

如果T1和T2完全吻合怎么办?
T1:Rx0 Lx Cx
T2:Rx0 Lx Cx
会发生什么?

要么
T1:Rx0 Lx Cx
T2:Rx0 Lx Cx

要么
T1:Rx0 Lx Cx
T2:Rx0 Lx Cx

验证为什么检查可序列化性的直觉:
即检查“一次执行一次吗?”
如果没有冲突,版本不会更改,并且允许提交
如果发生冲突,将看到锁定或更改版本

图4中的VALIDATE呢?
它是对事务刚刚读取的对象的优化
VALIDATE =读取一侧RDMA以获取对象的版本号和锁定标志
如果自读取以来更改了锁集或版本号,TC将中止
未设置锁定,因此比LOCK + COMMIT更快

VALIDATE示例:
x和y最初为零
T1:
如果x == 0:
y = 1
T2:
如果y == 0:
x = 1
(这是一个经典的一致性测试示例)
T1,T2产生y = 1,x = 0
T2,T1产生x = 1,y = 0
中止可能会留下x = 0,y = 0
但是可序列化性禁止x = 1,y = 1

假设同时:
T1:Rx Ly Vx Cy
T2:Ry Lx Vy Cx
锁都会成功
VALIDATE都将失败,因为锁定位都已设置
所以两者都会中止-可以

怎么样:
T1:Rx Ly Vx Cy
T2:Ry Lx Vy Cx
然后T1提交,T2仍然中止,因为T2的Vy看到T1的锁或更高版本
但是我们不能在所有L之前都先有* V
因此在此示例中,VALIDATE似乎是正确的
速度快:比LOCK快,无需提交

容错呢?
防御丢失数据?
耐用?有空吗
发生崩溃时正在进行的交易是否完整?
分区?

高级复制图
oo地区1
oo区域2
厘米
哦ZK

每个区域有f + 1个副本以容忍每个区域中的<= f个故障
TC将所有写操作发送到所有副本(TC的COMMIT-BACKUP)
如果服务器崩溃,则无法立即使用
事务读取和提交将等待
但是CM很快会通知您,制作新副本,恢复交易

重新配置
一个ZooKeeper集群(少数副本)
仅存储配置号,此配置中的服务器集和CM
如果多台服务器尝试成为CM,则会中断联系
选择活动分区(如果已分区)(多数分区)
配置管理器(CM)(未复制)
通过快速ping监视所有服务器的活动状态
管理重新配置
续约
仅在得到大多数计算机的响应时才激活
检查每个区域至少存在一个副本
将区域分配给主要/备份集
告诉服务器制作新副本
管理中断交易的完成

让我们回顾一下图4的提交协议,看看如何
尽管服务器出现故障,但可能已提交的所有xaction仍然可见。
“可能已承诺”:
TC可能对客户回答“是”
主要读者可能已经透露了对后续阅读的更新

在TC从所有LOCK和VALIDATE中看到“是”之后,
TC将COMMIT-BACKUP附加到每个备份的日志中
毕竟,将COMMIT-PRIMARY附加到每个主数据库的日志中
一个确认后,向应用程序报告“提交”

注意TC复制到备份;原色不复制
COMMIT-BACKUP包含写入值,足以更新备份的状态

为什么TC仅在* all * COMMIT-BACKUPs确认后才发送COMMIT-PRIMARY?
一个主数据库一看到COMMIT-PRIMARY就可以执行
并显示其他交易的更新
因此,到那时,每个对象的新值必须在f + 1个日志中(每个区域)
因此f可以失败而不丢失新值
如果有一个备份没有COMMIT-BACKUP
该对象的写入仅在f日志中
所有f都可能与TC一起失败
那么我们本可以公开提交,但可能永久丢失一次写入!

为什么TC等待来自COMMIT-PRIMARY的确认?
这样就可以知道提交的完整f + 1区域
在此之前,每个区域只有f个备份知道(来自COMMIT-BACKUPs)
但是我们假设每个区域最多有f个失败

为什么可以进行恢复的基本理由:
如果TC可能报告了“提交”,或者主要数据库可能具有公开价值,
那么每个区域中的所有f + 1在日志中都有LOCK或COMMIT-BACKUP,
因此f可以从任何/每个区域失败而不会丢失写入。
如果恢复看到一个或多个COMMIT- *,以及COMMIT- *或LOCK,
来自每个地区的承诺;否则中止。
即,证据TC决定提交,再加上每个对象的写入。
(第5.3节,第7步)

FaRM非常令人印象深刻;它不完美吗?
*由于OCC,如果冲突很少,效果最好。
*数据必须适合总RAM。
*数据模型是低级的;将需要例如SQL库。
*由特定的NIC功能驱动的详细信息;如果NIC已进行测试并设置怎么办?

摘要
分布式事务被认为太慢而无法认真使用
FaRM可能证明这不是真的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值