Kafka剖析(一):Kafka背景及架构介绍

上传人:woxinch****an2018 文档编号:42951344 上传时间:2018-06-04 格式:DOCX 页数:13 大小:1.53MB
返回 下载 相关 举报
Kafka剖析(一):Kafka背景及架构介绍_第1页
第1页 / 共13页
Kafka剖析(一):Kafka背景及架构介绍_第2页
第2页 / 共13页
Kafka剖析(一):Kafka背景及架构介绍_第3页
第3页 / 共13页
Kafka剖析(一):Kafka背景及架构介绍_第4页
第4页 / 共13页
Kafka剖析(一):Kafka背景及架构介绍_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《Kafka剖析(一):Kafka背景及架构介绍》由会员分享,可在线阅读,更多相关《Kafka剖析(一):Kafka背景及架构介绍(13页珍藏版)》请在金锄头文库上搜索。

1、Kafka 剖析(一):剖析(一):Kafka 背景及架构介绍背景及架构介绍Kafka 是由 LinkedIn 开发的一个分布式的消息系统,使用 Scala 编写,它以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如 Cloudera、Apache Storm、Spark 都支持与 Kafka 集成。InfoQ 一直在紧密关注 Kafka 的应用以及发展, “Kafka 剖析”专栏将会从架构设计、实现、应用场景、性能等方面深度解析 Kafka。背景介绍Kafka 创建背景Kafka 是一个消息系统,原本开发自 LinkedIn,用作 LinkedIn 的活动流(Activi

2、ty Stream)和运营数据处理管道(Pipeline)的基础。现在它已被多家不同类型的公司 作为 多种类型的数据管道和消息系统使用。 活动流数据是几乎所有站点在对其网站使用情况做报表时都要用到的数据中最常规的部分。 活动数据包括页面访问量(Page View)、被查看内容方面的信息以及搜索情况等内容。 这种数据通常的处理方式是先把各种活动以日志的形式写入某种文件,然后周期性地对这 些文件进行统计分析。运营数据指的是服务器的性能数据(CPU、IO 使用率、请求时间、 服务日志等等数据)。运营数据的统计方法种类繁多。近年来,活动和运营数据处理已经成为了网站软件产品特性中一个至关重要的组成部分,

3、 这就需要一套稍微更加复杂的基础设施对其提供支持。Kafka 简介Kafka 是一种分布式的,基于发布/订阅的消息系统。主要设计目标如下:以时间复杂度为 O(1)的方式提供消息持久化能力,即使对 TB 级以上数据也能保证常数时间复杂度的访问性能。高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒 100K 条以上消息的 传输。支持 Kafka Server 间的消息分区,及分布式消费,同时保证每个 Partition 内的消息顺 序传输。同时支持离线数据处理和实时数据处理。Scale out:支持在线水平扩展。为何使用消息系统解耦解耦 在项目启动之初来预测将来项目会碰到什么需求,是极其困

4、难的。消息系统在处理过 程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。 这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。冗余冗余有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队 列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。 许多消息队列所采用的“插入-获取-删除“范式中,在把一个消息从队列中删除之前,需 要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存 直到你使用完毕。扩展性扩展性 因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只 要另

5、外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按 钮一样简单。灵活性灵活性 import kafka.utils.VerifiableProperties;public class JasonPartitioner implements Partitioner public JasonPartitioner(VerifiableProperties verifiableProperties) Overridepublic int partition(Object key, int numPartitions) try int partitionNum = Integer.

6、parseInt(String) key);return Math.abs(Integer.parseInt(String) key) % numPartitions); catch (Exception e) return Math.abs(key.hashCode() % numPartitions);如果将上例中的类作为 partition.class,并通过如下代码发送 20 条消息(key 分别为 0,1,2,3)至 topic3(包含 4 个 Partition)。public void sendMessage() throws InterruptedExceptionfor(in

7、t i = 1; i ();for(int j = 0; j (“topic2“, j+“, “The “ + i + “ message for key “ + j);producer.send(messageList);producer.close();则 key 相同的消息会被发送并存储到同一个 partition 里,而且 key 的序号正好和 Partition 序号相同。(Partition 序号从 0 开始,本例中的 key 也从 0 开始)。下图所示是通过 Java 程序调用 Consumer 后打印出的消息列表。Consumer Group(本节所有描述都是基于 Consum

8、er hight level API 而非 low level API)。使用 Consumer high level API 时,同一 Topic 的一条消息只能被同一个 Consumer Group 内的一个 Consumer 消费,但多个 Consumer Group 可同时消费这一消息。这是 Kafka 用来实现一个 Topic 消息的广播(发给所有的 Consumer)和单播(发给某一 个 Consumer)的手段。一个 Topic 可以对应多个 Consumer Group。如果需要实现广播, 只要每个 Consumer 有一个独立的 Group 就可以了。要实现单播只要所有的 C

9、onsumer 在 同一个 Group 里。用 Consumer Group 还可以将 Consumer 进行自由的分组而不需要多 次发送消息到不同的 Topic。实际上,Kafka 的设计理念之一就是同时提供离线处理和实时处理。根据这一特性,可以 使用 Storm 这种实时流处理系统对消息进行实时在线处理,同时使用 Hadoop 这种批处理 系统进行离线处理,还可以同时将数据实时备份到另一个数据中心,只需要保证这三个操 作所使用的 Consumer 属于不同的 Consumer Group 即可。下图是 Kafka 在 Linkedin 的 一种简化部署示意图。下面这个例子更清晰地展示了 K

10、afka Consumer Group 的特性。首先创建一个 Topic (名为 topic1,包含 3 个 Partition),然后创建一个属于 group1 的 Consumer 实例,并创建三个 属于 group2 的 Consumer 实例,最后通过 Producer 向 topic1 发送 key 分别为 1,2,3 的消息。结果发现属于 group1 的 Consumer 收到了所有的这三条消息,同时 group2 中的 3 个 Consumer 分别收到了 key 为 1,2,3 的消息。如下图所示。Push vs. Pull作为一个消息系统,Kafka 遵循了传统的方式,选择

11、由 Producer 向 broker push 消息并由 Consumer 从 broker pull 消息。一些 logging-centric system,比如 Facebook 的 Scribe 和 Cloudera 的 Flume,采用 push 模式。事实上,push 模式和 pull 模式各有优劣。 push 模式很难适应消费速率不同的消费者,因为消息发送速率是由 broker 决定的。push 模式的目标是尽可能以最快速度传递消息,但是这样很容易造成 Consumer 来不及处理消 息,典型的表现就是拒绝服务以及网络拥塞。而 pull 模式则可以根据 Consumer 的消费

12、能 力以适当的速率消费消息。对于 Kafka 而言,pull 模式更合适。pull 模式可简化 broker 的设计,Consumer 可自主控 制消费消息的速率,同时 Consumer 可以自己控制消费方式即可批量消费也可逐条消 费,同时还能选择不同的提交方式从而实现不同的传输语义。Kafka delivery guarantee有这么几种可能的 delivery guarantee:At most once 消息可能会丢,但绝不会重复传输At least one 消息绝不会丢,但可能会重复传输 Exactly once 每条消息肯定会被传输一次且仅传输一次,很多时候这是用户所想要的。当 P

13、roducer 向 broker 发送消息时,一旦这条消息被 commit,因数 replication 的存在, 它就不会丢。但是如果 Producer 发送数据给 broker 后,遇到网络问题而造成通信中 断,那 Producer 就无法判断该条消息是否已经 commit。虽然 Kafka 无法确定网络故 障期间发生了什么,但是 Producer 可以生成一种类似于主键的东西,发生故障时幂等性的重试多次,这样就做到了 Exactly once。截止到目前(Kafka 0.8.2 版本,2015-03- 04),这一 Feature 还并未实现,有希望在 Kafka 未来的版本中实现。(所

14、以目前默认 情况下一条消息从 Producer 到 broker 是确保了 At least once,可通过设置 Producer 异步发送实现 At most once)。接下来讨论的是消息从 broker 到 Consumer 的 delivery guarantee 语义。(仅针对 Kafka consumer high level API)。Consumer 在从 broker 读取消息后,可以选择 commit,该操作会在 Zookeeper 中保存该 Consumer 在该 Partition 中读取的消息的 offset。该 Consumer 下一次再读该 Partition

15、时会从下一条开始读取。如未 commit, 下一次读取的开始位置会跟上一次 commit 之后的开始位置相同。当然可以将 Consumer 设置为 autocommit,即 Consumer 一旦读到数据立即自动 commit。如果 只讨论这一读取消息的过程,那 Kafka 是确保了 Exactly once。但实际使用中应用程 序并非在 Consumer 读取完数据就结束了,而是要进行进一步处理,而数据处理与 commit 的顺序在很大程度上决定了消息从 broker 和 consumer 的 delivery guarantee semantic。读完消息先 commit 再处理消息。这种

16、模式下,如果 Consumer 在 commit 后还没来得 及处理消息就 crash 了,下次重新开始工作后就无法读到刚刚已提交而未处理的消息, 这就对应于 At most once读完消息先处理再 commit。这种模式下,如果在处理完消息之后 commit 之前 Consumer crash 了,下次重新开始工作时还会处理刚刚未 commit 的消息,实际上该 消息已经被处理过了。这就对应于 At least once。在很多使用场景下,消息都有一个 主键,所以消息的处理往往具有幂等性,即多次处理这一条消息跟只处理一次是等效 的,那就可以认为是 Exactly once。(笔者认为这种说法比较牵强,毕竟它不是 Kafka 本身提供的机制,主键本身也并不能完全保证操作的幂等性。而且实际上我们说 delivery guarantee 语义是讨论被处理多少次,而非处理结果怎样,因为处理方式多种 多样,我们不应该把处理过程的特性如是否幂等性,当成 Kafka 本身的 Feature)如果一定要做到

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号