初识Kafka

发布于:2023-01-08 ⋅ 阅读:(559) ⋅ 点赞:(0)

LinkedIn
领英是全球领先的职业社交网站,全球会员总数近 7.74 亿,覆盖全球 200 多个国家和地区。主要用于处理网站每天产生的大量用户行为数据而研发的产品。

背景

Kafka是由LinkedIn开发并开源的分布式消息系统,后开源捐给Apache。

Kafka介绍

Kafka是一种分布式的,基于发布/订阅的消息系统。
主要设计目标如下:
以时间复杂度为O(1)的方式提供消息持久化能力,
即使对TB级以上数据也能保证常数时间复杂度的访问性能

高吞吐率:即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输
支持Kafka Server间的消息分区,及分布式消费,同时保证每个Partition内的消息顺序传输
同时支持离线数据处理和实时数据处理

核心能力
高吞吐量、可扩展的、永久存储、高可用性

每秒 200 万次写入(在三台廉价机器上)

Kafka 为 Java 和 Scala 提供了五个核心 API:
Admin API :管理topics、brokers和其他Kafka对象的API
Producer API:生产者API
Consumer API :消费者API
Kafka Streams API :流处理API
Kafka Connect API :实现关系型数据库连接导入导出的API

核心组成介绍

Producer
生产者可以将数据发布到所选择的topic(主题)中。生产者负责将记录分配到topic的哪一个 partition(分区)中。可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(例如:记录中的key)来完成。下面会介绍更多关于分区的使用。
Consumer
消费者使用一个 消费组 名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例.消费者实例可以分布在多个进程中或者多个机器上。
在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便在任何时间,每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例。
Broker
⼀台 Kafka 机器就是⼀个 Broker。⼀个集群(kafka cluster)由多个 Broker 组成。⼀个 Broker 可以容纳多个 Topic。
Topic
可以理解为⼀个队列,Topic 将消息分类,⽣产者和消费者⾯向的是同⼀个 Topic。
Topic是分区的(partitioned), Topic分布在位于不同 Kafka 代理上的多个“buckets”中。数据的这种分布式放置对于可扩展性非常重要,因为它允许客户端应用程序同时从多个代理读取和写入数据。一个Topic通常会有多个Producer和多个Consumer。一个Topic有0个1个或多个Producer发送消息,就像它可能有0个1个或者多个Consumer一样。
Topic 可以设置同步备份的最小数量。
Events
Events被组织并持久存储在Topic中,Topic相当于文件系统中的文件夹,events是文件夹中的文件。Events在消息读取后不会被删除,你可以定义kafka来设置消息的存放时间。Kafka 的性能在数据大小方面实际上是恒定的,因此长时间存储数据是非常好的。
在这里插入图片描述
图例种的Topic有4个分区(p1-p4),两个不同的producer客户端,相互独立,通过网络将events写入主题的分区,从而为Topic添加新事件。具有相同键的Events(在图中由它们的颜色表示)被写入同一个分区。
为了使您的数据具有容错性和高可用性,可以replicated每个主题,甚至跨地理区域或数据中心,以便始终有多个代理拥有数据副本,以防万一出现问题,您想要对brokers进行维护,等等。一个常见的生产设置是复制因子为 3,即始终存在三个数据副本。此复制在主题分区级别执行。

深入了解

Producer

Load balancing
生产者直接发送数据到主分区的服务器上,不需要经过任何中间路由。 为了让生产者实现这个功能,所有的 kafka 服务器节点都能响应这样的元数据请求: 哪些服务器是活着的,主题的哪些分区是主分区,分配在哪个服务器上,这样生产者就能适当地直接发送它的请求到服务器上。

客户端控制消息发送数据到哪个分区,这个可以实现随机的负载均衡方式,或者使用一些特定语义的分区函数。 我们有提供特定分区的接口让用于根据指定的键值进行hash分区(当然也有选项可以重写分区函数),例如,如果使用用户ID作为key,则用户相关的所有数据都会被分发到同一个分区上。 这允许消费者在消费数据时做一些特定的本地化处理。这样的分区风格经常被设计用于一些本地处理比较敏感的消费者。

Asynchronous send
批处理是提升性能的一个主要驱动,为了允许批量处理,kafka 生产者会尝试在内存中汇总数据,并用一次请求批次提交信息。 批处理,不仅仅可以配置指定的消息数量,也可以指定等待特定的延迟时间(如64k 或10ms),这允许汇总更多的数据后再发送,在服务器端也会减少更多的IO操作。 该缓冲是可配置的,并给出了一个机制,通过权衡少量额外的延迟时间获取更好的吞吐量。
ACK
producer 也 可以选择是否等待消息被提交,这取决他们的设置在延迟时间和持久性之间的权衡,这个选项是由 producer 使用的 acks 设置控制。
pros.put(“acks”,“0”)//不等待broker返回确认消息
pros.put(“acks”,“1”)//(默认)leader保存成功返回
pros.put(“acks”,“-1”)// 所有备份都保存成功返回 all=ISR 此时可以指定最小的 ISR 集合大小,只有当 ISR 的大小大于最小值,分区才能接受写入操作

consumer

Kafka consumer通过向 broker 发出一个“fetch”请求来获取它想要消费的 partition。consumer 的每个请求都在 log 中指定了对应的 offset,并接收从该位置开始的一大块数据。因此,consumer 对于该位置的控制就显得极为重要,并且可以在需要的时候通过回退到该位置再次消费对应的数据。
Push vs. pull
producer 把数据 push 到 broker,然后 consumer 从 broker 中 pull 数据。
消费者的位置
Kafka 使用完全不同的方式解决消息丢失问题。Kafka的 topic 被分割成了一组完全有序的 partition,其中每一个 partition 在任意给定的时间内只能被每个订阅了这个 topic 的 consumer 组中的一个 consumer 消费。这意味着 partition 中 每一个 consumer 的位置仅仅是一个数字,即下一条要消费的消息的offset。这使得被消费的消息的状态信息相当少,每个 partition 只需要一个数字。这个状态信息还可以作为周期性的 checkpoint。这以非常低的代价实现了和消息确认机制等同的效果。
这种方式还有一个附加的好处。consumer 可以回退到之前的 offset 来再次消费之前的数据,这个操作违反了队列的基本原则,但事实证明对大多数 consumer 来说这是一个必不可少的特性。 例如,如果 consumer 的代码有 bug,并且在 bug 被发现前已经有一部分数据被消费了, 那么 consumer 可以在 bug 修复后通过回退到之前的 offset 来再次消费这些数据。

Replication

Kafka 允许 topic 的 partition 拥有若干副本,你可以在server端配置partition 的副本数量。当集群中的节点出现故障时,能自动进行故障转移,保证数据的可用性。
其他的消息系统也提供了副本相关的特性,但是在我们(带有偏见)看来,他们的副本功能不常用,而且有很大缺点:slaves 处于非活动状态,导致吞吐量受到严重影响,并且还要手动配置副本机制。Kafka 默认使用备份机制,事实上,我们将没有设置副本数 的 topic 实现为副本数为1的 topic 。

创建副本的单位是 topic 的 partition ,正常情况下, 每个分区都有一个 leader 和零或多个 followers 。 总的副本数是包含 leader 的总和。 所有的读写操作都由 leader 处理,一般 partition 的数量都比 broker 的数量多的多,各分区的 leader 均 匀的分布在brokers 中。所有的 followers 节点都同步 leader 节点的日志,日志中的消息和偏移量都和 leader 中的一致。(当然, 在任何给定时间, leader 节点的日志末尾时可能有几个消息尚未被备份完成)。

Followers 节点就像普通的 consumer 那样从 leader 节点那里拉取消息并保存在自己的日志文件中。Followers 节点可以从 leader 节点那里批量拉取消息日志到自己的日志文件中。
在所有时间里,Kafka 保证只要有至少一个同步中的节点存活,提交的消息就不会丢失。

备份管理
优化主从关系的选举过程也是重要的,这是数据不可用的关键窗口。原始的实现是当有节点挂了后,进行主从关系选举时,会对挂掉节点的所有partition 的领导权重新选举。相反,我们会选择一个 broker 作为 “controller”节点。controller 节点负责 检测 brokers 级别故障,并负责在 broker 故障的情况下更改这个故障 Broker 中的 partition 的 leadership 。这种方式可以批量的通知主从关系的变化,使得对于拥有大量partition 的broker ,选举过程的代价更低并且速度更快。如果 controller 节点挂了,其他 存活的 broker 都可能成为新的 controller 节点。
日志压缩
日志压缩可确保 Kafka 始终至少为单个 topic partition 的数据日志中的每个 message key 保留最新的已知值。保证日志包含每一个key的最终值

以上均来此
中文文档kafka.apachecn.org
英文文档kafka.apache.org

本文档仅用来做基础学习和记录。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到