What's kafka
What's kafka
- Kafka 可以提供 MQ 功能:发布 & 订阅消息
- Kafka 可以提供 stream processing 功能
- Kafka 提供对 messages/ streams 的存储功能(通过配置,决定存储的 retention,当然,本质上我们不能把 Kafka 当成真正的存储系统来用)
- Kafka 是 distributed system,搭建 cluster 来灵活动态的伸缩容
Kafka vs Messaging system
Kafka 是一个 MQ 系统,支持 publish & subscribe messages,就像 ActiveMQ, RabbitMQ,核心就是处理消息,提供 producer & consumer 的解耦。
Kafka 和普通 MQ 系统的真正不同在于它的 stream processing capabilities,可以通过该功能读取 streams & 动态的输出 streams。
Kafka vs RabbitMQ
- RabbitMQ 不会存数据,没有消费者的话,msg 就丢了
- RabbitMQ 支持灵活的 exchange 策略,Kafka 的 topic 不支持
- Kafka 需要 Zookeeper 来管理 cluster,RabbitMQ 不需要
- Kafka 对 Java 友好
- Kafka 的社区活跃度比 RabbitMQ 高
Kafka vs Big data systems
Hadoop 支持大规模的 data 存储 & 周期性的处理文件数据。
Kafka 侧重于提供实时、低延迟的大量 data 处理能力
Kafka vs ETL tools
ETL 的主要能力在于:从一个系统中获取到数据,插入到新的系统中。Kafka 也可以提供该能力。
Summary
Kafka 通过抽象数据流的概念,把以上三种类型系统的能力结合了起来。而 stream processing 正是 Kafka 的突出亮点。
Messages and Batches
Messages
kafka 中 message 是可以持久化一定时间的,但是不同的配置 (retention)会影响 messages 保留的时间长短。触发阈值时,消息会被删除。
retention 是针对 topic 来配置的,可以配置的项有两个:
- log.retention.ms: Retention by time is performed by examining the last modified time (mtime) on each log segment file on disk.
- log.retention.bytes: all retention is performed for an individual partition, not the topic.
If you have specified a value for both log.retention.bytes and log.retention.ms (or another parameter for retention by time), messages may be removed when either criteria is met.
不同的业务场景对 message 丢失、重复、延迟的忍耐程度不同,需要使用不同的配置参数、不同的 API
Batches
Batches 是一组 messages。Batches 中的 messages 拥有相同的 topic and partition。
producer client 创建消息后,实际上会先缓存在本地的 buffer 中,等收集到一定量后,batches 发送给 broker。这种方式提升了效率,但导致了消息发送的延迟。可以根据业务需求,通过配置 batch 的 size 来调节延迟。
Serializer and deserializer
message 在网络间传递时,是需要 serialize 的,这时就需要有 serializer。
kafka 中有以下几种 serializer:
- string serializer
- Custom Serializer
- Serializing Using Apache Avro
默认的 string serializer 不够灵活,custom serializer 又需要投入大量的时间开发,比较建议使用现成的 serializer 工具,如 Apache Avro。Avro 通过 schema 的概念很好的实现了 serialize & deserialize 的功能。schemas 存储在独立的 register 中。producer & consumer 都从 schema repository 中读取 schema 来达到自动更新两端的能力。
Topic
kafka 中的消息是按 topic 来组织的。可以把 topic 理解成数据库中 table 的概念。
Partitions
partition 是 topic scale 的重要手段,它跟存储系统中的分片是一个概念。topic split 成多个 partitions,topic 中的 messages 分布到不同的 partitions 中,平衡负载,提高写性能,同时通过增加 consumer group 中 consumers 的个数,达到提高读性能的目的。
kafka 可以保证单个 partition 上的 msg 是有序的,但是在各个 partition 间,是无法维持一个全局有序的。
如何决定消息落到哪个 partition 上:
- 不指定 message 的 partition & key 参数,根据 round-robin algorithm ,随机落到某个 partition
- 指定 message 的 key
2.1 默认的 partitioner 对 key 应用一定的 hash 算法,来决定 partition 位置
2.2 默认的 key partition 算法在某种业务场景下,会导致各个 partition 的数据量严重不平衡。根据业务场景自定义 partitioner,对 key 应用自定义的算法来分配 partition 位置 - 指定 partition,则忽略 key,直接按照配置的 partition 去存储消息
改变 topic 的 partition 个数后,相同 key 的 messages 在改变前后可能分配到不同的 partition 中,如果业务系统对此敏感,则建议:
1、初始时,估算好恰当的、足够大的 partitions
2、初始化后,尽量不改