MQ入门总结(六)Kafka的原理和使用
Kafka的架构原理,你真的理解吗?
真的,Kafka 入门一篇文章就够了
Kafka 常用命令总结
一、kafka架构

- Zookeeper用于保存集群配置、选举Leader等
- 集群中有许多broker用于堆积消息,Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高。
- Producer使用push模式将消息发布到broker。
- Consumer使用pull模式从broker订阅并消费消息。
二、kafka组件
- 话题(Topic):是特定类型的消息流。消息是字节的有效负载(Payload),话题是消息的分类名或种子(Feed)名。
- 生产者(Producer):是能够发布消息到话题的任何对象。
- 服务代理(Broker):已发布的消息保存在一组服务器中,它们被称为代理(Broker)或Kafka集群。
- 消费者(Consumer):可以订阅一个或多个话题,并从Broker拉数据,从而消费这些已发布的消息。
核心API
Kafka 有四个核心API,它们分别是
- Producer API:它允许应用程序向一个或多个 topics 上发送消息记录
- Consumer API:允许应用程序订阅一个或多个 topics 并处理为其生成的记录流
- Streams API:它允许应用程序作为流处理器,从一个或多个主题中消费输入流并为其生成输出流,有效的将输入流转换为输出流。
- Connector API:它允许构建和运行将 Kafka 主题连接到现有应用程序或数据系统的可用生产者和消费者。例如,关系数据库的连接器可能会捕获对表的所有更改

三、存储策略
kafka以topic来进行消息管理,每个topic包含多个partition,每个partition对应一个逻辑log,有多个segment组成。
每个segment中存储多条消息,消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射。
每个part在内存中对应一个index,记录每个segment中的第一条消息偏移。
发布者发到某个topic的消息会被均匀的分布到多个partition上(或根据用户指定的路由规则进行分布),broker收到发布消息往对应partition的最后一个segment上添加该消息,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息订阅者才能订阅到,segment达到一定的大小后将不会再往该segment写数据,broker会创建新的segment。
四、删除策略
1)N天前的删除。
2)保留最近的MGB数据。
消息不丢失
1、生产消息
1)通过 ACK 机制保证消息送达。Kafka 采用的是至少一次(At least once),消息不会丢,但是可能会重复传输。

2)为了得到更好的性能,Kafka 支持在生产者一侧进行本地buffer,也就是累积到一定的条数才发送,如果这里设置不当是会丢消息的。
生产者端设置 producer.type=async, sync,默认是 sync。
- 当设置为 async,会大幅提升性能,因为生产者会在本地缓冲消息,并适时批量发送。
- 如果对可靠性要求高,那么这里可以设置为 sync 同步发送。
2、配置
- 给 topic设置 replication.factor ,这个值必须大于 1,保证每个 partition 必须至少有 2 个副本
- 在 kafka 服务端设置 min.insync.replicas 参数,这个值必须大于 1,这个是要求一个leader至少感知到有至少一个follower还跟自己保持联系,没掉队,这样才能确保 leader挂了还有一个follower,保证至少一个 follower能和leader保持正常的数据同步。
3、消费消息
如果更注重可靠性,则需要显示提交 Offset,也就是当所有业务都处理完成的时候,再提交 Offset。这样会导致重复消费,需要提供幂等性接口。
速度快
1、顺序写磁盘
顺序写磁盘的性能是随机写入的性能的6000倍的提升,媲美内存随机访问的性能,磁盘不再是瓶颈点。
2、Page Cache
为了优化读写性能,Kafka利用了操作系统本身的Page Cache,就是利用操作系统自身的内存而不是JVM空间内存。通过操作系统的Page Cache,Kafka的读写操作基本上是基于内存的,读写速度得到了极大的提升。
3、零拷贝技术
零拷贝技术,可以有效的减少上下文切换和拷贝次数。
4、消息压缩
5、分批发送
保证顺序
写入一个 partition中的数据一定是有顺序的。
生产者在写的时候,可以指定一个 key,比如订单id作为key,那么订单相关的数据,一定会被分发到一个 partition中区,此时这个 partition中的数据一定是有顺序的。Kafka 中一个 partition 只能被一个消费者消费。消费者从partition中取出数据的时候 ,一定是有顺序的。

