Kafka基础知识

1. 消息队列

“消息队列”( Message Queue,MQ)从字面来理解,是一个队列,拥有先进先出的特性。它主要用于不同进程或线程之间的通信,用来处理一系列的输入请求。
在高并发的应用场景中需要一个缓冲机制,消息队列则可以很好地充当这样一个角色。消息队列通过异步处理请求来缓解系统的压力。

2. 消息队列主要作用

应用解耦:多个应用可通过消息队列对相同的消息进行处理,应用之间相互独立,互不影响;
异步处理:相比于串行和并行处理,异步处理可以减少处理的时间;
数据限流:流量高峰期,可通过消息队列来控制流量,避免流量过大而引起应用系统崩溃;
消息通信:实现点对点消息队列或聊天室等。

3. Kafka基本概念

代理:在Kafka集群中,一个Kafka进程(Kafka进程又称为Kafka实例)被称为一个代理(Broker)节点。代理节点是消息队列中的一个常用概念。通常,在部署分布式Kafka集群时,一台服务器上部署一个Kafka实例。

生产者:Producer将消息记录发送到Kafka集群指定的主题(Topic)中进行存储,同时生产者(Producer)也能通过自定义算法决定将消息记录发送到哪个分区(Partition)。

消费者:消费者(Consumer)从Kafka集群指定的主题(Topic)中读取消息记录。在读取主题数据时,需要设置消费组名(GroupId)。如果不设置,则Kafka消费者会默认生成一个消费组名称。一个分区的数据只能被同一个消费组的一个消费者消费,可被不同消费者组同时消费。

消费者组:消费者程序在读取Kafka系统主题(Topic)中的数据时,通常会使用多个线程来执行。**一个消费者组可以包含一个或多个消费者程序,使用多分区和多线程模式可以极大提高读取数据的效率。**一般而言,一个消费者对应一个线程。在给应用程序设置线程数量时,遵循“线程数(消费者数量)小于等于分区数”原则。如果线程数大于分区数,则多余的线程不会消费分区中的数据,这样会造成资源浪费。

主题:Kafka系统通过主题来区分不同业务类型的消息记录。生产和消费都需要指定主题,只能生产到该主题,或只能消费该主题的消息。

分区:**每一个主题(Topic)中可以有一个或者多个分区(Partition)。**在Kafka系统的设计思想中 分区是基于物理层面上的 不同的分区对应着不同的数据文件。Kafka通过分区(Partition)来支持物理层面上的并发读写,以提高Kafka集群的吞吐量。每个分区(Partition)内部的消息记录是有序的,每个消息都有一个连续的偏移量序号(Offset)。一个分区只对应一个代理节点(Broker),一个代理节点可以管理多个分区。

副本:在Kafka系统中,**每个主题(Topic)在创建时会要求指定它的副本数,默认是1。**通过副本(Replication)机制来保证Kafka分布式集群数据的高可用性。在创建主题时, 题的副本系数值应如下设置:(1)若集群数量大于等于3,则主题的副本系数值可以设置为3(也可以更大,要小于等于broker数量);(2)若集群数量小于3,则主题的副本系数值可以设置为小于等于集群数量值。

记录:被实际写入到Kafka集群并且可以被消费者应用程序读取的数据,被称为记录(Record)。每条记录包含一个键(Key)、值(Value)和时间戳(Timestamp)。

4. Kafka工作机制-生产消息、消费消息

Kafka作为一个消息队列系统,**其核心机制就是生产消息和消费消息。**在Kafka基本结构中,生产者(Producer)组件和消费者(Consumer)组件互不影响,但又是必须存在的。缺少生产者和消费者中的任意一方,整个Kafka消息队列系统将是不完整的。

生产者(Producer)负责写入消息数据。将审计日志、服务日志、数据库、移动App日志,以及其他类型的日志主动推送到Kafka集群进行存储。

消费者(Consumer)负责读取消息数据。例如,通过Hadoop的应用接口、Spark的应用接口、Storm的应用接口、ElasticSearch的应用接口,以及其他自定义服务的应用接口,主动拉取Kafka集群中的消息数据。

另外,Kafka是一个分布式系统,用Zookeeper来管理、协调Kafka集群的各个代理(Broker)节点。当Kafka集群中新添加了一个代理节点,或者某一台代理节点出现故障时,Zookeeper服务将会通知生产者应用程序和消费者应用程序去其他的正常代理节点读写。

5. 需要满足的需求

高吞吐量、高可用性、低延时、分布式

6. Kafka特性

  1. 异步生产数据:从Kafka0.8.2起,生产者(Producer)写数据时不再区分同步和异步,所有的操作请求均以异步的方式发送,这样大大地提高了客户端写数据的效率。异步方式将数据批量的发送到Kafka不同的代理(Broker)节点,因此也减少了Kafka服务端的资源开销。这种方式在与Kafka系统进行网络通信时,能够有效地减少等待时间。(发送缓冲队列+批量发送,发送使用单独线程,从缓冲队列拉去16k消息发送,缓冲队列大小可配置,批量发送大小可配置,当消息大小始终小于16k,可设置最小发送时间。)

  2. 偏移量迁移:从Kafka0.8.2版本开始,消费者(Consumer)应用程序可以把“消费”记录提交到Kafka集群,并以内部主题的方式进行存储,Kafka系统将其命名为**__consumer_offsets**。一直持续到Kafka0.10.0版本,Kafka官网才将该特性设置为默认属性。

  3. 安全机制:在Kafka0.9版本以后,系统添加了安全机制,可以通过SSL和SASL安全机制来进行身份确认。生产者(Producer)和消费者(Consumer)必须进行身份验证,才能操作Kafka集群。另外,Kafka代理(Broker)与Zookeeper集群进行连接时也需要身份验证。在设置了安全机制的Kafka集群中,数据均采用加密方式进行传输。由于加密方式依赖操作系统的CPU和Java虚拟机(Java VirtualMachine,JVM),所以,在采用加密方式传输数据时性能可能会降低。

  4. 连接器:Kafka在0.9版本中,添加了一个名为Connect的模块,即连接器。从命名上来看,它可以在外部系统与数据集之间建立一个数据流管道,以实现数据的读与写。Kafka使用了一个通用的框架,可以在这个框架上非常便捷地开发和管理Kafka连接器(Connect)接口。Kafka连接器还支持在分布式模式或者单机模式下运行,并可以通过REST API提交和管理Kafka集群。

  5. 机架感知:需要使用机架感知来让Kafka的备份数据分布到不同的机架上,以保证数据的高可用性。

  6. 数据流:在Kafka 0.10及以后版本中,添加了数据流特性。在实际业务场景中,如需将Kafka集群中的数据进行流处理之后再重新回写到Kafka集群中,那使用Kafka Streams(数据流)这一特性能够很轻易地实现。

  7. 时间戳:在Kafka0.10及以后版本中,生产者(Producer)写入的每一条消息记录都加入了时间戳(Timestamp)。在写入消息的过程中,如果用户没有指定该消息的时间,则该消息的时间会被自动添加上。

  8. 消息语义:在Kafka 0.11.0.0版本中,实现了消息记录只处理一次(ExactlyOnce Semantics,EOS)。在Kafka中,单个代理(Broker)节点可能会出现宕机,或者生产者(Producer)在向Kafka集群主题(Topic)发送消息时出现网络故障。Kafka生产者在处理这类异常行为时会有以下几种不同语义。
    1.至少一次:如果在Kafka中设置ACKS=ALL,则意味着写入的消息至少有一条。如果生产者(Producer)等待Kafka集群服务端确认发生超时,或者收到服务端响应的错误码,则会触发重试机制。若是Kafka代理(Broker)节点在发送确认之前失败了,但是消息却成功写入到了Kafka集群主题(Topic),由于失败再次触发重试机制导致消息被重写,最终导致结果不正确。
    可能重复发送:发送给leader节点并保存到磁盘,副本也同步了,返回ack之前leader宕机,生产者没有收到ack,会重试,造成重复消息。
    2.至多一次:生产者(Produce)在发送消息到Kafka集群主题(Topic)时,最多允许消息成功写入一次,这样可避免数据重复。
    可能丢失消息:ack=0,不检查leader是否落盘存储好,集群收到消息后,leader宕机,生产者也不会重传,造成消息丢失。
    精准一次:这是最符合要求的,但是也是最困难的。因为它需要消息传递系统与生产者和消费者的应用程序之间进行配合。在成功读取一条消息后,如果用户将Kafka的偏移量(Offset)的值回退到原点,则用户将会从回退的偏移量值开始读取消息,一直读取到最新的消息为止。

你可能感兴趣的:(Kafka,kafka,java,分布式)