6.824-lecture13

6.824 讲座13:Naiad案例研究

Naiad:及时的数据流系统
默里,麦克谢里,以撒,艾萨德,巴勒姆,阿巴迪
SOSP 2013

如今:流和增量计算
案例研究:Naiad
我们为什么要读《 Naiad》?
优雅的设计
令人印象深刻的表现
开源且仍在开发中

总结:Spark提高了迭代计算的性能
即,一次又一次使用相同数据的数据
但是如果输入数据发生变化怎么办?
可能会发生,例如因为搜寻器更新页面(新链接)
或因为应用程序将新记录追加到日志文件
实际上,Spark(如上一课的论文一样)必须重新开始!
即使只更改一个链接,也可以再次运行所有PageRank迭代
(但是:Spark Streaming-与Naiad类似,但在Spark之上)

增量处理
输入顶点
可能是文件(如Spark / MR)
或一系列事件,例如网络请求,推文,传感器读数…
将(键,值,纪元)记录注入图形
固定数据流
记录流入顶点,作为响应可能会发出零个或多个记录
有状态顶点(长寿命)
有点像缓存的RDD
但可变:状态变化以响应到达顶点的新记录
例如:GroupBy和sum()为每个组存储一个记录
新记录更新当前汇总值

数据流循环迭代
对比:Spark没有周期(DAG),通过添加新的RDD进行迭代
没有RDD可以依靠自己的孩子
适用于带循环的算法
例如:PageRank将等级更新发送回计算开始
“根”流上下文
特殊,因为引入了带有时期的输入(由程序指定)
循环上下文
可以任意筑巢
不能部分重叠
[图3带嵌套循环的示例]

问题:需要订购!
[示例:延迟PR等级更新,下一次迭代读取旧等级]
直觉:避免耗时的更新
当顶点已经移动时,它会看到过去迭代的更新
顶点从将来的迭代中发出更新
关键要素:分层时间戳
时间戳:(epoch,[c1,…,ck])其中ci是第i级循环上下文
入口,出口,反馈顶点修改时间戳
进入:在末尾附加新的循环计数器(开始循环)
出口:从末端丢弃循环计数器(脱离循环)
反馈:结束时递增循环计数器(迭代)
[图3时间戳传播:演讲题]
纪元1:
(a,2):循环3次(值4-> 8-> 16)
A:(1,[]),I:(1,[0]),… F:(1,[1]),… F:(1,[2]),… E: (1,[])
(b,6):仅循环一次(值6-> 12)
A:(1,[]),I:(1,[0]),… F:(1,[1]),… E:(1,[])
纪元2:
(a,5):由于DISTINCT而下降到A。
时间戳形成部分顺序
(1,[5,7])<(1,[5,8])<(1,[6,2])<(2,[1,1])
而且:(1,[5,7])<(1,[5])-循环计数器的字典顺序
并且,对于两个顶级循环:(1,lA [5])与(1,lB [2])不进行比较
允许顶点排序更新
并决定何时可以释放它们
因此下游顶点按顺序获得一致的输出

程序员API
好消息:最终用户大多不用担心时间戳记
及时的数据流是低级基础架构
允许专家针对特定用途进行特殊目的的实现
[图2:运行时,及时的数据流,差异数据流,其他库]
由基于及时数据流抽象的库提供的高级API
例如:LINQ(类似SQL),BSP(类似Pregel-ish),Datalog
Spark生态系统中针对专用库的类似趋势
SparkSQL,GraphX,MLLIb,流式传输…

低级顶点API
需要明确处理时间戳
通知
“您将不再收到带有此时间戳或更早的时间戳的记录”
顶点可以例如决定计算最终值并释放
运行时在顶点上调用的两个回调:
OnRecv(edge,msg,timestamp)-这是一些消息
OnNotify(timestamp)-没有更多消息<=时间戳即将到来
两个API调用可用于顶点代码:
SendBy(edge,msg,timestamp)-在当前或将来的时间发送消息
NotifyAt(timestamp)-在时间戳记时回叫我
允许不同的策略
逐步释放记录一段时间,并以通知结束
暂时缓冲所有记录,然后在通知时释放
[代码示例:非重复计数顶点]

进度追踪
确定何时将通知传递到顶点的协议
直觉
可以在前辈无法“完成”之后立即发送通知
生成具有更早时间戳记的记录
单线程示例
“ pointstamps”:只是一个时间戳+位置(边缘或顶点)
[x轴上的顶点/边的格子图,y轴上的时间]
箭头表示可能导致
遵循时间戳的部分顺序
例如:示例CRI(1,[3])中位于B的(1,[2]),但也(1,[])位于B
=>在一切都离开循环之前,无法完成(1,[])
一旦没有活动发生,请删除活动的pointstamp
即出现次数(OC)= 0
前沿:没有输入箭头的点戳
一直沿时间轴移动,但是位置的速度有所不同
分布式版本
稻草人1:将所有事件发送给单个协调员
慢,因为需要等待此协调员
这是“全球前沿”-协调员拥有所有信息
稻草人2:在本地处理事件,然后通知所有其他工人
广播!
工人现在维护“本地边界”,这近似于全球
工作人员只能落后:进度更新可能仍在网络中
本地边界永远无法超越全球边界
因此安全,因为只会延迟通知
问题:发送大量进度信息!
60台计算机上的WCC约为10 GB(“无”,图6(c))
解决方案:广播前在本地汇总事件
每个事件将OC改变+1或-1 =>可以合并
表示我们可能要等一会儿再进行更新(始终安全)
仅在活动点戳集更改时发送更新
全球聚合器合并来自不同工作人员的更新
就像稻草人的全球协调员,但信息却少得多

容错能力
也许是本文最薄弱的部分
选项1:编写全局同步,协调的检查点
恢复加载最后一个检查点(包括时间戳,进度信息)
然后从那里开始处理,可能会重复输入
在进行检查点时引起暂停时间(参见尾部等待时间,图7c)
选项2:在发送之前将所有消息记录到磁盘
无需检查站
恢复可以从任何点恢复
但常见的间接费用很高(即即使没有故障也要付出代价)
问:为什么不使用Spark的重新计算策略?
答:很难进行细粒度的更新。到什么时候我们才可以重新计算?
本文之后制定的更聪明的方案
一些顶点检查点,一些日志消息
仍然可以恢复关节图
见福尔柯克轮论文-https://arxiv.org/abs/1503.08877

绩效结果
从根本上优化系统,如微基准测试所示(图6)
出色的PageRank性能(在twitter_rv图上,每次迭代<1s)
2013年非常好,现在仍然非常好!
Naiad在几个不同的领域中匹配或击败了专门的系统
迭代批处理:PR,SCC,WCC&c与DB,DryadLINQ的对比-提升了10倍以上
图形处理:twitter与PowerGraph上的PR-约提高10倍
迭代ML:Logistic回归与Vowpal Wabbit的比较-提升约40%

参考文献:
差分数据流:http://cidrdb.org/cidr2013/Papers/CIDR13_Paper111.pdf
Rust重新实现:

  • https://github.com/frankmcsherry/timely-dataflow
    • https://github.com/frankmcsherry/differential-dataflow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值