kafka必修课

 Kafkas是什么?     

      Kafka是一个分布式消息队列, 也是一个开源消息系统Scala语言写成kafka对消息保存时根据Topic进行归类发送消息者称为Producer消息接受者称为Consumer此外 kafka集群有多个kafka实例组成每个实例(server)称为broker无论是kafka集群还是consumer都依赖于zookeeper集群保存一些mate信息来保证系统可用性。在通常的流式计算中kafka 一般用来缓存数据Storm或者Spark Streaming通过消费kafka的数据进行计算

Kafka架构分析图:

(1)Producer:消息生产者,就是向kafka broker发消息的客户端。
(2)Consumer:消息消费者,向kafka broker取消息的客户端。
(3)Topic:可以理解为一个队列。

(4)ConsumerGroup(CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CGtopic 的消息会复制(不是真的复制是概念上的)到所有的CG但每个partition只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic
(5)Broker:一台kafka服务器就是一个broker一个集群由多个broker组成。一个broker可以容纳多个topic
(6)Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的idoffset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition 间)的顺序。
(7)Offset: kafka的存储文件都是按照offset.kafka来命名offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可当然the first offset就是00000000000.kafka

Kafka生产过程分析:

(1)写入方式: producer采用推(push)模式将消息发布到broker,每条消息都被追加 (append)到分区(partition)中,属于顺序写磁盘(顺序写磁盘效率比随机写内存要高,保障kafka吞吐率)。

(2)分区(Partition):消息发送时都被发送到一个topic,其本质就是一个目录,而 topic是由一些 Partition Logs(分区日志)组成, 其组织结构如下图所示

 

每个Partition中的消息都是有序生产的消息被不断追加到Partition log其中的每一个消息都被赋予了一个唯一的offset

(3)分区的原因:
a方便在集群中扩展每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成因此整个集群就可以适应任意大小的数据了。
b、可以提高并发因为可以以Partition为单位读写了。

(4)分区的原则:

a指定了partition则直接使用。

  1. 未指定partition但指定key通过对keyvalue进行hash出一个partition
  2. partitionkey都未指定使用轮询选出一个partition

(5)副本(Replication):

同一个partition可能会有多个replication(对应server.properties配置中的default.replication.factor=N)。没有replication的情况下,一旦broker宕机,其上所有patition的数据都不可被消费,同时producer 也不能再将数据存于其上的 patition。引入replication之后,同一个partition可能会有多个replication,而这时需要在这些replication之间选出一个leaderproducerconsumer只与这个leader 交互,其它replication作为followerleader中复制数据。

(6)写入流程:

producer写入消息流程如下:

aproducer先从zookeeper"/brokers/.../state"节点找到该partitionleader
bproducer将消息发送给该leader
cleader将消息写入本地log
dfollowersleader pull消息写入本地log后向leader发送ACK

eleader收到所有ISR中的replicationACK增加HWhigh watermark最后commitoffset并向producer发送ACK

(7)Broker保存消息

a存储方式

物理上把topic分成一个或多个partition(对应server.properties中的 num.partitions=3配置),每个partition物理上对应一个文件夹(该文件夹存储该 partition 的所有消息和索引文件)。

b存储策略

   无论消息是否被消费,kafka都会保留所有消息。有两种策略可以删除旧数据基于时间: log.retention.hours=168

基于大小: log.retention.bytes=1073741824
需要注意的是,因为kafka读取特定消息的时间复杂度为O(1),即与文件大小无关,所以删除过期文件与提高kafka性能无关。

Kafka生产过程分析:

kafka提供了两套consumer API:高级Consumer API和低级Consumer API

(1)高级API

优点

高级API写起来简单。
不需要自行去管理offset,系统通过zookeeper自行管理。
不需要管理分区,副本等情况,系统自动管理。
消费者断线会自动根据上一次记录在zookeeper中的offset去接着获取数据(默认设置1分钟更新一下zookeeper中存的offset可以使用group来区分对同一个topic的不同程序访问分离开来(不同的group记录不同的offset,这样不同程序读取同一个topic才不会因为offset互相影响)。

缺点

     不能自行控制offset对于某些特殊需求来说
不能细化控制如分区、副本、zk 等。

(2)低级API

优点

      能够让开发者自己控制offset,想从哪里读取就从哪里读取。
自行控制连接分区,对分区自定义进行负载均衡。
zookeeper的依赖性降低(如:offset 不一定非要靠zk存储,自行存储 offset即可,比如存在文件或者内存中)。

   缺点

     太过复杂,需要自行控制offset,连接哪个分区,找到分区leader 等。

(3)消费者组

消费者是以consumer group 消费者组的方式工作,由一个或者多个消费者组成一个组,共同消费一个topic。每个分区在同一时间只能由group中的一个消费者读取但是多个group可以同时消费这个partition。在图中,有一个由三个消费者组成的group有一个消费者读取主题中的两个分区,另外两个分别读取一个分区。某个消费者读取某个分区,也可以叫做某个消费者是某个分区的拥有者。
    在这种情况下消费者可以通过水平扩展的方式同时读取大量的消息。另外,如果一个消费者失败了,那么其他的group 成员会自动负载均衡读取之前失败的消费者读取的分区。

(4)消费方式

consumer采用pull(拉)模式从broker中读取数据push(推)模式很难适应消费速率不同的消费者因为消息发送速率是由broker决定的它的目标是尽可能以最快速度传递消息但是这样很容易造成consumer来不及处理消息典型的表现就是拒绝服务以及网络拥塞pull模式则可以根据consumer的消费能力以适当的速率消费消息对于kafka而言,pull模式更合适它可简化broker的设计consumer可自主控制消费消息的速率同时consumer可以自己控制消费方式即可批量消费也可逐条消费,同时还能选择不同的提交方式从而实现不同的传输语义pull模式不足之处是,如果kafka没有数据消费者可能会陷入循环中一直等待数据到达为了避免这种情况,可以在拉请求中有参数允许消费者请求在等待数据到达的长轮询中进行阻塞(并且可选地等待到给定的字节数,以确保大的传输大小)

猜你喜欢

转载自blog.csdn.net/SHYLOGO/article/details/107973710