此页介绍啊Samza的一些高层级概念。
Streams
Samza处理Streams(流)。流由同一类型的不可变的消息组成。例如,一个流可以是对一个网站的所有点击,或者对一个数据库表的所有更新,或者一个服务产生的所有日志,或者其它类型的消息数据。消息可以被追加到一个流上或者从一个流读出来。一个流可以有任意数量的消费者,并且从一个流读消息并不会把消息从其中删除(所有每息都可以有效地广播到其它消费者)。消息可以有选择地拥有一个相关连的key用做分区partitioning,分区的问题接下来会提到。
Samza支持实现了流这种抽象的pluggable系统:对Kafka,一个流就是一个topic,对于数据库,我们可以消费对一个数据表的更新从而得到一个流,对Hadoop我们可以tail HDFS中的一个目录下的文件。
Jobs
一个Samza job是一些代码,它们用来对一些输入流做逻辑转换,然后把输出的消息追加到一些输出流里。
如果我们不关心可扩展性,我们就只需要streams和jobs。但是,为了扩展流处理器stream processor的吞吐量,我们把streams和jobs切成更小的并行工作的单元:partitions和tasks.
Partitions
每个流被分成一个或更多分区。流中的每个分区都是一个有序的消息序列。
序列中的每条消息都有一个叫做offset的标识,offset在每个partition中是唯一的。offset可以是连续的整数,字节偏移量,或者依赖于底层系统的字符串。
当一个消息被附加到一个流上,它被附加到这个流的一个分区里。从消息到分区的分配由消息生成者提供的一个key来完成。例如,如果用户ID被用来做key,那么就可以使得一个用户相关的所有消息都被送到同一个分区里。
Tasks
一个job通过分成多个task来扩展。task是job并行执行的单元,就像partition是stream的并行单元。每个task消费这个job的一系列输入流中每一个流的一个分区。
一个task从它的每一个输入分区中顺序处理消息,按照message的offset的顺序。在partition之间没有确定的顺序。这使得每个task可以独立操作。YARN调度器把每个task分配到机器,所以每个job做为一个整体被分布到多台机器上。
job里边task的数量由输入的parition的数量决定(不能有比输入的partition更多的task, 否则会有一些task没有输入)。你可以调整分配给一个job的计算资源(内存大小 、 CPU的核数,等)来满足job的需要。详见下边对container的描述。
task和partition之间的分配永远不会改变:如果某个机器上的task失败了,这个task会在别的地方重启,它还会继续消费同样的流的分区。
Dataflow Graphs
我们可以把多个job组在一起来创建一个dataflow graph。这个数据流图中,节点是包含了数据的stream,边是进行转换的jobs。这种组合完全通过job的输入输出流来实现。这些job的其它方面是完全解耦合的:它们不需要由同样的代码基础实现,并且对下游job的增加、移除、重启都不会影响上游的job。
这些graph通常都是无环的——数据通常不是从一个job出来,经过其它的job,回到它自己。但是,如果你需要,也可以创建有环图。
Containers
partition和task都是并行的逻辑单元,它们并不和任何对计算资源(CPU、内存、磁盘空间等)的特定分配有关。Container是物理并行的单元,一个container本质上是一个Unix进程(或Linux cgroup)。每个container运行一个或多个tasks。task的数目由输入的partition 的数目自动决定,并且是固定的。但是container的数量(以及与其相关联的CPU和存储资源)由用户在运行时指定的,并且任何时候都可以改变。
下一节 Architecture