努力学习都是为了自己的名字有一个好的归宿。加油!
“士由百折不挠之真心,方有万变无穷之妙用”
为本次kafka专栏做一个强化记忆专栏,都是自己看完以后理解,用尽量最少的语言对问题进行解答,第一次发表文章,难免有考虑不周的地方,还请见谅。
kafka的基本架构
?基础概念扫盲
消息生产者,是消息的产生源头,负责生成消息并发送给Kafka
消息消费者,是消息的使用方,负责消费Kafka服务器上的消息
主题,由用户自定义,并配置在Kafka服务器,用于建立生产者和消费者之间的订阅关系,生产者将消息发送到指定的Topic,然后消费者再从该Topic下去取消息。
消息分区,一个Topic下面会有多个Partition,每个Partition都是一个有序队列,Partition中的每条消息都会被分配一个有序的id
这个其实就是Kafka服务器了,无论是单台Kafka还是集群,被统一叫做Broker,有的资料上把它翻译为代理或经纪人。
消费者分组,将同一类的消费者归类到一个组里。在Kafka中,多个消费者共同消费一个Topic下的消息,每个消费者消费其中的部分消息,这些消费者就组成了一个分组,拥有同一个组名。
面试题
请简述kafka数据分区和消费者的关系?
? 对于每个消费者分组,Kafka都会为其分配一个全局唯一的Group ID,分组内的所有消费者会共享该ID, Kafka还会为每个消费者分配一个consumer ID,通常采用hostname:uuid的形式。
? 在kafka的设计中规定,对于topic的每个分区,最多只能被一个消费者进行消费,也就是消费者与分区的关系是一对多的关系。消费者与分区的关系也被存储在ZooKeeper中节点为{}该节点的内容就是消费者的Consumer ID。?
Kafka消息数据积压,Kafka消费能力不足怎么处理?
- 增加 topic 的 partition 的个数,同时提升消费者组的消费者数量
-
若是下游数据处理不及时,则提高每批次拉取的数量。?
Kafka中的数据如何保障不丢失?
?
原因:由于生产者是以push的方式将消息写入topic某个分区leader,写入之后Follower主动去拉取,需要设置参数保证消息不丢失
Ack参数决定了可靠程度
Asks这个参数是生产者客户端的重要配置,发送消息的时候就可设置这个参数。该参数有三个值可配置:0、1、All
第一种是设为0,意思是生产者把消息发送出去之后,之后这消息是死是活咱就不管了,有那么点发后即忘的意思,自然消息就有可能丢失。
第二种是设为1,意思是生产者把消息发送出去之后,这消息只要顺利传达给了Leader,其他Follower有没有同步就无所谓了。存在一种情况,Leader刚收到了消息,Follower还没来得及同步Broker就宕机了,但生产者已经认为消息发送成功了,那么此时消息就丢失了。
第三种是设为All(或者-1),意思是生产者把消息发送出去之后,不仅Leader要接收到,ISR列表中的Follower也要同步到,生产者才会任务消息发送成功。
?我们进一步思考,设置为all就不会丢失了吗?答案是否!当ISR中只有Leader时,Asks=All 相当于Asks=1,这种情况下节点宕机,没有剩余节点顶替,就完蛋了。所以要想保证数据不丢失就必须在保证Acks=All时并且ISR列表中至少还有两个副本。
?消费者消费的进度通过offset保存在Kafka集群的__consumer_offsets这个topic
消费者端配置参数:enable.auto.commit=false,禁止自动提交offset,避免多线程消费时出现消息丢失。
? 总而言之,kafka写入的数据不丢失要必须保证至少一个Follower在ISR里面,跟得上Leader数据的同步,每一条数据写入成功必须要有两个副本,万一宕机,还可以切换
采集数据为什么要使用Kafka??
一般在项目中都是flume和kafka联用,他们各自的特性可以进行互补,提高项目的运行效率和稳定性,以下几点是对此问题的一些粗浅理解:
从数据角度类型:.生产环境中都是读取日志进行分析,而这往往是多数据源的,如果kafka构建多个生产者方式向主题发送数据,无疑是很麻烦的
?从拦截数据角度:.flume可以使用拦截器实时处理数据,而kafka必须依靠外部流处理系统。
从高可用角度:在flume中没有副本概念的,如果flume代理的一个节点崩溃了,恢复数据还要等到磁盘完全恢复,如果你需要一个高可靠行的管道,那么使用Kafka是个更好的选择。
从数据缓存角度:.如果flume直接对接实时计算框架,当数据采集速度大于数据处理速度时,必然会发生数据积压和数据丢失,而kafka当做一个消息缓存队列,从广义上理解,把他当做一个数据库,可以存放一段时间的数据
kafka的其他特性:
削峰
系统可以按照数据库能处理的并发量,从消息队列中慢慢拉取,这个短暂的高峰期积压是可以的。
高并发:支持数千个客户端同时读写
容错性:在kafka的一个topic中有多个分区,每个分区在若干服务中都有副本,这些持有副本的服务可以共同处理数据和请求,同时可以设置数量,保证kafka的一个容错性。
Kafka的数据是放在磁盘还是内存,为什么速度会快?
先不说他的数据到底存放在哪里,先说他为什么快?
你可能会认为:在磁盘上读写数据是会降低性能的,因为-!-寻址-!-会比较消耗时间,事实上,磁盘的读写速度关键在于你如何使用他
顺序写入
Kafka在设计时采用了文件追加的方式写入消息,即只能在日志文件的尾部追加新消息,并且不允许修改已写入的消息,这种方式属于典型的顺序写盘的操作,因此就算Kafka使用磁盘作为存储介质,它所能承载的吞吐量也很大。(磁盘顺序写比内存随机写还要快)
页缓存
虽然Kafka 会持久化所有数据到磁盘,但是本质上写入操作都是把他写到系统的页缓存,然后由操作系统来决定什么时候写入到磁盘,因为它是由内存分配的,不用直接和底层文件打交道
零拷贝
直接从磁盘文件复制到网卡设备,减少其中繁琐的多次复制和上下文切换
?
只是将包含图片数据的位置和长度信息的特殊描述符(Descriptor)加载到SocketBuffer中。?明显少了两次复制到socket套接字中的次数,并且减少了上下文切换的次数(具体描述自己CSDN),就不在此多余赘述,理解就好。
?
?
|