Kafka
一、Kafka 基础
核心问题-kafka消息积压
kafka作为消息中间件,起着承上启下的作用,所以kafka消息积压的问题尤其重要,是保证系统运行稳定性的关键。
积压问题由两方面导致:生产者的生产速度 远大于 消费者的消费速度。故从这两方面进行着手。
1.生产者
1⃣️可设置限流。限制生产速度
2⃣️提前分局业务峰值规划分区数
3⃣️背压机制,调整生产者缓冲区大小 和 缓冲区满时的最大阻塞时间。
4⃣️监控消费滞后,当消费滞后时间达到阈值时,则暂停生产
2.消费者
1⃣️尽量保证消费者数量=分区数
2⃣️调整每次拉取的数量
3⃣️调整拉取缓冲区的大小
4⃣️调整心跳间隔,避免误判死亡
5⃣️使用监控工具监控消费者滞后告警
1.1 Kafka的特点
1.解耦:
允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
2.冗余:
消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
3.扩展性:
因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。
4.灵活性 & 峰值处理能力:
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
5.可恢复性:
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
6.顺序保证:
在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。(Kafka 保证一个 Partition 内的消息的有序性)
7.缓冲:
有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
8.异步通信:
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
1.2 Kafka架构图



1.3 Kafka相关概念

1.producer:
消息生产者,发布消息到 kafka 集群的Borker(下面的Leader分区)。
2.broker:
kafka 集群中安装Kafka的服务器(容器),broker要有唯一的ID。
3.topic:
每条发布到 kafka 集群的消息属于的类别,即 kafka 是面向 topic 的(相当于数据库中的表)
4.partition:
partition 是物理上的概念,每个 topic 包含一个或多个 partition。kafka 分配的单位是 partition。
5.consumer:
从 kafka 集群中消费消息的终端或服务。
6.Consumer group:
high-level consumer API 中,每个 consumer 都属于一个 consumer group,每条消息只能被 consumer group 中的一个 Consumer 消费,但可以被多个 consumer group 消费。
7.replication:
partition 的副本,保障 partition 的高可用。
8.leader:
replication 中的一个角色, producer 和 consumer 只跟 leader 交互(leader分区负责对象)。
9.follower:
replica 中的一个角色,从 leader 中复制数据(follower分区负责同步数据)。
10.zookeeper:
kafka 通过 zookeeper 来存储集群的 meta 信息
总结:
1.Kafka的生产者直接向Broker的Leader分区写入数据,不需要连接ZK
2.Kafka的消费者(老的API需要先连接ZK,获取Broker信息和topic、分区偏移量信息),新的API不需要连接ZK(直连方式,新的API,底层的API,效率更高)
1.4 安装Kafka集群
一定要开启zookeeper
上传-->解压-->配置-->分发
- 上传Kafka安装包
- 解压
- 修改配置文件
vi servier.properties
properties
#指定broker的id
broker.id=101 -->分发到其他节点的brokerId要不同,101,102,103
#数据存储的目录
log.dirs=/data/kafka
#指定zk地址
zookeeper.connect=Linux01:2181,linux02:2181,linux03:2181
#可以删除topic的数据(生成环境不用配置)
#delete.topic.enable=true -->这个没有配置,所以删除的时候不会立马删除,会过段时间再删除
- 将配置好的kafka拷贝的其他节点
- 修改其他节点Kafka的broker.id
二、 启动Kafka
开启zookeeper
zk.sh start
/opt/apps/kafka_2.12-2.6.2/bin/kafka-server-start.sh -daemon /opt/apps/kafka_2.12-2.6.2/config/server.properties
2.1 在所有节点启动Kafka
-daemon是后台启动 每台节点都要开启kafka
/opt/apps/kafka_2.12-2.6.2/bin/kafka-server-start.sh -daemon /opt/apps/kafka_2.12-2.6.2/config/server.properties
2.2 查看Kafka进程信息
jps
进程中会有kafka的进程
2.3 查看Kafka的topic
#老的api
/bigdata/kafka_2.12-2.6.2/bin/kafka-topics.sh --list --zookeeper localhost:2181
#新的
/bigdata/kafka_2.12-2.6.2/bin/kafka-topics.sh --list --bootstrap-server linunx01:9092,linux02:9092,linux03:9092
2.4 创建topic
#老的
/bigdata/kafka_2.12-2.6.2/bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic hellokafka --replication-factor 3 --partitions 3
#x新的--可以指定topic的名称、分区数、副本数
/opt/apps/kafka_2.12-2.6.2/bin/kafka-topics.sh --create --topic access24 --partitions 4 --replication-factor 2 --bootstrap-server linux01:9092,linux02:9092,linux03:9092
2.5 启动命令行开启一个生产者
--可以开启多个生产者
/opt/apps/kafka_2.12-2.6.2/bin/kafka-console-producer.sh --broker-list linux01:9092,linux02:9092,linux03:9092 --topic test1
2.6 启动一个命令行开启一个消费者
--可以开启多个消费者
/opt/apps/kafka_2.12-2.6.2/bin/kafka-console-consumer.sh --bootstrap-server linux01:9092,linux02:9092,linux03:9092 --from-beginning --topic access24
--from-beginning 消费以前产生的所有数据,如果不加,就是消费消费者启动后产生的数据,还有其他的参数如latest
2.7 删除topic
/opt/apps/kafka_2.12-2.4.1/bin/kafka-topics.sh --delete --topic rulesTopic --zookeeper localhost:2181
2.8 查看topic详细信息
/opt/apps/kafka_2.12-2.6.2/bin/kafka-topics.sh --zookeeper linux01:2181 --describe
--topic test1
2.9 查看某个topic的偏移量
/opt/apps/kafka_2.12-2.6.2/bin/kafka-console-consumer.sh --topic __consumer_offsets --bootstrap-server linux01:9092,linux02:9092,linux03:9092 --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config /opt/apps/kafka_2.12-2.6.2/config/consumer.properties --from-beginning
三、概念
3.1 producter写入的策略
数据的写入:会攒一批,然后再写入,而不是来一条写一条
1)若不指定key,不指定分区,则会轮巡写入,先往一个分区写一批,然后再换个分区写一批,轮流着 写。。。
2)若指定分区,则只会往指定的分区写
3)若指定key,则相同的key会跑到同一个分区,但同一个分区会有多个key,原理也是key取哈希值再模 分区数
3.2 偏移量
有三个因素决定:topic,分区,组id
topic不同 或者分区编号不同,或者组id不同,所记录的偏移量是不同的,只有偏移量的记录是分开的,就不会混乱
----偏移量
1)默认是自动提交偏移量,默认提交时间是5秒,这两个参数都可以更改
当把自动提交偏移量的参数改为false的时候,下次再读取的时候,就是从头读,因为没有记录偏移 量
2)--consumer_offsets一个特殊的topic,有50个分区,1个副本。所有自动提交偏移量的消费者都会 将偏移量写道这个topic中.这也预示着创建topic的时候不能用 下划线和点
有个缺点,默认是5秒保存一次偏移量,加入消费者将数据消费了,但是还没来得及提交偏移量就 挂掉了,这样便会造成数据的重复读取,可能会出问题
解决方式应该提交到事物中,偏移量提交成功了就消费,提交不成功就将数据回滚。
---手动提交偏移量:
1)同步提交--阻塞的 -->不提交完程序不往下进行
2)异步提交--异步的 -->开一个线程来提交偏移量,不会阻塞
3)手动指定偏移量提交的内容--同步提交--> 可以将偏移量中的数据取出来,然后手动提交部分 内容,比如不把每个偏移量都提交,而是把每个分区的最大偏移量取出来提交
4)手动指定偏移量提交的内容--异步提交,并且有回调函数-->
5)可能以后会把偏移量提交到mysql中等...
3.3 消费者组
1)同一个消费者组不会消费同样的数据,当消费数据的时候会更新偏移量,如果停掉再打开,即使是从 头开始消费,之前的数据也不会取到
2)同一个消费组内的不同消费者不会消费同一个分区的数据,换句话说,一个分区的数据,不能被同一 个组内的不同消费者消费,但可以被不同组的消费者同时消费,此时若将组id改了,再从头earliest 读数据,则可以读取到,若改为latest,即最近的,则只会读取新产生的数据
假设有4个分区,若一个组内的消费者有3个,则会有一个消费者消费两个分区的数据
若一个组内的消费者有4个,则一个消费者消费一个分区的数据
若一个组内的消费者有5个,则一个消费者消费一个分区的数据,剩下的一个 会一直等待,直到有个消费者挂掉了,便接替那个消费者所消费的分区的数据
四、Kafka 与 Idea
需要在虚拟机中开启zookeeper和Kafka
—生产者
object ProducerDemo {
def main(args: Array[String]): Unit = {
// 1 配置参数
val props = new Properties()
// 连接kafka节点
props.setProperty("bootstrap.servers", "linux01:9092,linux02:9092,linux03:9092")
//指定key序列化方式
props.setProperty("key.serializer"

最低0.47元/天 解锁文章
1299

被折叠的 条评论
为什么被折叠?



