1. 简介
- Kafka 是 LinkedIn 使用 Scala 编写具有高水平扩展和高吞吐量的分布式消息系统。
- Kafka 对消息保存时根据 Topic 进行归类,发送消息者称为 producer,消息接收者称为 consumer,此外 Kafka 集群有多个 Kafka 实例组成,每个实例(server)称为 broker。
- 无论是 Kafka 集群,还是 producer 和 consumer 都依赖于 zookeeper 来保证系统可用性,为集群保存一些 meta 信息。
2. 主流 MQ 对比
- 数据吞吐量:Kafka > RabbitMQ > ActiveMQ
- 数据准确性:RabbitMQ > ActiveMQ > Kafka
ActiveMQ | RabbitMQ | Kafka | |
---|---|---|---|
所属社区/公司 | Apache | Mozilla Public License | Apache/LinkedIn |
开发语言 | Java | Erlang | Scala |
支持的协议 | OpenWire、STOMP、REST、XMPP、AMQP | AMQP | 仿 AMQP |
事务 | 支持 | 不支持 | 0.11 开始支持 |
集群 | 支持(不擅长) | 支持(不擅长) | 支持 |
负载均衡 | 支持 | 支持 | 支持 |
动态扩容 | 不支持 | 不支持 | 支持(zk) |
3. Kafka 主要特性
- Kafka 是一个流处理平台,流平台需如下特性:
- 可发布和订阅流数据,类似于消息队列或者企业级消息系统。
- 以存储容错的方式存储流数据。
- 可以在流数据产生时就进行处理。
- Kafka 适合什么样的场景?
- 基于 Kafka,构造实时流数据管道,让系统或应用之间可靠地获取数据。
- 构建实时流式应用程序,处理流数据或基于数据做出反应。
4. 相关概念
- AMQP(Advanced Message Queuing Protocal),是一个提供统一消息服务的标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件而设计。
概念 | 描述 |
---|---|
server | AMQP 服务端,接受客户端连接,实现 AMQP 消息队列和路由功能的进程。 |
producer | 生产者,向 broker 发布消息的客户端应用程序。 |
consumer | 消费者,向消息队列请求消息的客户端应用程序。 |
Topic | 是数据主题,是 Kafka 用来代表一个数据流的一个抽象。发布数据时,可用 topic 对数据进行分类,也作为订阅数据时的主题。一个 Topic 同时可有多个 producer、consumer。 |
Partition | 每个 Partition 是一个顺序的、不可变的 record 序列,partition 中的 record 会被分配一个自增长的 id,我们称之为 offset。 |
Replication | 每个 partition 还会被复制到其他服务器作为 replication,这是一种冗余备份策略。 |
Record | 每条记录都有 key、value、timestamp 三个信息 |
5. Kafka 核心 API
四个核心 API
API | 描述 |
---|---|
Producer API | 允许一个应用程序发布一串流式的数据到一个或者多个 Kafka topic。 |
Consumer API | 允许一个应用程序订阅一个或者多个 topic,并且对发布给它们的流式数据进行处理。 |
Stream API | 允许一个应用程序作为一个流处理器,消费一个或者多个 topic 产生的输入流,然后生产一个输出流到一个或者多个 topic 中去,在输入输出中进行有效的转换。 |
Connector API | 允许构建并运行可重用的生产者或者消费者,将 Kafka topics 连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。 |
Kafka API - producer
代码语言:javascript复制Properties props = new Properties();
props.put("batch.size", 16384); // 默认值为 16384
props.put("linger.ms", 16384); // 默认值为 0
props.put("acks", "all");
props.put("retries", 1);
// ...
Producer<String, String> producer = new KafkaProducer(props);
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key", "value");
producer.send(record);
producer.close();
- producer 会为每个 partition 维护一个缓冲,用来记录还没有发送的数据,每个缓冲区大小用 batch.size 指定,默认值为 16K。
- linger.ms:buffer 中的数据在达到 batch.size 前,需要等待的时间。
- acks:用来配置请求成功的标准。
- 0:不检查返回。
- 1:leader partition 请求成功即可。
- all:leader partition 及 follower partition 请求成功才行。
6. Kafka 使用场景
1. 消息系统
- 消息系统被用于各种场景,如解耦数据生产者,缓存未处理的消息。Kafka 可作为传统的消息系统的替代者,与传统消息系统相比,Kafka 有更好的吞吐量、更好的可用性,这有利于处理大规模的消息。
- 根据经验,通常消息传递对吞吐量要求较低,但可能要求较低的端到端延迟,并经常依赖 Kafka 可靠的 durable 机制。
- 在这方面,Kafka 可以与传统的消息传递系统(ActiveMQ 和 RabbitMQ)相媲美。
2. 存储系统
- 写入到 Kafka 的数据是落地到了磁盘上,并且有冗余备份,Kafka 允许 producer 等待确认,通过配置,可实现直到所有的 replication 完成复制才算写入成功,这样可保证数据的可用性。
- Kafka 认真对待存储,并允许 client 自行控制读取位置,你可以认为 Kafka 是一种特殊的文件系统,它能够提供高性能、低延迟、高可用的日志提交存储。
3. 日志聚合(Kafka 官方提出,装得有点大)
- 日志系统一般需要如下功能:日志的收集、清洗、聚合、存储、展示。
- Kafka 常用来替代其他日志聚合解决方案。
- 和 Scribe、Flume 相比,Kafka 提供同样好的性能、更健壮的堆积保障、更低的端到端延迟。
- 日志会落地,导致 Kafka 做日志聚合更昂贵。
- Kafka 可实现日志的清洗(需要编码)、聚合(可靠但昂贵)、存储。
- ELK 是现在比较流行的日志系统。在 Kafka 的配合下才是更成熟的方案,Kafka 在 ELK 技术栈中,主要起到 buffer 的作用,必要时可进行日志的汇流。
4. 跟踪网站活动
- Kafka 的最初是作用就是,将用户行为跟踪管道重构为一组实时发布-订阅源。把网站活动(浏览网页、搜索或其他的用户操作)发布到中心 topics 中,每种活动类型对应一个 topic。基于这些订阅源,能够实现一系列用例,如实时处理、实时监视、批量地将 Kafka 的数据加载到 Hadoop 或离线数据仓库系统,进行离线数据处理并生成报告。
- 每个用户浏览网页时都生成了许多活动信息,因此跟踪活动的数据量通常非常大。(Kafka 实际应用)
5. 流处理
- Kafka 社区认为仅仅提供数据生产、消息机制是不够的,他们还要提供流数据实时处理机制,从 0.10.0.0 开始,Kafka 通过提供 Stream API 来提供轻量、但功能强大的流处理。实际上就是 Stream API 帮助解决流引用中一些棘手的问题,比如:处理无序的数据,代码变化后再次处理数据,进行有状态的流式计算。
- Stream API 的流处理包含多个阶段,从 input topics 消费数据,做各种处理,将结果写入到目标 topic,Stream API 基于 Kafka 提供的核心原语构建,它使用 Kafka consumer、producer 来输入、输出,用 Kafka 来做状态存储。
- 流处理框架:flink、spark streaming、Storm、Samza 才是正统的流处理框架,Kafka 在流处理中更多的是扮演流存储的角色。