一、Kafka 简介
Kafka 是 linkedin 使用 Scala 编写具有高水平扩展和高吞吐量的分布式消息系统。
Kafka 对消息保存时根据 Topic 进行归类,发送消息者成为 Producer ,消息接受者成为 Consumer ,此外 kafka 集群有多个 kafka 实例组成,每个实例(server)称为 broker。
无论是 Kafka集群,还是 producer 和 consumer 都依赖于 zookeeper 来保证系统可用性,为集群保存一些 meta 信息。
二、mq 对比
属性 分类 | ActiveMQ | RabbitMQ | Kafka |
---|---|---|---|
所属社区/公司 | Apache | Mozilla Public License | Apache/LinkedIn |
开发语言 | Java | Erlang | Scala |
支持的协议 | OpenWire、STOMP、 REST、XMPP、AMQP | AMQP | 仿AMQP |
事务 | 支持 | 不支持 | 0.11 开始支持 |
集群 | 支持(不擅长) | 支持(不擅长) | 支持 |
负载均衡 | 支持 | 支持 | 支持 |
动态扩容 | 不支持 | 不支持 | 支持(zk) |
三、kafa 主要功能
Apache Kafka® 是 一个分布式流处理平台
3.1流处理平台特性
- 可以让你发布和订阅流式的记录。这一方面与消息队列或者企业消息系统类似。
- 可以储存流式的记录,并且有较好的容错性。
- 可以在流式记录产生时就进行处理。
3.2 Kafka 适合什么样的场景?
- 构造实时流数据管道,它可以在系统或应用之间可靠地获取数据。 (相当于消息队列)
- 构建实时流式应用程序,对这些流数据进行转换或者影响。
四、kafa相关概念
首先我们要了解一些重要概念。
- kafka作为一个集群运行在一个或多个服务器上
- Kafka 通过 topic 对存储的流数据进行分类
- 每条记录中包含一个 key ,一个 value 和一个 timestamp(时间戳)
4.1 AMQP
AMQP (Advanced Message Queuing Protocol) ,是一个提供统一消息服务的标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件而设计。
一些基本的概念:
- AMQP服务器端(broker):用来接收生产者发送的消息并将这些消息路由给服务器中的队列
- 消费者(Consumer):从消息队列中请求消息的客户端应用程序
- 生产者(Producer):向 broker 发布消息的客户端应用程序
4.2 Topics 和 Logs
Topic 就是数据主题,是数据记录发布的地方,可以用来区分业务系统。Kafka 中的 Topics 总是多订阅者模式,一个 topic 可以拥有一个或者多个消费者来订阅它的数据。
对于每一个topic,Kafka集群都会维持一个分区日志,如图所示:
4.3 Partition
每一个分区都是一个顺序的、不可变的消息队列, 并且可以持续的添加。分区中的消息都被分了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。
Kafka 集群保持所有的消息,直到它们过期, 无论消息是否被消费了。 实际上消费者所持有的仅有的元数据就是这个偏移量,也就是消费者在这个 log 中的位置。 这个偏移量由消费者控制:正常情况当消费者消费消息的时候,偏移量也线性的的增加。但是实际偏移量由消费者控制,消费者可以将偏移量重置为更老的一个偏移量,重新读取消息。 可以看到这种设计对消费者来说操作自如, 一个消费者的操作不会影响其它消费者对此 log 的处理。
kafka 并没有提供其他额外的索引机制来存储 offset,因为在 kafka 中几乎不允许对消息进行“随机读写”。
Kafka中采用分区的设计有一下的目的:
- 可以处理更多的消息,不受单台服务器的限制。Topic拥有多个分区意味着它可以不受限的处理更多的数据。
- 分区可以作为并行处理的单元
4.4 Distribution
Log 的分区被分布到集群中的多个服务器上,每个服务器处理它分到的分区, 根据配置每个分区还可以复制到其它服务器作为备份容错。
每个分区有一个 leader,零或多个 follower。Leader 处理此分区的所有的读写请求,而 follower 被动的复制数据。如果 leader 宕机,其它的一个 follower 会被推举为新的 leader。 一台服务器可能同时是一个分区的 leader,另一个分区的 follower。 这样可以平衡负载,避免所有的请求都只让一台或者某几台服务器处理。
4.5 Producers
生产者往某个 Topic 上发布消息,生产者也负责选择发布到Topic上的哪一个分区。最简单的方式从分区列表中轮流选择,也可以根据某种算法依照权重选择分区。开发者负责如何选择分区的算法。
4.6 Consumers
消费者使用一个消费组名称来进行标识,发布到 topic 中的每条记录被分配给订阅消费组中的一个消费者实例。消费者实例可以分布在多个进程中或者多个机器上。
- 如果所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例。
- 如果所有的消费者实例在不同的消费组中,每条消息记录会广播到所有的消费者进程。
如图,这个 Kafka 集群有两台 server 的,四个分区(p0-p3)和两个消费者组。消费组A有两个消费者,消费组B有四个消费者。
通常情况下,每个 topic 都会有一些消费组,一个消费组对应一个”逻辑订阅者”。一个消费组由许多消费者实例组成,便于扩展和容错。这就是发布和订阅的概念,只不过订阅者是一组消费者而不是单个的进程。
在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便在任何时间,每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例。
Kafka 只保证分区内的记录是有序的,而不保证主题中不同分区的顺序。每个 partition 分区按照key值排序足以满足大多数应用程序的需求。但如果你需要总记录在所有记录的上面,可使用仅有一个分区的主题来实现,这意味着每个消费者组只有一个消费者进程。
4.6 Replication
每个partition还会被复制到其它服务器作为 replication ,这是一种冗余备份策略
- 同一个 partition 的多个 replication 不允许在同一 broker 上
- 每个partition的replication中,有一个 leader ,零或多个 follower
- leader 处理此分区的所有的读写请求, follower 仅仅被动的复制数据
- leader 宕机后,会从 follower 中选举出新的 leader
4.7 四个核心 API
- Producer API:允许一个应用程序发布一串流式的数据到一个或者多个 Kafka topic。
- Consumer API:允许一个应用程序订阅一个或多个 topic ,并且对发布给他们的流式数据进行处理。
- Streams API:允许一个应用程序作为一个流处理器,消费一个或者多个 topic 产生的输入流,然后生产一个输出流到一个或多个 topic 中去,在输入输出流中进行有效的转换。
- Connector API:允许构建并运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。
在Kafka中,客户端和服务器之间的通信是通过简单,高性能,语言无关的TCP协议完成的。此协议已版本化并保持与旧版本的向后兼容性。Kafka提供多种语言客户端。
4.8 kafka API – producer
- Producer 会为每个 partition 维护一个缓冲,用来记录还没有发送的数据,每个缓冲区大小用 batch.size 指定,默认值为16k.
- linger.ms 为,buffer中的数据在达到 batch.size 前,需要等待的时间
- acks用来配置请求成功的标准
4.9 kafka API – consumer
4.9.1 Kafka Simple Consumer
Simple Cnsumer 位于kafka.javaapi.consumer包中,不提供负载均衡、容错的特性。每次获取数据都要指定topic、partition、offset、fetchSize
4.9.2 High-level Consumer
该客户端透明地处理kafka broker异常,透明地切换consumer的partition,通过和broker交互来实现consumer group级别的负载均衡。
如图,这个 Kafka 集群有两台 server 的,四个分区(p0-p3)和两个消费者组。消费组A有两个消费者,消费组B有四个消费者。
通常情况下,每个 topic 都会有一些消费组,一个消费组对应一个”逻辑订阅者”。一个消费组由许多消费者实例组成,便于扩展和容错。这就是发布和订阅的概念,只不过订阅者是一组消费者而不是单个的进程。
在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便在任何时间,每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例。
Kafka 只保证分区内的记录是有序的,而不保证主题中不同分区的顺序。每个 partition 分区按照key值排序足以满足大多数应用程序的需求。但如果你需要总记录在所有记录的上面,可使用仅有一个分区的主题来实现,这意味着每个消费者组只有一个消费者进程。
五、kafa整体架构
六、kafka应用场景
6.1 消息
kafka 更好的替换传统的消息系统,消息系统被用于各种场景(解耦数据生产者,缓存未处理的消息),与大多数消息系统比较,kafka 有更好的吞吐量,内置分区,副本和故障转移等功能,这有利于处理大规模的消息。
根据官方的经验,通常消息传递使用较低的吞吐量,但可能要求较低的端到端延迟,kafka 提供强大的持久性来满足这一要求。在这方面,Kafka 可以与传统的消息传递系统(ActiveMQ 和 RabbitMQ)相媲美。
6.2 跟踪网站活动
kafka 的最初始作用就是是将用户活动跟踪管道重建为一组实时发布-订阅源。 把网站活动(浏览网页、搜索或其他的用户操作)发布到中心 topic,其中每个活动类型有一个 topic。 这些订阅源提供一系列用例,包括实时处理、实时监视、对加载到Hadoop或离线数据仓库系统的数据进行离线处理和报告等。
每个用户浏览网页时都生成了许多活动信息,因此活动跟踪的数据量通常非常大。这就非常使用使用 kafka。
6.3 日志聚合
许多人使用 kafka来替代日志聚合解决方案。
日志聚合系统通常从服务器收集物理日志文件,并将其置于一个中心系统(可能是文件服务器或HDFS)进行处理。
kafka 从这些日志文件中提取信息,并将其抽象为一个更加清晰的消息流。 这样可以实现更低的延迟处理且易于支持多个数据源及分布式数据的消耗。
与 Scribe 或 Flume 等以日志为中心的系统相比,Kafka具备同样出色的性能、更强的耐用性(因为复制功能)和更低的端到端延迟。
6.4 流处理
从0.10.0.0开始,kafka 支持轻量,但功能强大的流处理。
kafka 消息处理包含多个阶段。其中原始输入数据是从 kafka 主题消费的,然后汇总,丰富,或者以其他的方式处理转化为新主题以供进一步消费或后续处理。
例如,一个推荐新闻文章,文章内容可能从articles
主题获取;然后进一步处理内容,得到一个处理后的新内容,最后推荐给用户。这种处理是基于单个主题的实时数据流。
除了 Kafka Streams,还有 Apache Storm 和 Apache Samza 也是不错的流处理框架。
6.5 事件采集
Event sourcing是一种应用程序设计风格,按时间来记录状态的更改。 Kafka 可以存储非常多的日志数据,为基于 event sourcing 的应用程序提供强有力的支持。
6.6 提交日志
容,最后推荐给用户。这种处理是基于单个主题的实时数据流。
除了 Kafka Streams,还有 Apache Storm 和 Apache Samza 也是不错的流处理框架。
6.5 事件采集
Event sourcing是一种应用程序设计风格,按时间来记录状态的更改。 Kafka 可以存储非常多的日志数据,为基于 event sourcing 的应用程序提供强有力的支持。
6.6 提交日志
kafka 可以从外部为分布式系统提供日志提交功能。 日志有助于记录节点和行为间的数据,采用重新同步机制可以从失败节点恢复数据。 Kafka 的日志压缩 功能支持这一用法。 这一点与 Apache BookKeeper 项目类似。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/181965.html原文链接:https://javaforall.cn