【Samza系列】实时计算Samza中文教程(三)——架构

本篇紧接着概念篇,从宏观角度上看一下Samza实时计算服务的架构是什么样的?

Samza是由以下三层构成:

1. 数据流层(A streaming layer)

2. 执行层(An execution layer)

3. 处理层(A progressing layer)

那Samza是依靠哪些技术完成以上三层的组合呢?如下图所示:

1. 数据流:分布式消息中间件Kafka

2. 执行:Hadoop资源调度管理系统YARN

3. 处理: Samza API

玩过大数据Hadoop的人可以类比下面的架构模式(存储由HDFS负责,执行层由YARN负责,而处理层则由MapReduce负责),如下图所示:

在你进一步了解这三层的每一部分前,应该要注意到对于Samza的支持并不局限于使用Kafka和YARN,具体需要根据你的业务场景来确定使用什么技术框架、工具作支持。特别是Samza的执行层和数据流层都是可插拔的,并且允许开发者自己去实现更好的替代品。

咱们深入一点,先介绍数据流层的解决方案——kafka(熟悉的童鞋可以跳过)。

这个有着浓厚文艺气息名号的Kafka是一个分布式发布/订阅消息队列系统,它支持至少一次通信保障(即系统保证没有信息丢失,但是在某些故障情况下,消费者可能收到超过一条同样的信息)和高度可用的分区特性(即使一台机器宕机了,分区依然是可用的)。

对于Kafka来讲,每一条数据流被称为一个话题(topic)。每一个话题都在多台被称作broker的机器上进行分区和复制。当一个生产者发送一条消息给一个话题,它会提供一个key,这个key被用来决定这条消息应该被发送到哪一个分区。生产者发送信息而Kafka的broker则接收和存储它们。kafka的消费者能通过在一个话题的所有分区上订阅消息来读取消息。

值得补充的是,kafka有一些有趣的特点:

* 带着同一个key的所有消息都被划分到同一个分区,这就意味着如果你想要读到一个特定用户的所有消息,你只要从包含这个用户id的分区读取即可,而不是整个topic(假设把用户id用作key)

* 一个话题的分区是按顺序到达的一序列消息,所以你可以通过单调递增偏移量offset来引用任何消息(就好比放一个索引到一个数组里);这也意味着broker不需要跟踪被一个特定的消费者读取的消息,为什么呢?因为消费者保存了消息的偏移量offset能够跟踪到它。然后我们知道的是带着一个比当前偏移量小的消息是已经被处理过的,而每一个带着更大偏移量的消息还没有被处理过

关于Kafka还有很多知识点,有兴趣的同学可以参考我关于Kafka的一些文章加深对它的理解(http://blog.csdn.net/yangchao228/article/details/40583765)。

再来看看新一代Hadoop推出的资源管理系统YARN

YARN(Yet Another Resource Negotiator)是新一代hadoop集群调度器。它可以让你在一个集群中配置一个容器,并且执行任意命令。当一个应用和YARN相互交互时,它看起来像这样的:

1. Application:hi YARN Boy!我想用512MB内存在两台机器上跑命令X;

2. YARN:cool, 你的代码在哪里?

3. Application:代码在这里呢:http://path.to.host/jobs/download/my.tgz

4. YARN:我正在网格node1 和node2上执行你的job。

Samza使用YARN去管理部署、容错、日志、资源隔离、安全以及本地化。这里提供一个简要介绍(见http://hortonworks.com/blog/apache-hadoop-yarn-background-and-an-overview/)。

YARN的架构

当然为了节省大家的时间,宏观上来看一下YARN的架构吧。首先YARN也是有三个层次构成:一个资源管理器(ResourceManager),,一个节点管理器(NodeManager)和一个应用管理器(ApplicationMaster)。在一个YARN网格里,每一台机器上都跑着一台NodeManager,它负责在所在的机器上启动进程。而一个ResourceManager则与所有的NodeMananger交互告诉它们跑什么应用,反过来NodeManager也会告诉ResourceManager它们希望什么时间在集群里跑这些东东。对于第三层ApplicationMaster则是让特定应用的代码跑在YARN集群上。它负责管理应用的负载、容器(通常是UNIX进程),并且当其中一个容器失败时发出通知。

Samza and YARN

Samza提供了一个YARN ApplicationMaster和一个开箱即用的YARN任务运行器。这样说大家可能觉得不直观,Samza和YARN的集成可以用下图来概述(不同的颜色表示不同的机器):

解释一下上面这个图吧,Samza的客户端当它想开始一个新job时会告诉YARN的RM(ResourceManager,以下简称RM)。这个RM会告诉YARN的一个NodeManager(简称NM)为Samza的ApplicationMaster(AM)在集群里分配空间。一旦NM分配了空间,就会启动这个Samza的AM。AM开始后,它会要求RM为了跑SamzaContainers需要更多的YARN的containers。而且RM会和NMs一起为containers分配空间。一旦空间被分配,NMs就会开启Samza
containers。

Samza

简要介绍了一下YARN,接下来就是我们的焦点Samza。Samza通过使用YARN和Kafka提供一个阶段性的流处理和分区的框架。把它们三者放在一起的话大概就是这个样子了:

Samza的客户端使用YARN来运行一个Samza任务(job):YARN启动并且监控一个或者多个SamzaContainers,并且你的处理逻辑代码(使用the StreamTask API)在这些容器里运行。这些Samza 流任务的输入和输出都来自Kafka的Brokers(通常他们都是作为YARN NMs位于同台机器)

举个例子

比如我们想要统计页面访问数量。如果用SQL,你可能会写成下面这样的:

SELECT user_id, COUNT(*) FROM PageViewEvent GROUP BY user_id

尽管Samza目前不支持SQL,但是思路是相同的;计算这个需求需要两个任务:一个任务按照userid聚合消息,另一个任务则是计数。

进一步来说,第一个任务是分组工作通过发送带有相同userid的消息发送到一个中间话题的相同分区里,你可以通过使用第一个job发射的消息里的userid作为key来做到,并且这个key被映射到这个中间话题的分区(通常会取key对分区数目取余)。第二个任务处理中间话题产生的消息。在第二个任务里每个任务都会处理中间话题的一个分区。在对应分区中任务会针对每一个userid弄一个计数器,并且每次任务接受带着一个特定userid的消息时对应的计数器自增1。弄张图大家看看:

 

怎么样这个图是不是到处都看得到,和hadoop的Mapreduce的运行很相似对吧,每一个记录带着一个特定的key放到mapper里,被框架按照相同key进行分组,然后再reduce里进行计算统计。但是hadoop和Samza还是非常不同的,因为Hadoop的计算时基于一个固定的输入,而Samza则是和没有限定的数据流打交道。另外我自己再补充一条,流式计算框架和MapReduce另一个很大不同点在于mr的任务是会停止的,而Samza是持续不断处理。

Kafka接收到第一个job发送的消息并且把它们缓冲到硬盘,并且分布在多台机器上。这有助于系统的容错性提升:如果一台机器挂了,没有消息会被丢失,因为它们被存在其他机器里。并且如果第二个job因为某些原因消费消息的速度慢下来或者停止,第一个任务也没有影响:磁盘缓冲可以积累消息直到第二个任务快起来。

通过对topic的分区,将数据流处理拆解到任务中以及在多台机器上并行执行任务,使得Samza具有很高的消息吞吐量。通过结合YARN和Kafka,Samza实现了高容错:如果一个进程或者机器失败,它会自动在另一台机器上重启它并且继续从消息终端的地方开始处理,这些都是自动化的。

最后我想表达一下,samza其实并不是一个人在战斗,它拉上其他给力的伙伴,使得上面的一切显得顺其自然,我相信这也是未来优秀软件的发展方向。好了架构介绍完了,按照官方文档的顺序本来应该介绍一些对比介绍,考虑到有些同学可能没接触过,我们就跳过跟其他家伙(后续抽时间完成翻译)的对比直奔主题吧。下一篇咱们来看看Samza的API,敬请期待!

时间: 2024-08-02 07:33:59

【Samza系列】实时计算Samza中文教程(三)——架构的相关文章

Swift中文教程(三)--流程控制

原文:Swift中文教程(三)--流程控制 Swift用if和switch编写条件控制语句,用for-in,for,while和do-while编写循环.条件控制语句和循环语句中,小括号是可选的,但花括号包住这个循环体是必须的: 1 let individualScores = [75, 43, 103, 87, 12] 2 var teamScore = 0 3 for score in individualScores { 4 if score > 50 { 5 teamScore += 3

【Samza系列】实时计算Samza中文教程(四)—API概述

上一篇和大家一起宏观上学习了Samza平台的架构,重点讲了一下数据缓冲层和资源管理层,剩下的一块很重要的SamzaAPI层本节作为重点为大家展开介绍. 当你使用Samza来实现一个数据流处理逻辑时,你必须实现一个叫StreamTask的接口,如下所示: public class MyTaskClass implements StreamTask { public void process(IncomingMessageEnvelope envelope, MessageCollector col

实时计算Samza中文教程(二)——概念

希望上一篇背景篇让大家对流式计算有了宏观的认识,本篇根据官网是介绍概念,先让我们看看有哪些东西呢? 概念一:Streams Samza是处理流的.流则是由一系列不可变的一种相似类型的消息组成.举个例子,一个流可能是在一个网站上的所有点击,或者更新到一个特定数据库表的更新操作,或者是被一个服务或者事件数据生成所有日志信息.消息能够被加到另一个流之后或者从一个流中读取.一个流能有多个消费者,并且从一个流中读取不会删除消息(使得小心能够被广播给所有消费者).另外消息可以有一个关联的key用来做分区,这

实时计算Samza中文教程(一)背景

大家应该听我在前言篇里扯皮后,迫不及待要来一看Samza究竟是何物了吧?先了解一下Samza的Background是必不可少的(至少官网上是放在第一个的),我们需要从哪些技术背景去了解呢? 什么是消息(Messaging)? 消息系统是一种实现近实时异步计算的流行方案.消息产生时可以被放入一个消息队列(ActiveMQ,RabbitMQ).发布-订阅系统(Kestrel,Kafka)或者日志聚合系统(Flume.Scribe).下游消费者从上述系统读取消息并且处理它们或者基于消息的内容产生进一步

Netty4.x中文教程系列(三) ChannelHandler

Netty4.x中文教程系列(四)  ChannelHandler 上一篇文章详细解释了Hello World示例的代码.里面涉及了一些Netty框架的基础. 这篇文章用以解释ChannelHandler.笔者本身在以前写过文章ChannelHandler改动及影响 和 ChannelInitializer 学习 对Netty的.ChannelHandler做过阐述.里面主要描述了4.x版本相对于3.x版本的改动以及影响.并引用了一些文章.为大家详细的解释了ChannelHandler里面涉及架

Netty4.x中文教程系列(二) Hello World !<转>

在中国程序界.我们都是学着Hello World !慢慢成长起来的.逐渐从一无所知到熟悉精通的. 第二章就从Hello World 开始讲述Netty的中文教程. 首先创建一个Java项目.引入一个Netty 框架的包.这个步骤我在本系列教程的后面就不在重复了. 先上一张我示例的项目工程图给大家看一下: 1.下载并为项目添加Netty框架 Netty的包大家可以从Netty官网:http://netty.io/downloads.html 下载 如图所示: Netty提供了三个主要版本的框架包给

Netty4.x中文教程系列(六) 从头开始Bootstrap

Netty4.x中文教程系列(六) 从头开始Bootstrap 其实自从中文教程系列(五)一直不知道自己到底想些什么.加上忙着工作上出现了一些问题.本来想就这么放弃维护了.没想到有朋友和我说百度搜索推荐了我的文章.瞬间有点小激动啊.决定自己要把这个教程系列完善下去.这里诚挚的想支持我的盆友们道歉.真的是让你们失望了.我居然有想放弃的这种丧心病狂的念头.以后绝对不会了. 其实伴随着对Netty的逐步深入学习.感觉自己对netty的了解仍然有所欠缺.加上笔者语文课是美术老师教的.所以..说多了都是泪

struts2官方 中文教程 系列八:异常处理

在本教程中,我们将探讨如何启用Struts 2框架处理web应用程序生成的任何未捕获的异常.Struts 2提供了健壮的异常处理,包括能够自动记录任何未捕获的异常,并将用户重定向到错误web页面. 贴个本帖的地址,以免被爬:struts2官方 中文教程 系列八:异常处理  即 http://www.cnblogs.com/linghaoxinpian/p/6915066.html 下载本章节代码 全局异常处理(Global Exception Handling) 使用Struts 2框架,您可以

struts2官方 中文教程 系列十一:使用XML进行表单验证

在本教程中,我们将讨论如何使用Struts 2的XML验证方法来验证表单字段中用户的输入.在前面的教程中,我们讨论了在Action类中使用validate方法验证用户的输入.使用单独的XML验证文件让您可以内置到Struts 2框架的验证器. 贴个本帖的地址,以免被爬:struts2官方 中文教程 系列十一:使用XML进行表单验证  即 http://www.cnblogs.com/linghaoxinpian/p/6938720.html 下载本章节代码 为了使用户能够编辑存储在Person对