前面通过文章《论文图谱当如是:Awesome-Graphs用200篇图系统论文打个样》向大家介绍了论文图谱项目Awesome-Graphs,并分享了Google的Pregel、OSDI'12的PowerGraph、SOSP'13的X-Stream。这次向大家分享Microsoft发表在SOSP'13的另一篇关于流处理系统论文Naiad,TimelyDataflow是它的开源实现。该论文促进了后续的流图系统的设计与创新,从其调度框架设计中也可以看到TuGraph Analytics调度器的影子。
对图计算技术感兴趣的同学可以多做了解,也非常欢迎大家关注和参与论文图谱的开源项目:
提前感谢给项目点Star的小伙伴,接下来我们直接进入正文!
Naiad是一个可执行有环数据流的分布式数据并行系统,提供了高吞吐的批处理、低延迟的流处理,以及迭代和增量计算的能力。
支持特性:
数据流图可以包含嵌套的循环结构,时间戳用于区分数据是由哪个轮次/迭代产生的。
及时数据流图包含输入/输出节点,输入节点从外部的生产者接受消息序列,输出节点将消息序列发送到外部消费者。
外部的生产者为每个消息打标了一个轮次(epoch),当没有消息需要输入时,会主动通知输入节点。
生产者也可以关闭输入节点,表示输入节点将不会再收到任何消息。
输出节点的消息也会打标这个轮次,同样当没有消息需要输出时,也会通知外部消费者。
及时数据流图里可以包含嵌套的循环上下文(loop contexts):
针对上图所表达的计算语义解释:
关键概念:逻辑时间戳(logical timestamp):
逻辑时间戳变化规则:
逻辑时间戳大小比较,t1=(e1, <c1, ..., cm>),t2=(e2, <c1, ..., cn>):
数据流的节点可以接收、发送带逻辑时间戳的消息(message),以及通知(notification)。
每个节点v实现两个回调函数:
并可以调用系统提供的两个函数:
对于数据流边e=(u, v),u.SendBy将触发v.OnRecieve,u.NotifyAt将触发v.onNotify。
数据流系统保证v.OnNotify(t)一定发生在v.OnRecieve(e, m, t')之后,其中t' < t,即保证处理完所有t之前的消息后再处理通知,以让节点具备机会清理t之前的工作状态。
这种机制保证了消息处理不会发生时光回溯(backwards in time)。
如下示例代码描述了一个双出的数据流节点实现distinct、count算子的逻辑。
class DistinctCount<S,T> : Vertex<T>
{
Dictionary<T, Dictionary<S,int>> counts;
void OnRecv(Edge e, S msg, T time)
{
if (!counts.ContainsKey(time)) {
counts[time] = new Dictionary<S,int>();
this.NotifyAt(time);
}
if (!counts[time].ContainsKey(msg)) {
counts[time][msg] = 0;
this.SendBy(output1, msg, time);
}
counts[time][msg]++;
}
void OnNotify(T time)
{
foreach (var pair in counts[time])
this.SendBy(output2, pair, time);
counts.Remove(time);
}
}
数据流处理受限于未处理的事件(events:消息、通知)和数据流图的结构。
关键概念:pointstamp:
单线程调度器实现:
OC的计算规则为:
Naiad通过允许程序按需协调,支持了混合的同步+异步计算。