上一篇和大家一起宏观上学习了Samza平台的架构,重点讲了一下数据缓冲层和资源管理层。剩下的一块非常重要的SamzaAPI层本节作为重点为大家展开介绍。

    当你使用Samza来实现一个数据流处理逻辑时。你必须实现一个叫StreamTask的接口,例如以下所看到的:
public class MyTaskClass implements StreamTask {

  public void process(IncomingMessageEnvelope envelope,
MessageCollector collector,
TaskCoordinator coordinator) {
// process message
}
}

当你执行你的job时,Samza将为你的class创建一些实例(可能在多台机器上)。这些任务实例会处理输入流里的消息。


    在你的job的配置中你能告诉Samza你想消费哪条数据流。

举一个较为完整的样例(大家也能够參看http://samza.incubator.apache.org/learn/documentation/0.7.0/jobs/configuration.html

):
# This is the class above, which Samza will instantiate when the job is run
task.class=com.example.samza.MyTaskClass # Define a system called "kafka" (you can give it any name, and you can define
# multiple systems if you want to process messages from different sources)
systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory # The job consumes a topic called "PageViewEvent" from the "kafka" system
task.inputs=kafka.PageViewEvent # Define a serializer/deserializer called "json" which parses JSON messages
serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory # Use the "json" serializer for messages in the "PageViewEvent" topic
systems.kafka.streams.PageViewEvent.samza.msg.serde=json
    对于Samza从任务的输入流利接收的每一条消息,处理逻辑都会被调用。它主要包括三个重要的信息:消息、关键词key以及消息来自的数据流:
/** Every message that is delivered to a StreamTask is wrapped
* in an IncomingMessageEnvelope, which contains metadata about
* the origin of the message. */
public class IncomingMessageEnvelope {
/** A deserialized message. */
Object getMessage() { ... } /** A deserialized key. */
Object getKey() { ... } /** The stream and partition that this message came from. */
SystemStreamPartition getSystemStreamPartition() { ... }
}
    注意键和值都要被声明为对象,而且须要转化为正确的类型。假设你不配置一个serializer/deserializer。它们就会成为典型的java字节数组。一个deserializer可以转化这些字节到其它随意类型,举个样例来说j一个son deserializer可以将字节数组转化为Map、List以及字符串对象。

    SystemStreamPartition()这种方法会返回一个SystemStreamPartition对象,它会告诉你消息是从哪里来的。它由下面三部分组成:
    1. The system:系统的名字来源于消息。就在你job的配置里定义。你能够有多个用于输入和输出的不同名字的系统;
    2. The stream name: 在原系统里数据流(话题、队列)的名字。相同也是在job的配置里定义;
    3. The partition: 一条数据流一般会被划分到多个分区。而且每个分区会被Samza安排一个StreamTask实例;
    API看起来像是这种:
/** A triple of system name, stream name and partition. */
public class SystemStreamPartition extends SystemStream { /** The name of the system which provides this stream. It is
defined in the Samza job's configuration. */
public String getSystem() { ... } /** The name of the stream/topic/queue within the system. */
public String getStream() { ... } /** The partition within the stream. */
public Partition getPartition() { ... }
}
    在上面这个job的配置样例里可以看到。这个系统名字叫“Kafka”。数据流的名字叫“PageViewEvent”。(kafka这个名字不是特定的——你能给你的系统取不论什么你想要的名字)。

假设你有一些输入流向导入你的StreamTask,你可以使用SystemStreamPartition去决定你接受到哪一类消息。


    怎样发送消息呢?假设你看一下StreamTask里的process()方法,你将看到你有一个MessageCollector接口。
/** When a task wishes to send a message, it uses this interface. */
public interface MessageCollector {
void send(OutgoingMessageEnvelope envelope);
}
    为了发送一个消息, 你会创建一个OutgoingMessageEnvelop对象而且把它传递给消息收集器。它至少会确定你想要发送的消息、系统以及数据流名字再发送出去。你也能够确定分区的key和还有一些參数。详细能够參考javadoc(http://samza.incubator.apache.org/learn/documentation/0.7.0/api/javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html)。

    注意事项:
    请仅仅在process()方法里使用MessageCollector对象。

假设你保持住一个MessageCollector实例而且之后再次使用它,你的消息可能会错误地发送出去。举一个样例,这儿有一个简单的任务,它把每个输入的消息拆成单词,而且发送每个单词作为一个消息:

public class SplitStringIntoWords implements StreamTask {

  // Send outgoing messages to a stream called "words"
// in the "kafka" system.
private final SystemStream OUTPUT_STREAM =
new SystemStream("kafka", "words"); public void process(IncomingMessageEnvelope envelope,
MessageCollector collector,
TaskCoordinator coordinator) {
String message = (String) envelope.getMessage(); for (String word : message.split(" ")) {
// Use the word as the key, and 1 as the value.
// A second task can add the 1's to get the word count.
collector.send(new OutgoingMessageEnvelope(OUTPUT_STREAM, word, 1));
}
}
}
    Samza的API的概要介绍就到这里吧,非常多细节的API能够參看javadoc文档,这也是官网下一节的内容,因为篇幅有限,大家能够自己针对性的去深入了解了解就能够了。下一篇会讲一下之前在架构篇里多次提到的SamzaContainer。


    

【Samza系列】实时计算Samza中文教程(四)—API概述的更多相关文章

  1. Swift中文教程(四)--函数与闭包

    原文:Swift中文教程(四)--函数与闭包 Function 函数 Swift使用func关键字来声明变量,函数通过函数名加小括号内的参数列表来调用.使用->来区分参数名和返回值的类型: fu ...

  2. 【Samza系列】实时计算Samza中文教程(二)——概念

    希望上一篇背景篇让大家对流式计算有了宏观的认识,本篇依据官网是介绍概念,先让我们看看有哪些东西呢?     概念一:Streams     Samza是处理流的.流则是由一系列不可变的一种相似类型的消 ...

  3. 【Samza系列】实时计算Samza中文教程(一)背景

        大家应该听我在前言篇里扯皮后,迫不及待要来一看Samza到底是何物了吧?先了解一下Samza的Background是不可缺少的(至少官网上是放在第一个的),我们须要从哪些技术背景去了解呢?   ...

  4. Netty4.x中文教程系列(四) 对象传输

    Netty4.x中文教程系列(四)  对象传输 我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持. 首先我们定义一个U ...

  5. struts2官方 中文教程 系列十四:主题Theme

    介绍 当您使用一个Struts 2标签时,例如 <s:select ..../>  在您的web页面中,Struts 2框架会生成HTML,它会显示外观并控制select控件的布局.样式和 ...

  6. Netty4.x中文教程系列(五)编解码器Codec

    Netty4.x中文教程系列(五)编解码器Codec 上一篇文章详细解释了ChannelHandler的相关构架设计,版本和设计逻辑变更等等. 这篇文章主要在于讲述Handler里面的Codec,也就 ...

  7. Netty4.x中文教程系列(一) 目录及概述

    Netty4.x中文教程系列(一)目录及概述 Netty 提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. Netty是一个NIO客户端 服务端框架 ...

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

    Netty4.x中文教程系列(四)  ChannelHandler 上一篇文章详细解释了Hello World示例的代码.里面涉及了一些Netty框架的基础. 这篇文章用以解释ChannelHandl ...

  9. NGUI系列教程四(自定义Atlas,Font)

    今天我们来看一下怎么自定义NGUIAtlas,制作属于自己风格的UI.第一部分:自定义 Atlas1 . 首先我们要准备一些图标素材,也就是我们的UI素材,将其导入到unity工程中.2. 全选我们需 ...

随机推荐

  1. Python操作MySQL数据库完成简易的增删改查功能

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 目录 一丶项目介绍 二丶效果展示 三丶数据准备 四丶代码实现 五丶完整代码 一丶项目介绍 1.叙述 博主闲暇之余花了10个小时写的 ...

  2. BZOJ 3732 Network Kruskal+倍增LCA

    题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 NOIP2013 货车运输.差点儿就是原题...仅仅只是最小边最大改成了最大边最小.. . 首先看到最大值最小第一 ...

  3. “ping”命令的原理就是向对方主机发送UDP数据包,HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”

    Socket  是一套建立在TCP/IP协议上的接口不是一个协议 应用层:  HTTP  FTP  SMTP  Web 传输层:  在两个应用程序之间提供了逻辑而不是物理的通信(TCP  UDP) T ...

  4. Windows 共享无线上网 无法启动ICS服务解决方法(WIN7 ICS服务启动后停止)

    Windows 共享无线上网 无法启动ICS服务解决方法(WIN7 ICS服务启动后停止) ICS 即Internet Connection Sharing,internet连接共享,可以使局域网上其 ...

  5. 40.lombok在IntelliJ IDEA下的使用

    转自:https://www.cnblogs.com/yjmyzz/p/lombok-with-intellij-idea.html lombok是一款可以精减java代码.提升开发人员生产效率的辅助 ...

  6. 108.sqllite3(C语言数据库库)详解

    //创建数据库,插入表,生效 //创建数据库,插入表,生效 void create_database() { //数据库指针 sqlite3 *db=; //打开数据数据库,初始化指针 int res ...

  7. ES5, ES6, ES2016, ES.Next: JavaScript 的版本是怎么回事?

    原网址:http://huangxuan.me/2015/09/22/js-version/ JavaScript 有着很奇怪的命名史. 1995 年,它作为网景浏览器(Netscape Naviga ...

  8. Redis的高级应用-安全性和主从复制

    Redis的服务器命令和键值命令(String,Hash,List,Set,Zset)相对简单,只需查看文档即可. 文档地址: http://www.runoob.com/redis/redis-tu ...

  9. 浩爷AC自己主动机高速学习方案

        今天弄完自己主动机之后.从那天比赛的阴影中爬出来了,猛地一看真不咋滴难,细致一看这尼玛还不如猛的一看. ..     必备算法:KMP,字典树(KMP我写了,字典树太简单,就是一个思想.我能够 ...

  10. GO语言学习(八)Go 语言常量

    Go 语言常量 常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: const identifier ...