本文介绍LinkedIn开源的Kafka,久仰大名了,依照其官方文档做些翻译和二次创作。相应能够查看整份官方文档。
基本术语
topics。维护的消息源种类(更像是业务上的数据种类/分类)
producer。给kafka的某个topic公布消息的进程
consumer,订阅和处理topic的消息的进程
broker。组成kafka集群的server
Topic和日志
kafka为每一个topic维护了例如以下一份被分区了的log
每份log有序。不可变,不断被append。分区中的消息会被分配一个有序的id。称为offset。
kafka内保留的消息是有时间限制的,超出设定的时间段的话,消息就不保留了。kafka的性能与数据容量是成正比的。
offset能方便consumer来取数据。自由度比較大(或者说这样的缓存性质的消息队列。方便消费者读取一定窗体内的消息。也算一种回放功能吧)。
分区一方面是为了增大消息的容量(能够分布在多个分区上存。而不会限制在单台机器存储大小里),二方面能够类似看成一种并行度。
分布
partitition分布在不同机器上,且能够设置备份数以达到容错。
每份partition都有一个扮演leader角色的server和几个扮演follower角色的server。leader来负责对这份分区的读写请求。
follower被动复制leader动作。leader挂了的话会有follower自己主动成为新的leader。
各个server都会各自扮演某份分区的leader和其它几份分区的followe,如此的话整个集群上的机器相对负载比較好些。
生产者
生产者选择公布数据给topic,负责选择topic的哪个partition,把消息写进去。
选择方法和策略有多种。
消费者
传统的消息模型有两种模型,队列模型和公布-订阅模式。
1. 队列形式中。一群消费者可能从server那边读消息。而每条消息会流向他们中的一个。
2. 公布-订阅模式中,消息会广播到全部它的消费者们那。
Kafka是使用consumer group这个概念(以下把它翻译为"消费组")。把两者结合了。。
消费者给自己标志了一个消费组名,每条新公布到topic的消息会被传递给订阅它的消费组里的消费者实例,这些消费者实例能够是不同的进程。存在在不同的机器上。
假设全部的消费者在同一个消费组里。那么这相当于是一个队列模型的场景。
假设全部的消费者都属于不同的消费组。那么这相当于是一个公布-订阅模式的场景。全部消息会广播到全部消费者们。
下图展示的是两台server组成的Kafka集群。共4个分区。两个消费组。A、B消费组各有2个、4个消费者,他们相应订阅了不同的分区。
此外,Kafka比传统的消息系统具备更强的有序性保证。以下会展开说明。
传统的队列形式的消息系统,在server端是有序保存着消息的。
但当有多个消费者来并发取queue里的消息的时候。因为每一个queue里的消息是异步输送给消费者,尽管输出是有序的(队列里排好队输出的),当消息到达消费者那头的时候。就不保证顺序了。假设单个消费者来取。能够保证有序,某些中庸的解决的方法还是会丧失一定并行度。
Kafka是怎么做到更好的并行且有序的呢?Kafkad的"分区"事实上是一种并行度的概念,即在topic内,kafka的消费者进程池能得到有序性保证和负载均衡。
这是由于在topic内设置了多个分区,使得topic相应的消费组里的消费者们各自能够独享一个分区。如此的话,每一个消费者是其消费的分区的唯一reader,在单个reader下当然保证了有序这件事。并且多个分区也使得负载能够比較平衡。
须要注意的是。消费者不能比分区数多。
保证
kafka能保证的几件事情,
1. 生产者向topic分区发来的消息能按序加入进来。即先送来的消息在log里面有更小的offset。
2. 消费者实例能在log里(第一张图里)看到有序的消息。
3. 一个拥有N个分区的topic。系统能容忍N-1台server失败,而不丢失写到了log里的消息数据。
很多其它设计上的内容不在这里阐述。
适合场景
消息队列
kafka作为消息队列。优势在更好的吞吐。内置分区。副本数。容错这几个特性,所以适合大规模消息处理应用。
MQ有非常多,就不详细比較了。
网页行为追踪
kafka原本的一个应用场景,就是跟踪用户浏览页面、搜索及其它行为。以公布-订阅的模式实时记录到相应的topic里。
那么这些结果被订阅者拿到后,就能够做进一步的实时处理。或实时监控,或放到hadoop/离线数据仓库里处理。
行为追踪常常会有非常大的吞吐量。
元信息监控
作为操作记录的监控模块来使用。即汇集记录一些操作信息,能够理解为运维性质的数据监控吧。
日志收集
日志收集方面,事实上开源产品有非常多。包含Scribe、Apache Flume。
假设谈Kafka的优势的话,事实上还是离不开他的容错、高吞吐性能方面的设计层面的特点吧。详细就不分析了。
參考我之前写的分布式日志收集系统Apache Flume的设计介绍
流处理
这个场景可能比較多,也非常好理解。保存收集流数据。以提供之后对接的Storm或其它流式计算框架进行处理。
Commit Log
为分布式系统的一些commit log(操作日志)做容错意义的备份,我是这么理解的,类似于HDFSnamenode的log。对照BookKeeper,事实上就是做这件事的。
BookKeeper在Hadoop HDFS Namenode HA方案里,用于记录namenode的操作日志(一时想不起叫什么log了,反正不记录namenode的image数据)。
參考我之前写的BookKeeper设计介绍及其在Hadoop2.0 Namenode HA方案中的使用分析
全文完 :)