1、kafka的由来。
Kafka的诞生,是为了解决linkedin的数据管道问题,期初linkedin采用了ActiveMQ
来进行数据交换,大约在2010年前后,那时的ActiveMQ还远远无法满足linkedin对数
据传递系统的要求,经常由于各种缺陷而导致消息阻塞或者服务无法正常访问,为了能
够解决这个问题,
linkedin决定研发自己的消息传递系统。当时由linkedin的首席架构师
jay kreps开始组织团队进行消息传递系统的研发。
Apache Kafka是一个分布式的基于push-subscribe的消息系统,它具备快速、可扩
展、可持久化的特点。它现在是Apache旗下的一个开源系统,作为Hadoop生态系统的
一部分,被各种商业公司广泛应用。它的最大的特性就是可以实时地处理大量数据以满
足各种需求场景。比如基于Hadoop的批处理系统、低延迟的实时系统、Storm或Spark
流式处理引擎。
1-1、 kafka的特性
Kafka的特性
(1)高吞吐量、低延迟:Kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒。
(2)可扩展性:Kafka集群支持热扩展。
(3)持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失。
(4)容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)。
(5)高并发:支持数千个客户端同时读写。
2、kafka的重要设计思路 思想。
从Kafka的主要设计思想中,可以让相关人员在短时间内了解到Kafka相关特性。
Consumergroup:各个Consumer可以组成一个组,每个消息只能被组中的一个Consumer消
费,如果一个消息可以被多个Consumer消费的话,那么这些Consumer必须在不同的组。
消息状态:在Kafka中,消息的状态被保存在Consumer中,broker不会关心哪个消息被消费了
且被谁消费了,它只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着
如果Consumer处理不好的话,broker上的一个消息可能会被消费多次。
消息持久化:Kafka中会把消息持久化到本地文件系统中,并且保持极高的效率。
消息有效期:Kafka会长久保留其中的消息,以便Consumer可以多次消费,当然其中很多细节
是可配置的。
从Kafka的主要设计思想中,可以让相关人员在短时间内了解到Kafka相关特性。
批量发送:Kafka支持以消息集合为单位进行批量发送,以提高push效率。
push-and-pull:Kafka中的Producer和Consumer采用的是push-and-pull模式,即Producer
只管向broker push消息,Consumer只管从broker pull消息,两者对消息的生产和消费是异步的。
Kafka集群中broker之间的关系:不是主从关系,各个broker在集群中地位一样,用户可以随
意地增加或删除任何一个broker节点。
负载均衡方面:Kafka提供了一个metadata API来管理broker之间的负载(此方式仅对 Kafka
0.8.x版本而言,对于0.7.x版本主要靠ZooKeeper来实现负载均衡)。
同步异步:Producer采用异步push方式,极大提高Kafka系统的吞吐率(可以通过参数控制是采
用同步还是异步方式)。
分区机制partition:Kafka的broker端支持消息分区,Producer可以决定把消息发到哪个分区,
在一个分区中消息的顺序就是Producer发送消息的顺序,一个主题中可以有多个分区,具体分区的数
量是可配置的。分区的意义很重大,后面的内容会逐渐体现。
离线数据装载:Kafka由于对可拓展的数据持久化的支持,它也非常适合向Hadoop或者数据仓库
中进行数据装载。
插件支持:现在不少活跃的社区已经开发出不少插件来拓展Kafka的功能,例如用来配合Storm、
Hadoop、flume相关的插件。
3、kafka应用场景
(1)日志收集:公司用Kafka可以收集各种服务的log,通过Kafka以统一接口服务的方式
开放给各种Consumer,例如Hadoop、HBase、Solr等。
(2)消息系统:解耦、生产者和消费者、缓存消息等。
(3)用户活动跟踪:Kafka经常被用来记录Web用户或者App用户的各种活动,如浏览网
页、搜索、点击等活动,这些活动信息被各个服务器发布到Kafka的topic中,然后订阅者通
过订阅这些topic来做实时的监控分析,或者装载到Hadoop、数据仓库中做离线分析和挖掘。
(4)运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据、
生产各种操作的集中反馈,比如报警和报告。
(5)流式处理:比如Spark streaming和Storm。
4、kafka架构组件
Kafka中发布订阅的对象是topic。用户可以为每类数据创建一个topic,把向topic发布消息的客户端称
作producer,从topic订阅消息的客户端称作Consumer。Producers和Consumers可以同时从多个topic
读写数据。一个Kafka集群由一个或多个broker服务器组成,它负责持久化和备份具体的kafka消息。
topic:消息存放的目录即主题。
Producer:生产消息到topic的一方。
Consumer:订阅topic消费消息的一方。
Broker:Kafka的服务实例就是一个broker。
5、 kafka Topic&Partition
消息发送时都被发送到一个topic,其本质就是一个目录,而topic由是由一些Partition Logs(分区日 志)组成的,其组织结构如图所示。
可以看到,每个Partition中的消息都是有序的,生产的消息被不断追加到Partition log上,其中的每
一个消息都被赋予了一个唯一的offset值。
Kafka集群会保存所有的消息,不管消息有没有被消费。用户可以设定消息的过期时间,只有过期的数
据才会被自动清除以释放磁盘空间。比如,设置消息过期时间为2天,那么这2天内的所有消息都会被保存
到集群中,数据只有超过了两天才会被清除。
Kafka需要维持的元数据只要一个消费消息在Partition中的offset值,Consumer每消费一个消息,
offset就会加1。其实消息的状态完全是由Consumer控制的,Consumer可以跟踪和重设这个offset值,这
样的话Consumer就可以读取任意位置的消息了。
把消息日志以Partition的形式存放有多重考虑。第一,方便在集群中扩展,每个Partition可以通过调
整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数
据了;第二,就是可以提高并发,因为可以以Partition为单位读写。
6、kafka的核心组。
1. Replications、Partitions和Leaders
Kafka中的数据是持久化的并且能够容错的。Kafka允许用户为每个topic设置副本数量,副本数量决定
了有几个broker来存放写入的数据。如果用户的副本数量设置为3,那么一份数据就会被存放在3台不同的
机器上,就可以允许有2个机器失败。一般推荐副本数量至少为2,这样就可以保证增减、重启机器时不会
影响到数据消费。如果对数据持久化有更高的要求,可以把副本数量设置为3或者更多。
Kafka中的topic是以Partition的形式存放的,每一个topic都可以设置它的Partition数量,Partition的
数量决定了组成topic的log的数量。Producer在生产数据时,会按照一定规则(这个规则是可以自定义的)
把消息发布到topic的各个Partition中。上面讲的副本都是以Partition为单位的,不过只有一个Partition的
副本会被选举成Leader作为读写用。
6-1、
关于如何设置Partition值需要考虑以下2个因素:
(1)一个Partition只能被一个消费者消费(一个消费者可以同时消费多个Partition),因此,如果设
置的Partition的数量小于Consumer的数量,就会有消费者消费不到数据。所以,推荐Partition的数量一定
要大于同时运行的Consumer的数量。
(2)建议Partition的数量大于集群broker的数量,这样Leader Partition就可以均匀地分布在各个
broker中,最终使得集群负载均衡。在云服务器,每个topic都有上百个Partition。需要注意的是,Kafka需
要为每个Partition分配一些内存来缓存消息数据,如果Partition数量特别大,就要为Kafka分配更大的
Heap Space。
6-2、producers
2. Producers
Producers直接发送消息到broker上的Leader Partition,不需要经过任何中间一系列的路由转发。为
了实现这个特性,Kafka集群中的每个broker都可以响应Producer的请求,并返回topic的一些元信息,这
些元信息包括哪些机器是存活的、topic的Leader Partition都在哪、现阶段哪些Leader Partition是可以直
接被访问的。
Producer客户端自己控制着消息被推送到哪些Partition。实现的方式可以是随机分配、实现一类随机
负载均衡算法或者指定一些分区算法。Kafka提供了接口供用户实现自定义的分区,用户可以为每个消息指
定一个partitionKey,通过这个key来实现一些hash分区算法。比如,把userid作为partitionkey的话,相
同userid的消息将会被推送到同一个分区。
Producers可以异步并行地向Kafka发送消息,但是通常Producer在发送完消息之后会得到一个future
响应,返回的是offset值或者发送过程中遇到的错误。这其中有个非常重要的参数“
acks”,这个参数决定
了Producer要求Leader Partition收到确认的副本个数。
6-3、consumers
3. Consumers
Kafka提供了两套Consumer API,分为High-level API和Sample-api。Sample-api是一个
底层的API,它维持了一个和单一broker 的连接,并且这个API是完全无状态的,每次请求都需
要指定offset值,因此,这套API也是最灵活的。
在Kafka中,当前读到消息的offset值是由Consumer来维护的,因此,Consumer可以自己
决定如何读取Kafka中的数据。比如,Consumer可以通过重设offset值来重新消费已消费过的数
据。不管有没有被消费,Kafka会保存数据一段时间,这个时间周期是可配置的,只有到了过期
时间,Kafka才会删除这些数据。
6-4kafka的核心组。
High-level API封装了对集群中一系列broker的访问,可以透明地消费一个topic。它自己维
持了已消费消息的状态,即每次消费的都是下一个消息。
High-level API还支持以组的形式消费topic,如果Consumers有同一个组名,那么Kafka就
相当于一个队列消息服务,而各个Consumer均衡地消费相应Partition中的数据。若Consumers
有不同的组名,那么此时Kafka就相当与一个广播服务,会把topic中的所有消息广播到每个
Consumer。