代码改变世界

Yahoo!S4分布式流处理引擎分析总结

2012-02-03 15:21  Aga.J  阅读(5456)  评论(4编辑  收藏  举报

  S4(Simple Scalable Streaming System)是一个分布式流处理引擎,开发者可以在这个引擎基础上开发面向无界的,不间断的流数据处理应用。

  什么是流数据处理应用?例如,为了个性化搜索广告,系统需要实时处理来自几百万唯一用户每秒成千上万次的查询,并即时分析用户的会话特征来提高广告相关性预测模型的准确度。流数据处理应用要求我们的系统可以接受大量的,不间断的数据(称为流式数据),并可以迅速做出数据处理,S4正是完成这样一个需求。

  S4的设计思想

  S4将一个流抽象为由(K,A)形式的元素组成的序列,这里K和A分别是键和属性。在这种抽象的基础上S4设计了能够消费和发出这些(K,A)元素的组件,也就是Process Element。Process Element在S4中是最小的数据处理单元,每个PE实例只消费事件类型,属性key,属性value都匹配的事件,并最终输出结果或者输出新的(K,A)元素。下面这张S4论文内的图很好的诠释了上面说的内容。

clip_image002

  图中节点表示PE,有向边表示一个(K,A)元素及其流向。流初始化为一个Key为null,事件类型为Quote的(K,A)元素,按照上文的说法,S4中需要定义一个能消费相应事件类型,属性key,属性value事件的PE,也就是图中的PE1。当PE1完成处理后,它发出新的(K,A)元素,即图中的事件类型为WordEvent,key为word=”x”,属性为count=x的边,最后经过多个PE处理和(K,A)事件转换得到最终结果(这里不介绍上图的处理过程,详细看论文介绍)。

  实际上,我认为S4最核心的部分就是上面的设计,它将流的处理分为多个流事件,抽象为处理图中的有向边,并且每个流事件都用(K,A)的形式表示,这种表示方式使得事件间的转换传递很方便,这是一种借鉴了MapReduce的(key,value)的设计。同时因为流被分为多个流事件,那么就需要对应多个处理单元,每个PE唯一处理一种事件,并且PE间独立,这也大大降低了概念复杂性和系统复杂性。我们开发者要做的就是定制个性化的PE。

  PE间有事件传递的依赖性,很自然的,我们希望可以有一个PE集群,S4使用Processing Element Container的概念,将多个PE包含到同一个容器中,PEC接收源event,并最终发送结果event。PEC加上通信处理模块就形成了PE的逻辑主机Processing Node。如下图所示:

clip_image003

  PN负责监听事件,在到达事件上执行操作(PE完成),然后通过通信层Communication Layer的协助分发事件,也可以发出输出事件。

  S4通过一个hash函数,将事件路由到目标PN上,这个hash函数作用于事件的所有已知属性值上(需要配置),所以一个事件可能被路由到多个PN上。然后PN中的事件监听器会将到来的事件传递给PEC,PEC以适当的顺序调用适当的PE(每个编键keyed的PE都会被映射到一个确定的PN上,即图中的PE并不是物理存在一个PN相关,而是逻辑相关)。处理完成后,PN可能发出输出事件,也可以向Communication Layer请求协助向指定逻辑节点发送消息。

最后是通信层的介绍,它提供了“集群管理”,“故障恢复到备用节点”,“逻辑节点到物理节点映射”的作用。同时通信层还使用一个插件式的架构来选择网络协议,使用zookeeper在S4集群节点之间做一致性协作!

S4的其他特点总结(摘自网络)

S4

S4是一个通用的、分布式的、可扩展的、分区容错的、可插拔的流式系统。基于S4框架,开发者可以轻松开发面向持续流数据处理的应用。

S4的设计特点有以下几个方面。

  • Actor Model

为了能在普通机型构成的集群上进行分布式处理,并且集群内部不使用共享内存,S4架构采用了Actor模式,这种模式提供了封装和地址透明语义,因此在允许应用大规模并发的同时,也提供了简单的编程接口。S4系统通过处理单元(Processing Elements,PEs)进行计算,消息在处理单元间以数据事件的形式传送,PE消费事件,发出一个或多个可能被其他PE处理的事件,或者直接发布结果。每个PE的状态对于其他PE不可见,PE之间唯一的交互模式就是发出事件和消费事件。框架提供了路由事件到合适的PE和创建新PE实例的功能。S4的设计模式符合封装和地址透明的特性。

  • Decentralized and Symmetric Architecture

除了遵循Actor模式,S4也参照了MapReduce模式。为了简化部署和运维,从而达到更好地稳定性和扩展性,S4采用了对等架构,集群中的所有处理节点都是等同的,没有中心控制。这种架构将使得集群的扩展性很好,处理节点的总数理论上无上限;同时,S4将没有单点容错的问题。

Pluggable Architecture

S4系统使用Java开发,采用了极富层次的模块化编程,每个通用功能点都尽量抽象出来作为通用模块,而且尽可能让各模块实现可定制化。

  • Partial Fault-Tolerance

基于Zookeeper服务的集群管理层将会自动路由事件从失效节点到其他节点。除非显式保存到持久性存储,否则节点故障时,节点上处理事件的状态会丢失。

  • Object Oriented

节点间通信采用“Plain Old Java Objects”(POJOs)模式,应用开发者不需要写Schemas 或用哈希表来在节点间发送Tuples。

S4的功能组件分3大类,Clients、Adapters和PNode Cluster,图2显示了S4系统框架。

clip_image005

图2 Yahoo! S4流式系统框架结构图

S4提供Client Adapter,允许第三方客户端向S4集群发送事件和接收事件。Adapter实现了基于JSON的API,支持多语言实现的客户端驱动。

Client通过Driver组件与Adapter进行交互,Adapter也是一个Cluster,其中有多个Adapter结点,Client可以通过多个Driver与多个Adapter进行通信,这样可以保证单个Client在分发大数据量时Adapter不会成为瓶颈,也可以确保系统支持多个Client应用并发执行的快速、高效和可靠性。

在Adapter中,真正与Client交互的是其Stub组件,该组件实现了管理Client与Adapter之间通过TCP/IP协议进行通信的功能。GenericJsonClientStub这个类支持将事件在Client与Adapter之间以JSON的形式转换,从而支持更多种类型的Client应用。不同的Client可以配置不同的Stub来与Adapter进行通信,用户可以定义自己的Stub来实现自己想要的业务逻辑,这样也使得Client的行为更加多样性、个性化。