kafka详解(持续更新中)

遗留问题:1、kafka能否保证单一消费
                  2、消息是又谁决定到哪个partition的
                  3、消费者获取消息的整个流程
                  4、两种索引文件的分别的应用场景

一、总体介绍:

1、kafka是什么?
      kafka是一个分布式消息队列,基于发布/订阅的模式

2、那么多消息队列,为什么kafka现在比较火?
      先思考,作为一个消息队列,怕遇到什么问题:1)吞吐量不够,导致并发消费效果不理想
                                                                                  2)访问速度不高,其实也是影响吞吐量的一个因素
                                                                                  3)因各种故障而导致的消息丢失
                                                                                  4)能否保证在任何情况下的单一消费
                                                                                  5)当吞吐量不足或者其他因素时,是否容易拓展
      看看kafka如何解决这些问题:kafka选用时间复杂度为o(1)的磁盘存储结构,保证了一个常数时间的访问速度,相当短的访问时间保证了高吞吐量,达到了在廉价商用机上也能达到单机每秒10万条数据的传输。kafka是一个通过zookeeper管控的集群,将数据分为逻辑上的topic,topic分为物理上的分区,分区又有多个副本。每个分区文件(包括那些副本)分布在不同的节点上,我们把这里的节点叫做broker,这样保证了某个节点出现异常,数据本身因为在其他broker上有副本,就不会丢数据。(其实是以空间换保障,有失有得)。关于第四点,kafka能否保证单一消费,有待考究,路过的各位大佬如果有知道麻烦告知。最后,kafka通过和zookeeper的配合管理,让其拓展变得简单,后面会讲解。

3、利用kafka有什么好处(或者,利用消息队列有什么好处)
      首先,从系统层面来说,对应用进行解耦,解耦的目的是为了方便维护系统,应用和应用之间单独维护。
      其次,从数据处理层面来说,可以对数据进行暂时的存储,生产者只管生产,消费者想消费就去消费,特别是在消息出现峰值,生产者生产速度比消费者的消费速度大很多倍的时候,系统可以稳住。

二、详细介绍

1、kafka逻辑上有topic的概念,意指同一类数据。topic中又会划分为分区,这是物理概念,一个分区对应一个物理路径。物理路径里面有数据文件和索引文件。
2、生产者往topic里面生产数据,前面说了topic是一个逻辑概念,所以实际上是往partition中放数据。那么有那么多个partition,难道生产者自己要知道放到哪个partition中吗?我认为不是的,应该是由kafka controller leader去负责将消息放到哪个分区中去,有待考证
3、partition的目录中,有数据文件和索引文件,数据文件是以消息在整个partition中的偏移量命名的,.log后缀。索引文件分为偏移量索引,.index后缀,时间戳索引,.timeindex后缀。那么有个问题,实际在读取数据的时候,流程是怎样的?我理解是,消费者从zookeeper中得到partition的位置和对应消息的偏移量,然后先找到partition所在的位置,通过文件名上的偏移量可以知道消息在哪个segment文件中,再找这个文件的索引文件,通过索引过去找到消息,读取出来。待求证另外就是,两种索引文件的使用场景分别是什么
4、那么说到这,从分布式集群的角度出发,考虑数据的存储可能存在的问题。如何保证partition的数据均衡问题?这是因为集群中有一个节点会有一个线程是controller leader,负责管理分区和副本的状态,包括数据均衡问题。
5、再回来说partition和副本的问题。partition数和副本数,都可以人为设。在每个partition所有的副本中,会选取出来一个partition leader,其他的是follower。那么问题来了,如何实现消息同步?机制是follower去跟leader同步消息。
6、那么,一个topic下,又是分区又是副本,可能数量还不少,怎么维护?这里就有个东西叫ISR列表,保存在zookeeper中,里面放的是每个partition的除了partition leader之外的活着的副本,有什么用呢?那么平时partition leader和follower都正常的时候,作用不大,follower去跟leader同步消息,表明这个follower还是正常的,leader就没啥动作。一旦partition leader发现某个follower很久没来了(没发送心跳),leader会认为这个follower挂了,就去ISR列表中把它移除掉。为什么要去移除掉?这是为了保证这个列表中的follower都是活的,万一哪天partition leader自己挂了,controller leader就会去找zookeeper要这个列表,从里面选一个follower成为partition leader,有种备胎转正的感觉。
7、回顾一下,我们这里说了两个leader,一个是controller leader,是节点层面的,及broker。一个是partition leader,是分区层面的。他俩都是怎么选出来的呢?首先是每个broker启动后,都会去zookeeper中注册自己的信息,这样zookeeper其实就知道整个集群的每个节点的信息,所以由zookeeper选举出来一个节点作为controller leader。还记不记得,zookeeper中还保留着ISR列表,那么选举出来的controller leader就会去ISR列表中为每个partition选一个partition leader。
8、回过头来看看zookeeper,zookeeper干的事有:选举controller leader、维护集群节点信息、维护集群拓展、保证消费者来消费时broker的负载均衡(这里包括新增消费者和原有消费者所在的consumer group变化)。说多不算多,说少也不算少。这里要提的一点是,为什么zookeeper只是保留了ISR而不去负责选举partition leader?因为zookeeper一直定义为是一个轻量级的框架,就是说不能在zookeeper上有夸张的计算消耗,所以如果zookeeper去负责partition leader的选举,那么因为多个partition的多个副本,总的数据量不会少,要在这么多的数据中运算并得到一个结果,zookeeper吃不消。zookeeper的角色定位一直是负责维护元信息等一些不需要频繁操作的动作,符合它轻量级的概念。
9、kafka的消费者方面,有消费者和消费者组。每个消费者属于一个消费者组,一个消费者组可以有多个消费者。一个partition只能被同一个消费者组中的一个消费者消费,所以对于同一个组中的不同消费者,会去消费不同的partition,这样可以让消息被均衡消费。反过来,如果有不同消费者,是属于不同的消费者组,但是是对同一个topic进行消费,那么就可能会发生同一个partition被不同的消费者消费。

猜你喜欢

转载自blog.csdn.net/Michael_Zheng_Tech/article/details/82670260