kafka技术分享02--------kafka入门

kafka技术分享02--------kafka入门

1. 消息系统

​ 所谓的Messaging System就是一组规范,企业利用这组规范在不同的系统之间传递语义准确对的消息,实现松耦合的异步数据传输。简单理解为系统A将消息发送给Messaging System,系统B从Messaging System中获取系统A发送的消息。消息系统主要作用可以概括为四个字:削峰填谷。通过消息系统可以对抗这种上下游消息系统TPS的错配以及瞬时峰值流量。

补充一点:

通常来说,两个进程进行数据流交互的方式一般有三种:

  1. 通过数据库:进程1写入数据库;进程2读取数据库

  2. 通过服务调用:比如REST或RPC,而HTTP协议通常就作为REST方式的底层通讯协议

  3. 通过消息传递的方式:进程1发送消息给名为broker的中间件,然后进程2从该broker中读取消息。消息传输协议属于这种模式

因此,Messageing System必须保证消息的传输格式的语义正确解析无歧义,另外还要对如何传输消息进行设计。对于第一点Kafka使用的是纯二进制的字节序列,对于第二点消息的传输方式大概有两种:

  • 点对点模式:系统A发送的消息只能被系统B所接受,其他任何系统不能读取系统A发送的消息

  • 发布(publish)/订阅(suscribe)模式:可以存在多个消息发布者往同一topic中发送数据,同时可以存在多个消费者对统一topic的数据进行消费。

kafka同时支持者两种消息传输模式。

2.kafka是什么

Kafka既是一个开源的分布式消息系统,又是一个分布式流平台。

kafka在设计之初旨在提供三个方面的特性:

  • 提供一套API实现生产者消费者;

  • 降低网络传输和磁盘存储开销

  • 实现高伸缩性架构

从以上三点可以看出,kafka的设计之初的目的其实是作为一个消息系统,主要作用是承接上下游、串联数据流管道。直到kafka0.10.0.0版本正式推出了流处理组件Kafka Streams,Kafka正式变身为流处理平台。那么kafka streams和其他大数据流处理框架相比的优势主要表现在:

  • 更容易实现端到端的正确性。实现正确性的基石是要求框架能够提供精确一次性处理语义,即处理一条消息有且只有一次影响系统的状态。目前主流的大数据流处理框架都宣称实现了精确一次处理语义,但是有条件的,只能实现框架内的精确一次处理语义,无法实现端到端的精确一次处理语义。而kafka streams的数据流转和计算都在kafka内部,因此能够实现端到端的精确一次处理语义。

  • 他自己对于流式计算的定位。官网上明确标识Kafka Streams是一个搭建实时流处理的客户端库,而非一个完整的功能系统。因此kafka不提供类似于集群调度和弹性部署等开箱即用的运维特性,需要自己选择合适的工具和系统来帮助kafka流处理应用实现此类功能。kafka Streams的定位是中小型公司,数据量没有那么大,使用大数据流处理框架有点浪费。

3. kafka的种类

  • Apache Kafka。

    Apache Kafka是社区版kafka。它的优势在于毫无疑问它是开发人数最多、版本迭代最快的Kafka。他的劣势在于仅仅提供了最基础的组件,对于Kafka Connect,仅仅提供了一种连接器即读写磁盘文件的连接器,而没有于其他系统交互的连接器。另外,Apache Kafka也没有提供任何监控的框架和工具。需要借助于第三方框架(Kafka Manager、kafka eagle、JMXTrans + InfluxDB + Grafana)

  • Confluent Kafka

    Confluent公司基于Apache Kafka创建的商业版Kafka

         

  • CDH/HDP Kafka

    Cloudera提供的CDH和HortonWorkers提供的HDP是著名的大数据平台,里边集成了目前主流的大数据处理框架,能够帮助用户实现从分布式存储、集群调度、流处理到机器学习、实时数据库等方面的数据处理。CDH和HDP都集成了Apache Kafka。

   

     补充kafka的性能监测工具:

     Kafka自己提供了kafka-producer-perf-test和kafka-consumer-perf-test脚本可以做producer和consumer的性能测试。另外LinkedIn开源了一款名为kafka-monitor的端到端系统测试工具,也可以用来测试Kafka集群end-to-end的性能。有些遗憾的是这个工具几乎没什么人维护了。

4. kafka术语

kafka属于分布式消息系统,它的主要功能室提供一套完备的消息发布订阅的解决方案,实现不同系统之间的消息传递。kafka中发布订阅的对象就是topic,可以将topic理解为某一类消息的一个标识。

客户端:向主题发布消息的客户端应用程序就称为生产者(Producer),订阅主题的客户端应用程序称之为消费者(Consumer)。生产者、主题和消费者的数量关系不固定,一个生产者可以不断的向一个或多个主题发送消息,一个消费者可以订阅一个或多个主题。

服务端:kafka的服务端由被称为Broker的服务进程组成,给一个kafka集群由多个broker进程组成。Broker主要负责接收和处理客户端的请求,以及对消息进行持久化。虽然一台主机可以运行多个Broker进程,但更为常见的做法是将Broker运行在不同的主机上,实现容灾与高可用。

另外一个实现高可用的方式是副本机制(Replication)。副本机制的基本思想就是将相同的数据拷贝到不同的机器上。kafka定义了两类副本:Leader Replia和Follower Replia。Leader主要是接收处理客户端的请求,Follower主要同步Leader的数据,不能与外界进行交互。

简单一句话就生产者总是想leader发送数据,而消费者总是从leader消费数据。follower就做一件事,请求leader将最新的消息发动给它。Kafka不能推送消息给consumer。Consumer只能不断地轮训去获取消息。从Kafka流向consumer的唯一方式就是通过poll。另外维持一个长连接去轮训的开销通常也没有你想的那么大,特别是Kafka用的是Linux上的epoll,性能还不错,至少比select好。

分区中的所有副本统称为AR(assigned Replica),很所时候follower副本中的消息相对于leader而言会有一定的滞后,这个滞后范围是可以通过参数进行配置的。所有与leader保持一定程度同步(并不一定是完全同步)的副本组成ISR(In-Sync Replica),剩余部分为OSR。所以AR=ISR+OSR。

leader副本负责维护和跟踪所有follower副本的滞后状态,当follower副本滞后太多或失效时,leader副本会将它从ISR中剔除,如果OSR中有follower副本追上leader副本,leader副本会将它从OSR迁移至ISR。默认情况下(可通过参数进行改变),leader副本发生故障,只有ISR集合中的副本才有资格参与leader的选举。

副本机制保证了数据的不丢失,提升容灾能力,但无法解决伸缩性问题(Scalability)。所谓的额伸缩性可以这样理解。倘若一个leader积累了足够多的数据,导致单台Broker无法容纳。Kafka的解决方式就是Partition机制,将一个topic的数据划分为多个分区,分区是有序的,编号从0开始,生产者生产的某一条数据只会发送到某一个分区,每一条消息在分区上的位置成为Offset。其实副本机制是建立在分区机制之上的,一个topic向的所有分区都有一个leader和多个folllower。分区在存储层可以被看做是一个可追加的日志文件,消息在追加到分区日志文件时,会分配一个特定的偏移量。每一条消息发送到broker之前都会根据分区规则选择存储到那个具体分区分区的数量可以在出题创建的时候指定,也可以在创建主题完之后进行修改实现水平扩展。

消费者组:多个消费者共同组成一个组来消费一组主题。这个主题的某一个分区只会被消费者的某个特定分区所消费,其他消费者实例不能进行消费。之所以引入消费者组,更多的是因为多个消费者同时消费可以提高消费端的TPS。另外这里的消费者实例可以是运行消费者的应用进程,也可以是一个线程。消费者组内的消费者除了瓜分主题消息的功能,还可以互相协作,当某个消费者挂掉,kafka能够自动检测掉,进行分区的重平衡(Rebalance )。另外每一个消费者在消费过程中必然会记录消费到了分区那个位置,成为消费者偏移量(Consumer Offset)

一张图简单概括一下:

kafka的Broker是如何对消息进行持久化的?

kafka使用消息日志(Log)来保存数据,一个日志就是磁盘上一个只支持追加(Append Only)的物理文件,用顺序IO代替随机IO,是kafka实现高吞吐的一个重要手段。不过如果不停地向统一日志文件追加数据,总会耗尽所有磁盘空间,因此kafka必然会定期的删除消息,回收磁盘。kafka是通过日志段(Log Segment)机制进行磁盘回收的。在kafka的底层一个日志又进一步分成多个日志段,消息被追加到当前最新的日志段中,当写满一个日志段后,kafka会自动切分出一个新的日志段,并将老的日志段封存起来。kafka在后台会有定时认为会定期的检查老的日志段是够能够被删除,从而实现磁盘回收的目的。

请思考一下为什么 Kafka 不像 MySQL 那样允许Follower对外提供服务,支持主从读写分离?

主从读写分离主要目的就是缓解leader节点的压力,将读请求负载到多个follower上,提升读操作的性能。这种设计只是一种架构,无优劣之说,只是有自己的适用场景而已,通常适用于读多写少的场景。而对于kafka而言,它是一个消息系统而不是以存储的方式对外提供读服务,通常会涉及到频繁的生产数据和消费数据,并不符合读多写少的应用场景。如果Kafka的分区相对均匀地分散到各个broker上,同样可以达到负载均衡的效果,没必要刻意实现主写从读增加代码实现的复杂程度。

kafka的副本机制采用的是异步消息拉取,因此存在leader和follower的数据一致性问题,如果要实现读写分离,必须要处理好副本lag导致的数据一致性问题。

分布式系统中replica的leader和follower之间如何复制数据保证消息的持久化的问题,我了解的是有3种模式:

1.生产者消息发过来以后,写leader成功后即告知生产者成功,然后异步的将消息同步给其他follower,这种方式效率最高,但可能丢数据;

2.同步等待所有follower都复制成功后通知生产者消息发送成功,这样不会丢数据,但效率不高;

3.折中的办法,同步等待部分follower复制成功,如1个follower复制成功再返回,这样兼顾效率和消息的持久化。

目前Kafka不支持第三种“折中”办法。。。要么只写leader,要么所有follower全部同步。但是,我同意很多分布式系统是可以配置同步follower和异步follower共存的,比如一个同步follower+N-1个异步follower的伪同步。Facebook的MySQL就是这个原理。

5.Kafka的版本号

从官网下载kafka时,会出现如下两种情况。但是无论是哪种情况,Kafka-2.11-2.2.1,其中2.11指的是scala编译器的版本。2.2.1才是kafka的版本。Kafka版本经历了由四位表示到三位表示的转变,1.0.0版本之前采取四位,之后采用3位,无论是四位还是三位,kafka版本构成都是:大版本号(Major version)-小版本号(Minor Version)-修订版本号(Patch)。

Kafka的大版本共经历了从0.7、0.8、0.9、0.10、0.11、1.0、2.0七个版本的演变。

  • 0.7 。这个版本仅仅提供了最基础的消息队列的功能,副本机制都没有。
  • 0.8 。0.8正式引入了副本机制,至此kafka成为一个真正意义上完备的分布式高可靠的消息队列解决方案。生产者和消费者使用的还是老版本的API,即当你开发生产者和消费者时,你需要指定的zookeeper的地址而不是Broker的地址。

        

  • 0.9版本的主要功能改进包括:增加了基础的安全认证和权限功能;用java重写了新版本消费者API;引入了kafka connect组件用于实现高性能的数据抽取;新版本的producer API算基本稳定。但是0.9版本的新版Consumer APIBug超多。
  • 0.10.0.0这个版本是个里程碑式的版本,它引入了Kafka Streams,至此kafka变身为一个分布式流处理平台。

        

  • 0.11.0.0提供了两个新的功能:提供了幂等性的Producer API和事务API,另一个是对kafka的消息格式进行了重构。

       

  • 1.0和2.0两个版本的更新主要体现在Kafka Streams上,而且两个版本的API变化挺大。
原文地址:https://www.cnblogs.com/gdy1993/p/11045685.html