@Kafka
Kafka
是一个分布式的基于发布、订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域
Kafka 在设计之初就旨在提供三个方面的特性:
提供一套 API 实现生产者和消费者;
降低网络传输和磁盘存储开销;
实现高伸缩性架构。
传统消息队列:
- 同步处理
- 异步处理:解耦,缓解压力,发的快,收的慢,可削峰
使用消息队列的好处:
- 解耦:允许由独立的扩展或修改两边的处理过程,只要确保他们遵守同样的接口约束
- 可恢复性:系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使有一个处理消息的进程挂掉了,加入队列中的消息仍然可以在系统恢复后被处理
- 缓冲:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的速度不一致的情况
- 灵活性&峰值处理能力:在访问量剧增的情况下,可帮助缓解突发的访问压力
- 异步通信:消息队列提供了异步处理机制,允许用户把一个消息放入队列,但是并不立即处理它。
消息队列的模式:
点对点:消费者主动拉取消息,消息收到后消息清楚 拉 有时会浪费资源,会常询问是否有新消息
一对多:消费者消费数据之后不会清除消息(有时间期限) 推 速度无法更改
kafka集群启动=》生产者生产消息=》
一个分区的数据,只能被同消费组里的一个消费者消费 并发时最好的状态就是消费组里的消费者的个数等于分区数
zookeeper可帮助消费者存储消费到的位置信息(0.9版本之前)
0.9版本之后存储在kafka本地的topic里
分区:可提高数据读取的并发度
副本:数据冗余,容灾,备份
Kafka术语:
- 消息:Record Kafka是消息引擎,这里的消息指的是Kafka处理的主要对象
- 主题:Topic 主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务
- 分区:Partition 一个有序不变的消息序列,每个主题下可以有多个分区
- 消息位移:Offset 表示分区中每条消息的位置信息,是一个单调递增且不变的值
- 副本:Replica Kafka中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。副本还分为领导者和追随者副本,各自有不同的角色划分。
- 副本是在分区层级下的,即每个分区可配置多个副本实现高可用。
- 生产者:Producer 向主题发布新消息的应用程序
- 消费者:Consumer 向主题订阅新消息的应用程序
- 消费者位移:Consumer Offset 表征消费者消费进度,每个消费者都有自己的消费者位移
- 消费者组:Consumer Group 多个消费者实例共同组成的一个组,同时消费多个分区以实现高吞吐
- 重平衡 Rebalance 消费者组内某个消费者实例挂掉之后,其他消费者实例自动重新分配订阅主题分区的过程。Rabalance是Kafka消费者端实现高可用的重要手段
思考:
为什么kafka不支持主从分离?
首先:主从分离与否没有绝对的优劣,它仅仅是一种架构设计,各自有适用的场景。
第二、Redis和MySQL都支持主从读写分离,这和它们的使用场景有关。
对于那种读操作很多而写操作相对不频繁的负载类型而言,采用读写分离是非常不错的方案。
反观Kafka,它的主要场景还是在消息引擎而不是以数据存储的方式对外提供读服务,通常涉及频繁地生产消息和消费消息,这不属于典型的读多写少场景,因此读写分离方案在这个场景下并不太适合。
第三、Kafka副本机制使用的是异步消息拉取,因此存在leader和follower之间的不一致性。如果要采用读写分离,必然要处理副本lag引入的一致性问题。
Kafka参数:
- log.dirs:指定Broker需要使用的若干个文件目录路径
- log.dir:注意这是 dir,结尾没有 s,说明它只能表示单个路径,它是补充上一个参数用的。
- listeners:学名叫监听器,其实就是告诉外部连接者要通过什么协议访问指定主机名和端口开放的 Kafka 服务
- advertised.listeners:和 listeners 相比多了个advertised。Advertised 的含义表示宣称的、公布的,就是说这组监听器是 Broker 用于对外发布的。
- host.name/port:列出这两个参数就是想说你把它们忘掉吧,压根不要为它们指定值,毕竟都是过期的参数了。
- auto.create.topics.enable:是否允许自动创建Topic,建议最好设置成false,即不允许自动创建 Topic。
- unclean.leader.election.enable:是否允许Unclean Leader 选举。设置成 false,那么就坚持之前的原则,坚决不能让那些落后太多的副本竞选 Leader。这样做的后果是这个分区就不可用了,因为没有 Leader 了。反之如果是 true,那么Kafka 允许你从那些“跑得慢”的副本中选一个出来当Leader。这样做的后果是数据有可能就丢失了,因为这些副本保存的数据本来就不全,当了 Leader 之后它本人就变得膨胀了,认为自己的数据才是权威的
- auto.leader.rebalance.enable:是否允许定期进行 Leader 选举。 换一次 Leader 代价很高的,原本向 A 发送请求的所有客户端都要切换成向 B 发送请求,而且这种换 Leader本质上没有任何性能收益,因此我建议你在生产环境中把这个参数设置成 false。
- log.retention.{hour|minutes|ms}:这是个“三兄弟”,都是控制一条消息数据被保存多长时间。从优先级上来说 ms 设置最高、minutes 次之、hour 最低。
虽然 ms 设置有最高的优先级,但是通常情况下我们还是设置 hour 级别的多一些,比如log.retention.hour=168表示默认保存 7 天的数据, - log.retention.bytes:这是指定 Broker 为消息保存的总磁盘容量大小。
这个参数真正发挥作用的场景其实是在云上构建多租户的 Kafka 集群:设想你要做一个云上的 Kafka 服务,每个租户只能使用100GB 的磁盘空间,为了避免有个“恶意”租户使用过多的磁盘空间 - message.max.bytes:控制 Broker 能够接收的最大消息大小。
实际场景中突破 1MB 的消息都是屡见不鲜的,因此在线上环境中设置一个比较大的值还是比较保险的做法。毕竟它只是一个标尺而
已,仅仅衡量 Broker 能够处理的最大消息大小,即使设置大一点也不会耗费什么磁盘空间的。
Topic 级别参数会覆盖全局Broker 参数的值,而每个 Topic 都能设置自己的参数值