2021 年 Java 面试心得,整理出这份 8 万字 Java 性能优化实战解析
目录
Kafka 的基本介绍
Kafka 的设计原理分析
Kafka 数据传输的事务特点
Kafka 消息存储格式
副本(replication)策略
Kafka 消息分组,消息消费原理
Kafak 顺序写入与数据读取
消费者(读取数据)
Kafka 的基本介绍
Kafka 是最初由 Linkedin 公司开发,是一个分布式、分区的、多副本的、多订阅者,基于 zookeeper 协调的分布式日志系统(也可以当做 MQ 系统),常见可以用于 web/nginx 日志、访问日志,消息服务等等,Linkedin 于 2010 年贡献给了 Apache 基金会并成为顶级开源项目。
主要应用场景是:日志收集系统和消息系统。
Kafka 主要设计目标如下:
以时间复杂度为 O(1)的方式提供消息持久化能力,即使对 TB 级以上数据也能保证常数时间的访问性能。
高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒 100K 条消息的传输。
支持 Kafka Server 间的消息分区,及分布式消费,同时保证每个 partition 内的消息顺序传输。
同时支持离线数据处理和实时数据处理。
Kafka 的设计原理分析
一个典型的 kafka 集群中包含若干 producer,若干 broker,若干 consumer,以及一个 Zookeeper 集群。Kafka 通过 Zookeeper 管理集群配置,选举 leader,以及在 consumer group 发生变化时进行 rebalance。producer 使用 push 模式将消息发布到 broker,consumer 使用 pull 模式从 broker 订阅并消费消息。
Kafka 专用术语:
Broker:消息中间件处理结点,一个 Kafka 节点就是一个 broker,多个 broker 可以组成一个 Kafka 集群。
Topic:一类消息,Kafka 集群能够同时负责多个 topic 的分发。
Partition:topic 物理上的分组,一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列。
Segment:partition 物理上由多个 segment 组成。
offset:每个 partition 都由一系列有序的、不可变的消息组成,这些消息被连续的追加到 partition 中。partition 中的每个消息都有一个连续的序列号叫做 offset,用于 partition 唯一标识一条消息。
Producer:负责发布消息到 Kafka broker。
Consumer:消息消费者,向 Kafka broker 读取消息的客户端。
Consumer Group:每个 Consumer 属于一个特定的 Consumer Group。
Kafka 数据传输的事务特点
at most once:最多一次,这个和 JMS 中"非持久化"消息类似,发送一次,无论成败,将不会重发。消费者 fetch 消息,然后保存 offset,然后处理消息;当 client 保存 offset 之后,但是在消息处理过程中出现了异常,导致部分消息未能继续处理。那么此后"未处理"的消息将不能被 fetch 到,这就是"at most once"。
at least once:消息至少发送一次,如果消息未能接受成功,可能会重发,直到接收成功。消费者 fetch 消息,然后处理消息,然后保存 offset。如果消息处理成功之后,但是在保存 offset 阶段 zookeeper 异常导致保存操作未能执行成功,这就导致接下来再次 fetch 时可能获得上次已经处理过的消息,这就是"at least once",原因 offset 没有及时的提交给 zookeeper,zookeeper 恢复正常还是之前 offset 状态。
exactly once:消息只会发送一次。kafka 中并没有严格的去实现(基于 2 阶段提交),我们认为这种策略在 kafka 中是没有必要的。
通常情况下"at-least-once"是我们首选。
Kafka 消息存储格式
Topic & Partition
一个 topic 可以认为一个一类消息,每个 topic 将被分成多个 partition,每个 partition 在存储层面是 append log 文件。
在 Kafka 文件存储中,同一个 topic 下有多个不同 partition,每个 partition 为一个目录,partiton 命名规则为 topic 名称+有序序号,第一个 partiton 序号从 0 开始,序号最大值为 partitions 数量减 1。
每个 partion(目录)相当于一个巨型文件被平均分配到多个大小相等 segment(段)数据文件中。但每个段 segment file 消息数量不一定相等,这种特性方便 old segment file 快速被删除。
每个 partiton 只需要支持顺序读写就行了,segment 文件生命周期由服务端配置参数决定。
这样做的好处就是能快速删除无用文件,有效提高磁盘利用率。
segment file 组成:由 2 大部分组成,分别为 index file 和 data file,此 2 个文件一一对应,成对出现,后缀".index"和“.log”分别表示为 segment 索引文件、数据文件.
segment 文件命名规则:partion 全局的第一个 segment 从 0 开始,后续每个 segment 文件名为上一个 segment 文件最后一条消息的 offset 值。数值最大为 64 位 long 大小,19 位数字字符长度,没有数字用 0 填充。
结语
小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。
我们选择的这个行业就一直要持续的学习,又很吃青春饭。
虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。
开源分享:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】
送给每一位想学习 Java 小伙伴,用来提升自己。
本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!
评论