1. kafka基础
1.1 定位和功能
kafka是一个分布式的消息系统,使用scala语言编写,现已经贡献给Apache基金会。主要有以下特点:
- 可以发布与订阅消息:消息可以细分为不同的主题,支持多种消息发布和订阅需求。
- 可以存储消息记录,并具有较好容错性:可以按时间或者容量大小清理旧消息。
- 支持弹性扩展,以支撑海量数据规模:kafka是分布式的,一方面可以提升系统吞吐,另一方面可以提升可用性。
1.2 消息
kafka的数据单元称为【消息】,可以理解为一条数据记录,由键和值组成。键值都是字节数组,其中键是可选的,kafka通过散列键取模后,控制消息写到主题的不同分区。
为了提高写入的效率,消息也会被分成一批写入kafka。
1.3 主题和分区
主题也叫Topic,是数据记录发布和订阅的地方。不同类型或者业务的数据,可以区分为不同的主题。一个Topic可以拥有一个或者多个消费者来订阅数据,也可以有一个或多个生产者生产数据。对每一个Topic,kafka集群会维护一个分区日志,如下所示:
每个分区都是有序并且顺序不可变的记录集合,新数据不断追加到结构化的commit log文件中。分区中的每一个数据记录都会配置一个ID号来表示顺序,也称之为offset。
消费者唯一保存的元数据是offset,在读取记录后,会以线性的方式增加偏移量。由于这个位置是消费者控制,所以消费者可以采用任何顺序来消费记录。比如重置到一个旧的偏移位置,从而达到数据回溯的目的。
Topic还有Partition(分区)的概念,一方面是扩展单台服务器的硬件限制,继而扩展Topic的日志量级,因为单独的分区都会受限于主机的文件限制。另一方面可以并行的处理以提高效率,比如并行的处理消费或者生产过程。
1.3 生产者和消费者
kafka的客户端分为生产者和消费者两种类型,其中生产者用于创建消息,将消息写入到kafka的某个主题。在大部分场景下,生产者不关注消息写到哪个分区,如果要控制部分消息写到相同的分区,需要自定义实现分区器,对消息的键做散列过程。
消费者从主题中订阅消息,它需要保存分区的offset。消费者从属于一个消费群组,一个或者多个消费群组可以订阅相同的主题,消费群组用来保证每个分区只能被一个消费者使用。例如:
消费群组A有两个消费者C1、C2,每个消费者均分两个分区。而消费群组B有四个消费者C3~C6,每个消费者均分1个分区。
kafka只能保证分区内的记录是有序的,而不保证不同分区的顺序。
1.4 broker和集群
一个独立的kafka服务器被称为broker,
- broker接收生产者消息,为消息设置偏移量,并提交到磁盘保存。
- broker为消费者提供服务,对读取分区的请求做出响应。
broker是集群的组成部分,每个集群都有一个broker充当集群控制器的角色,负责kafka管理工作,比如将分区分配给broker和监控broker等。为了提升可用性,分区还有副本的概念,每个分区副本都归属于不同的broker,如果一个副本挂掉,其他副本仍是可用的,这个得益于分区复制的特性。
kafka有两种消息保留策略,一种是设定过期时间,超时自动清理,一种是设置大小,当消息数量达到上限时,旧消息会过期会删除。
2. kafka API
2.1 The Produer API
允许应用程序发布一串流式的数据到一个或者多个kafka topic。
2.2 The Consumer API
允许应用程序订阅一个或者多个topic,并消费到相应topic中新发布的数据。
2.3 The Streams API
允许一个应用程序作为一个流处理器,消费一个或者多个topic,然后作为生产者输出到一个或者多个topic中。
2.4 The Connector API
允许构建并运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。
3. kafka概要
3.1 优缺点
优点:
- 高吞吐:充分利用磁盘顺序读写能力,单机吞吐性能卓越,每秒可处理数千条消息。
- 低延迟:毫秒级处理消息的能力。
- 容错性:部分分区挂掉的情况下,数据仍不会丢失。
- 持久化:kafka将消息持久化磁盘上,支持消息回溯、消息自动清理。
- 扩展性:支持弹性伸缩,以支撑更大规模的消息规模。
- 消息代理:kafka broker可以将发布者的消息传递协议转换为接受者的消息传递协议。
- 消费者友好型:kafka可以与各种消费者集成,根据消费者的不同,它可以表现或采取不同的行为。
- 批量处理能力:因为消息持久化,所以具有一定的批量处理能力。
- 丰富的项目示例:日志聚合、trace系统、流式系统等等。
缺点:
- 没有完善的监控工具集。
- 不支持通配符的方式选择主题。
- 消息调整:broker通过确定的系统调用来传递消息,如果消息未发生改变的时候,性能表现良好,如果消息发生更改或者调整,那么性能会下降的比较厉害。
- 不保证消息传递的稳定性:可能出现消息丢失、重复消息、消息乱序等。
3.2 性能表现
硬件配置:
- Intel Xeon 2.5 GHz processor with six cores
- Six 7200 RPM SATA drives
- 32GB of RAM
- 1Gb Ethernet
3台机器组成kafka集群,测试如下:
场景 | 消息量 | 大小 |
---|---|---|
单生产者无副本 | 821,557 records/sec | 78.3MB/sec |
单生产者3X副本 | 786,980 records/sec | 75.1 MB/sec |
三生产者3X副本 | 2,024,032 records/sec | 193.0 MB/sec |
— | — | — |
单消费者 | 940,521 records/sec | 89.7 MB/sec |
三消费者 | 2,615,968 records/sec | 249.5 MB/sec |
端到端的延迟:
- 平均:2ms
- 99分位:3ms
- 99.9分位: 14ms
3.3 适用场景
消息传递系统
kafka可以很好的替代传统的消息队列,比如数据生成器与数据处理的解耦,缓冲未处理的消息以流量削峰等。相比传统的消息系统,kafka拥有更好的吞吐、内置分区、具有复制和容错的能力。
Trace系统
用户活动信息(点赞、收藏、评论等)发布到中心主题Topic,订阅源可以进行一系列的处理,包括实时监控、通知用户、生成报表等等。
日志聚合
服务器物理日志文件可以传输到kafka相应的主题中,可以抽象成一个更加清晰的数据流,方便后续日志分析、错误定位、报警等等。
流处理
kafka可以解耦数据产出和数据加工环节,并以毫秒级延迟传递消息,这种特性可以基于各个主题创建实时数据流图,实现数据的流式处理。举个简单的例子:用户的点击、浏览行为可以推送到主题A,行为分析模块从主题A中获取数据开始分析产生模型数据,并推到主题B,推荐模块从主题B中获取模型,以生效新的推荐模型等等。
等等
4. 参考
- kafka官网手册
- kafka权威指南