分布式消息中间件(kafka问答篇)

本文主要记录一些kafka常见问题,希望给大家带来帮助

1.如何使用kafka做日志处理?

这也是kafka常用地点之一了

分布式消息中间件(kafka问答篇)_第1张图片

每次有日志的时候我们就可以调用kafka来进行发送日志消息到队列中,然后消费者应用我们可以使用,logstash

获取日志信息,然后将消息发送到elasticsearch中进行存储,分词。使用的时候 我们可以bibana来进行可视化阅读操作。(ELK+kafka就是这么简单)

2.kafka有什么优缺点 

1.发送消息快,吞吐量号称最高的MQ

2.消费速度追加了消费者组的概念,使其批量消费的时候速度也很快

3.动态扩展,只需要在zk中注册地址,就可以形成新的节点,是在是方便。(相比之下rabbitMQ的集群是真的麻烦

并且不支持动态扩展)

什么东西都有两面性,有优点自然就有缺点; 

1.系统可用性变低,因为加入了大量的第三方中间件导致系统维护麻烦,如果kafka是单机运行的话,一旦宕机了,那么会导致整个系统都不可用。

2.系统复杂度提高(要注意消费者的幂等性,和消息能够到达broker中)

3.一致性问题,a,b,c三个系统a调用B,B调用C,ab执行成功,C执行失败这样就出现了,数据不一致性问题,这时候要基于分布式事务的最终一致性理论进行补偿机制来确保C的成功执行。

3.kafka有几种消费语意

3种

1.消息最多被消费一次(消息可能会丢失,但是不会重复发送,特点是吐吞量是最高的,这种情况是不会出现消息重复消费的因为你的消息就只会消费一次嘛)

2.至少消费一次(无法容忍消息丢失,但是容忍消费重复的情况)

3.刚好消费一次(producer发消息的时候使用消息确认到达机制,consumer消费的时候使用唯一id来保证消息的幂等操作这样就可以自动手动来进行确认消费操作 ack)

4.kafka的消费模式。

kakf采用的拉(pull)的模式此模式的有点在理论篇已经有所讲述

5.如何保证生产者的发送消息的可靠性?

开启ack确认模式,kafka的确认模式分为3种

参数0,不需要broker确认消息producer只管发送一次

参数1,只要leader确认成功就发送下一条消息,不管从机是否确认成功(如果这个时候主机刚好挂了,消息就丢了)

参数all.所有的leader和followers都确认成功才会发送下一跳消息

6.kafka是否出现消息丢失的情况,如果会如何处理?

kafka单机的时候如果单机挂掉了,就会出现消息丢失的情况,这个时候我们就需要使用kafka集群了。

7.kakfa是否支持动态扩展?为什么支持

kafka支持动态扩展,因为kafka的集群管理信息是由zookeeper来管理的,我们添加节点的时候,只需要将新的broker嘻嘻注册到zookeeper中,kakfa内部会自动的将broker信息,复制到的新的节点上,这样就实现动态扩展

8.kafka和其它MQ相比优点

1.同时为发布和订阅提供高吞吐量。据了解,Kafka 每秒可以生产约 25 万消息(50MB),每秒处理 55 万消息(110MB)。

2.动态扩展

3.消费者的消费记录记录在消费者端,同一个消费者组内部可以进行异常偏移,a消费者消费失败之后,会分配到b消费者进行消费

4.利用了磁盘的顺序读写功能,并且消息最初是在页缓存中保存,速度也是高的一批

5.数据批量发送,批量消费

6.数据压缩(kafk一大特点,可以减少大数据量的体积,内部已经实现了极高的压缩,但是需要配置)

7.内部使用partition机制,使其并行程度大大提高

9.谈谈对kafka内部topic,partition,offset理解

topic在kafka中指的是一个主题主题中可以有个partition,主题之间是相互隔离的。

partition是主题中的分区,每个分区可以代码一个业务逻辑,也可以多个分区同属于一个业务逻辑。有了分区的概念,我们topic中就不会出现说一个队列有大量的信息,导致性能瓶颈问题的出现。partition大大增加了kafka的并发处理能力

offset 偏移量是在partition中的概念,它是记录了每个消息的数值,是一个顺序排列的队列,每当消费者消费的时候都会从offset寻找未被消费的消息进行消费,消息被成功消费后,offset会移动自己的位置。但是不会删除,如果想要删除信息,可以在broker指定消息的删除策略。

10.kafka消息发送和消费简单流程

分布式消息中间件(kafka问答篇)_第2张图片

  • 1、Producer ,根据指定的 partition 方法(round-robin、hash等),将消息发布到指定 Topic 的 Partition 里面。
  • 2、Kafka 集群,接收到 Producer 发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否被消费。
  • 3、Consumer ,从 Kafka 集群 pull 数据,并控制获取消息的 offset 。至于消费的进度,可手动或者自动提交给 Kafka 集群。

producer发送消息之后会将消息已append的方式写入partition中,partition的路由机制为

1.指定具体的partition,然后顺序写入此partition中

2.未指定partition,但是有消息的key,通过对key做一个hash算法选出一个partition

3.没有指定key,则使用轮询的方式来指定一个partition

broker存储机制,把topic分成多个partition,每个partition占用一个物理地址

consumer消费消息

一个消息只能被同一个消费者组的一个消费者进行消费,消费完成之后会在broker记录消费的位置,这个由broker内部进行设置和consumer无关,下次进行消费的时候需要从broker读取出offset的位置然后进行其他消息的消费。

要注意的点

1.分区数要>消费者数量(否则将会出现消费者没有分区消费的情况)

2.如果一个消费者消费多个partition内的消息,那可能此分区的消息顺序无法有保证,因为在确认的时候会产生延迟

11.kafka发送消息的时候异步和同步的区别

默认模式是异步,发送消息之后使用callback的方式来验证是否发送成功,这个也是经常使用的一种方式

同步方式:在每次发送消息之后使用producer.send("Message").get()

使用这种方式 线程会一直等待下去,直到写入成功或者出现异常,这样吞吐量特别低,可以保证无消息丢失。

注意,不管是同步还是异步kafka发送消息的时候都有可能失败,异常原因大致如下

1.分区的leadr主副本不可用,出现原因broker内部在实现leader换届选举,重试字后可以自行恢复

2.NotControllerException 这说明broker内部的controller在进行选举

3.网络延迟波动

上面的三种异常方式都可以通过重试的方法来解决

12说说kafka的序列化机制

kafka内部有提供十几种序列化器大致如下

StringSerializer

IntegerSerializer

LongSerializer等

使用序列化机制可以很大的程度上保护消息的安全性。

13.说说producer的拦截器

produce拦截器可以在消息即将发送之前最消息做一下序列化了,消息改变了,等处理

主要方法为onSend(ProducerRecord) 可以将修改后的消息重新封装放入里面,但是不要在这个方法里面修改kafka的分区。否则会影响分区计算

 onAcknowledgement(RecordMetadata, Exception) 会在消息被应答之前或消息发送失败调用。

14.kafka如何保证消息的顺序性

在producer中配置max.in.flight.requests.per.connection=1

保证了发送消息的时候如果上一条没到达broker就不会再给broker发送消息

15.当一个消息过于大导致发送太慢怎么办

这个时候我们可以引入kafka的压缩机制,kafka内部支持的压缩机制是比较完善的我们可以配置压缩算法为LZ4这个时候消息变小了,吐吞量也达到了最佳。

16. kafka中consumer group的作用

消费者用一个组id来标记自己,topic的每条消息都会发送到每个订阅它的消费者组的一个消费者实例上。即为:

实现了消费者的高伸缩性,高容错性的消费机制,组内多个consumer实例可以同时读取kafka的消息,而当有一个consumer挂了的时候,消费者组会将已经崩溃的消费者负责的分区转交给其它consumer的来进行消费从而达到重平衡(rebalance)的效。

17.什么是消费者组的重平衡(consumer group rebalance)

这是group中一个非常重要的概念,也是实现消费者故障转移的一个重要机制。本质是一个协议规定了 consumer group下所有的consumer如何达成一致来分配订阅topic的所有分区(这属于官方回答)

举例: 我们有一个conusmer group,group中有20个consumer,现在有100个分区,那么这个时候kafk就会将这100个分区,平均的分配给每个consumer5个分区,这个分配的过程就叫(rebalance)

18.如何为kafka挑选合适的分区数

1.我们在定分区数的时候不能认为分区数越多,kafkad吐吞量越高,其实它是有一个阀值的,超过这个阀值的时候由于硬件等关系跟不上,所以吞吐量有可能变的更低了。并且kafka在某个节点挂掉的时候,如果节点中存在大量的分区,那么在进行选举的时候会导致这些分区都不可用,造成kafka的短暂性失联。

19.kafka主题中分区数为什么不是越多越好

因为任何服务器都有自己的极限,超过自己的极限之后,吞吐量自然不会在继续上升还有可能下降,所以我们在生产环境定分区的时候可以使用压测软件,测试出最好的临界值达到最佳吐吞量。 有些小伙伴可能会想那我设置小点就可以了,设置小点可以满足当时的吞吐量,但是后续如果集群中的节点不断增加,那么会造成资源浪费,并且个人推荐 在使kafka的时候,分区就设置好,因为后续再新加分区的时候,又会进行重平衡(有可能会使kakfa短暂失去效应)

20.为什么kafka的分区不支持减少

因为分区在创建之后,会被分配对应的资源,消息,消费者等,当这个分区被删除之后,kafka内部会将这些数据分配给其它消费者但是有时候会造成被删除分区内部的消息可靠性得不到保障

21.什么是 kafka的无位移信息,和位移越界

这个知识点属于kafka的消费者配置。

假设我们在运行消费者的时候使用的是 auto.offset.reset=earliest(表示每次消费的时候都从最早的位移开始),使用了这种消费策略,可能会出现,重启消费者组之后,依然重头消费,但是由于消息已经被消费了所有出出现consume group无法消费的情况

这个时候我们需要实用将earliest修改成latest即可(从最新的位置开始消费)

22. kafka 如何实现延时队列(如果想实现分布式事务OR或者订单延时消费还是建议上rabbitMQ,kafka感觉太鸡肋)

kafka中延时队列和rabbitMQ中的延时消费有一定的区别由于rabbit的消费方式是发布订阅(具体的可查看笔者的rabbit篇),kafka的消费方式是poll。其实kafka每次消费的时候都是从broker中拉取的消息,我们只需要在comsumer.poll(1000) 中间的参数为超时时间,因为kafka消费的时候是循环拉取的,我们设置一个超时时间可以达到延时消费的效果。

 

                                                                                                 -------------------本文知识储备均来自于蚂蚁课堂,感谢余总的指点

你可能感兴趣的:(Kafka,分布式解决方案)