kafka入门

来源:互联网 发布:淘宝上好吃的特产 编辑:程序博客网 时间:2024/05/22 03:15
Publish / Subscribe Messaging  发布/订阅消息

在讨论kafka的特性之前,需要理解发布订阅消息的概念及其重要性。发布-订阅消息队列的特征是消息的sender(publisher)并不直接将data(message)发送给receiver, publisher以某种方法对消息进行分类,而receiver (subscriber) 会订阅接收特定类别的消息。Pub/Sub系统通常会有broker(消息被发布到的中心点)来进行实现,消息将被发送至broker。

kafka是什么?

kafka结构关系?


Topic:特指Kafka处理的消息源(feedsof messages)的不同分类。

Partition:Topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。

Broker:Kafka集群中包含一台或多台服务器,这种服务器被称为broker。

Producer:生产者,向Kafka的一个topic发布消息。

Consumers:消费者,从kafka的某个topic读取消息。

使用Spark streaming读取kafka数据时,为了避免数据丢失,我们会在zookeeper中保存kafkatopic对应的partitionoffset信息(每次执行成功后,才更新zk中的offset信息);从而保证执行失败的下一轮,可以从特定的offset开始读。

但,kafkatopic是可能会被删除的,而更糟糕的情况是,用户又新建了一个相同名字的topic。这是,zk中保存的offset信息会已经不再准确了,此时就需要与kafkabroker保存的offset信息进行比对,从而把zk中的offset信息修正成功

consumer与topic关系:

本质上kafka只支持Topic;

l  每个group中可以有多个consumer,每个consumer属于一个consumergroup;

通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高"故障容错"性,如果group中的某个consumer失效那么其消费的partitions将会有其他consumer自动接管。

l  对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer;

那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个"订阅"者。

l  在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻)

一个Topic中的每个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。

kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。

就是group中的消费者不要大于分区数

kafka确保每个partition只能同一个group中的同一个consumer消费,如果想要重复消费,那么需要其他的组来消费

kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。

 

查看topic-groupoffsert 
位置:zookeeper 
路径:[zk: localhost:2181(CONNECTED) 3] ls/brokers/topics/__consumer_offsets/partitions 
zookeepertopic中有一个特殊的topic __consumer_offserts 
计算方法:

 int hashCode =  Math.abs("ttt".hashCode());

 intpartition = hashCode %50;

新版kafka把这个offsert保存到了一个__consumer_offserttopic 
这个__consumer_offsert50个分区,通过将groupid哈希值%50的值来确定要保存到那一个分区
这样也是为了考虑到zookeeper不擅长大量读写的原因。

先计算grouphashCode,再除以分区数(50),可以得到partition的值 
使用命令查看:

kafka-simple-consumer-shell.sh--topic__consumer_offsets --partition11--broker-list localho



1 kafka中的消息单元:Message和batch
2 kafka中的消息格式:schema
3 kafka中的存储模式:Topic与partition
4 kafka中的两种客户端:producer和consumer
5 kafka中的服务核心:broker与cluster
6 多集群组成的灾备

Message和Batches

Kafka中最基本的数据单元是消息message,如果使用过数据库,那么可以把Kafka中的消息理解成数据库里的一条行或者一条记录。消息是由字符数组组成的,kafka并不关系它内部是什么,索引消息的具体格式与Kafka无关。消息可以有一个可选的key,这个key也是个字符数组,与消息一样,对于kafka也是透明的。key用来确定消息写入分区时,进入哪一个分区。最简单的处理方式,就是把key作为hash串,拥有相同key的消息,肯定会进入同一个分区。

为了提高效率,Kafka以批量的方式写入。一个batch就是一组消息的集合,这一组的数据都会进入同一个topic和partition(这个是根据producer的配置来定的)。每一个消息都进行一次网络传输会很消耗性能,因此把消息收集到一起,再同时处理就高效的多了。当然,这样会引入更高的延迟以及吞吐量:batch越大,同一时间处理的消息就越多。batch通常都会进行压缩,这样在传输以及存储的时候效率都更高一些。

Schemas

对于Kafa来说,消息本身是不透明的,这样就能对消息定义更多容易理解的内容。根据个人的需求不同,消息也会有不同的schema。比如JSON或者XML都是对人来说很容易阅读的格式。然后他们在不同的模式版本中间缺乏一些处理的鲁棒性和可扩展性。一些Kafka的开发者也倾向于使用Apache Avro(最开始是用来为Hadoop做序列化的),提供了紧凑的序列化格式,在发生变化时,也不需要重新生成代码,具有很强的数据类型和模式,具有很好的向前扩展与向后兼容的能力。

Kafka中数据是连续的,在数据在写入到同时也可能被读取消费,这样数据的格式就很重要了。如果数据的格式发生变化,消费的应用也需要做出适当的调整。如果事先定义好了数据存储的格式,那么读取数据的时候就不需要做特殊的处理了。

Topics和Partitions

消息都是以主题Topic的方式组织在一起,Topic也可以理解成传统数据库里的表,或者文件系统里的一个目录。一个主题由broker上的一个或者多个Partition分区组成。在Kafka中数据是以Log的方式存储,一个partition就是一个单独的Log。消息通过追加的方式写入日志文件,读取的时候则是从头开始按照顺序读取。注意,一个主题通常都是由多个分区组成的,每个分区内部保证消息的顺序行,分区之间是不保证顺序的。如果你想要kafka中的数据按照时间的先后顺序进行存储,那么可以设置分区数为1。如下图所示,一个主题由4个分区组成,数据都以追加的方式写入这四个文件。分区的方式为Kafka提供了良好的扩展性,每个分区都可以放在独立的服务器上,这样就相当于主题可以在多个机器间水平扩展,相对于单独的服务器,性能更好。


在Kafka这种数据系统中经常会提起stream流这个词,通常流被认为是一个主题中的数据,而忽略分区的概念。这就意味着数据流就是从producer到consumer。在很多框架中,比如kafka stream,apache samza,storm在操作实时数据的时候,都是这样理解数据流的。这种操作的模式跟离线系统处理数据的方式不同,如hadoop,是在某一个固定的时间处理一批的数据。

Producer和Consumer
Kafka中主要有两种使用者:Producer和consumer。

Producer用来创建消息。在发布订阅系统中,他们也被叫做Publisher发布者或writer写作者。通常情况下,消息都会进入特定的主题。默认情况下,生产者不关系消息到底进入哪个分区,它会自动在多个分区间负载均衡。也有的时候,消息会进入特定的一个分区中。一般都是通过消息的key使用哈希的方式确定它进入哪一个分区。这就意味着如果所有的消息都给定相同的key,那么他们最终会进入同一个分区。生产者也可以使用自定义的分区器,这样消息可以进入特定的分区。

Consumer读取消息。在发布订阅系统中,也叫做subscriber订阅者或者reader阅读者。消费者订阅一个或者多个主题,然后按照顺序读取主题中的数据。消费者需要记录已经读取到消息的位置,这个位置也被叫做offset。每个消息在给定的分区中只有唯一固定的offset。通过存储最后消费的Offset,消费者应用在重启或者停止之后,还可以继续从之前的位置读取。保存的机制可以是zookeeper,或者kafka自己。

消费者是以consumer group消费者组的方式工作,由一个或者多个消费者组成一个组,共同消费一个topic。每个分区在同一时间只能由group中的一个消费者读取,在下图中,有一个由三个消费者组成的grouop,有一个消费者读取主题中的两个分区,另外两个分别读取一个分区。某个消费者读取某个分区,也可以叫做某个消费者是某个分区的拥有者。

在这种情况下,消费者可以通过水平扩展的方式同时读取大量的消息。另外,如果一个消费者失败了,那么其他的group成员会自动负载均衡读取之前失败的消费者读取的分区。

Brokers和Clusters
单独的kafka服务器也叫做broker,Broker从生产者那里获取消息,分配offset,然后提交存储到磁盘年。他也会提供消费者,让消费者读取分区上的消息,并把存储的消息传给消费者。依赖于一些精简资源,单独的broker也可以轻松的支持每秒数千个分区和百万级的消息。

Kafka的broker支持集群模式,在Broker组成的集群中,有一个节点也被叫做控制器(是在活跃的节点中自动选择的)。这个controller控制器负责管理整个集群的操作,包括分区的分配、失败节点的检测等。一个partition只能出现在一个broker节点上,并且这个Broker也被叫做分区的leader。一个分区可以分配多个Broker,这样可以做到多个机器之间备份的效果。这种多机备份在其中一个broker失败的时候,可以自动选举出其他的broker提供服务。然而,producer和consumer都必须连接leader才能正常工作。



Kafka的一个重要特性就是支持数据的过期删除,数据可以在Broker上保留一段时间。Kafka的broker支持针对topic设置保存的机制,可以按照大小配置也可以按照时间配置。一旦达到其中的一个限制,可能是时间过期也可能是大小超过配置的数值,那么这部分的数据都会被清除掉。每个topic都可以配置它自己的过期配置,因此消息可以按照业务的需要进行持久化保留。比如,一个数据追踪分析的topic可以保留几天时间,一些应用的指标信息则只需要保存几个小时。topic支持日志数据的压缩,这样kafka仅仅会保留最后一条日志生成的key。这在修改日志类型的时候会非常有用。

Multiple Cluster
随着Kafka部署环境的演变,有时候需要莉利用多集群的优势。使用多集群的原因如下:
1 不同类型数据的分离
2 安全隔离
3 多数据中心(灾备)
在使用多数据中心的时候,需要很清楚的理解消息是如何在她们之间传递的。一般情况下,用户可以在多个对外提供服务的网址,产生一些前端数据,然后利用kafka把他们统一的汇总到一起,进行分析监控告警。这种备份的机制一般都是应用于单个集群,而不是多集群。

Kafka项目提供了一个叫做mirro maker的工具,它支持多机房的数据传输。它其实就是一个基于queu连接的consumer和producer。消息从kafka中消费,然后传输给另一个集群的kafka。如下图所示,就是使用mirror maker的一个例子,消息在两个集群的本地聚合,然后再传输给另一个集群进行分析。由于kafka设计的精简,可以在多机房中实现这种简单的管道处理机制。





1.kafka在大数据生态系统中的角色是什么?
2.kafka有哪些使用场景?
The Data Ecosystem 数据生态系统

许多的应用参与到我们所构建的处理数据的环境中。 我们定义了输入–产生数据或者引入数据到系统应用。 我们定义了输出–统计指标, 报告, 或者其他数据产品。 我们创造了回路, 一些组件从系统中读取数据,进行一些处理,然后将其回写到数据基础设施中, 以便后续其他地方处理。无数的内容,大小,用途不同的数据通过这套流程进行处理。

如图1-9所示, Apache Kafka为这个数据生态系统提供了循环系统。Kafka传输来自各个基础设施的消息, 为所有的客户端提供一致的接口。 因为引入了消息队列模式, producer和consumer就不再耦合, 之间也没有任何的直接连接。 组件能够随着业务的增加和融合而添加或移除, producer不需要关心谁在使用数据, 有多少consumer在使用数据。 

图1-9 大数据生态系统

                                                
Use Cases  用例Activity Tracking 行为追踪
Kafka最初的用途是用户行为追踪。 无论用户在前端进行什么交互操作都会产生消息以及行为记录。 这写信息可以是被动信息, 比如浏览页面和点击的追踪, 也可以是更加复杂的行为, 比如为用户资料添加信息。 这些message被发布到一个或多个topic, 随后被后端的消费者消费。以这种方式, 我们生成报表, 为机器学习系统提供数据源, 更新搜索结果, 以及无数其他的用途。

Messaging 消息传输
kafka的另外一个基本用途就是消息传输。 当一个应用把需要发送给用户的通知(例如邮件消息)发送给用户。 这些组件可以生产消息, 而不需要关注消息格式和消息将如何被发送。 一个通用的应用能够读取所有需要被发送的消息, 并且执行格式化, 选择如何发送它们。 通过使用一个通用组件, 不仅仅是减少了不同系统中的重复功能, 而且还能做一些有意思的转换功能, 比如聚集多条消息一次发送。

Metrics and Logging 指标和日志
Kafka同样是理想的处理应用和系统指标、日志的工具。可以用于多个生产者生产同一种类型的消息。应用定期发送它们的操作指标数据到kafka的topic中, 这些数据可以被用于系统监控和报警。 同样也可以被用于像hadoop这样的系统进行长周期的分析, 比如项目的年增长。日志消息能够以同样的方式进行发送, 能够被路由至专门的日志分析系统,比如Elasticsearch或者安全分析应用。 kafka提供了便利, 当目标系统需要改变时( 比我们要升级日志存储系统), 无需修改前端应用以及日志的聚合方式。

Commit Log 提交日志
Kafka是基于提交日志的思想来构建的, 自然可以以这种方式来使用kafka。 数据库更改可以发送到kafka, 应用可以监控这个流来接收实时更新。 这个changelog流同样也可以用于复制数据库更新到远程系统。或者合并多个应用的更新到单一的数据库视图。持久化的保存也为changelog提供了缓存, 意味着如果消费应用失败的话, changelog可以进行事件重放。另外,日志压缩的topic还能为日志提供更长的保留时间, 如果对于每个key只保留最新一个更新的话。

Stream Processing 流处理
另一方面,它提供了许多类型的应用程序流处理。 可以认为是提供了Hadoop的map/reduce处理类似的功能,但是Hadoop通常依赖于一个大的时间窗口的聚集数据, 几小时或几天, 然后以批处理的方式处理数据, 而流处理以实时的方式处理流。流处理框架允许用户写一个小应用来对kafka message进行操作, 执行诸如计数, 对message进行分区让其他应用更有效的处理, 或者转换来自多个源的数据。 Stream处理学习在第10章中单独讲解。









原创粉丝点击