zoukankan      html  css  js  c++  java
  • kafka(一)入门

    一、消息引擎系统

    这类系统引以为豪的消息传递属性,像引擎一样,具备某种能量转换传输的能力

    消息引擎系统是一组规范,企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。通俗地讲就是系统A发送消息给消息引擎系统,系统B从消息引擎系统读取系统A的消息

    既然消息引擎系统是用于不同系统之间传输消息的,如何设计待传输消息的格式,提供可重用性及通用性。kafka使用的是二进制的字节序列,当然消息还是结构化的,只是在使用之前都要将其转换成二进制的字节序列。

    消息引擎系统还要设定具体的传输协议,即我用什么方法把消息传输出去:

    1、点对点模型:也叫消息队列模型,系统A发送的消息只能被系统B接收,其他任何系统都不能读取A发送的消息

    2、发布/订阅模型:一个主题(Topic),可以理解为消息容器。多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息

    kafka同时支持这两种消息引擎模型

    作用:削峰填谷和松耦合

    1、削峰填谷就是指缓冲上下游瞬时突发流量,使其平滑。一旦有了消息引擎系统,它能够有效地对抗上游的流量冲击,真正做到将上游的“峰”填满到“谷”中,避免了流量的震荡

    2、发送方和接收方的松耦合,简化了应用的开发,减少了系统间不必要的交互

    类似于秒杀这样的业务时,上游订单流量会瞬时增加,可能出现的结果就是直接压垮下游子系统服务(调用支付宝和微信接口、查询登录信息、商品信息等)。当引入kafka后,上游订单服务不再直接与下游子服务进行交互。当新订单生成后它仅仅是向kafka broker发送一条订单消息即可。下游各个子服务订阅对应的主题,并实时从该主题的各自分区(Partition)中获取订单消息进行处理,从而实现上游订单服务与下游订单处理服务解耦。这样当出现秒杀业务时,kafka能够将瞬时增加的订单流量全部以消息形式保存在对应的主题中,既不影响上游服务的TPS,同时给下游子服务留出充足的时间消费它们。

    二、kafka术语

    kafka属于分布式的消息引擎系统,它的主要功能是提供一套完备的消息发布与订阅解决方案。在kafka中,发布订阅的对象是主题(Topic),你可以为每个业务、每个应用甚至是每类数据都创建专属的主题。

    客户端:

    1、生产者(Producer)

    向主题发布消息的客户端应用程序,生产者程序通常持续不断地向一个或多个主题发送消息。

    2、消费者(Consumer)

    订阅主题消息的客户端应用程序,消费者也能够同时订阅多个主题的消息。

    我们把生产者和消费者统称为客户端(Clients),你可以同时运行多个生产者和消费者实例,这些实例会不断地向kafka集群中的多个主题生产和消费消息。

    服务端:

    kafka的服务器端由被称为Broker的服务进程构成,即一个kafka集群由多个Broker组成,Broker负责接收和处理客户端发送过来的请求,以及对消息进行持久化。

    虽然多个Broker进程能够运行在同一台机器上,但更常见的做法是将不同的Broker分散运行在不同的机器上,这样如果集群中某一台机器宕机,即使在它上面运行的所有Broker进程都挂掉了,其他机器上的Broker也依然能够对外提供服务。这其实就是kafka提供高可用的手段之一

    实现高可用的另一个手段就是备份机制(Replication)。就是把相同的数据拷贝到多台机器上,而这些相同的数据拷贝在kafka中被称为副本(Replica)。副本的数量是可以配置的,这些副本保存着相同的数据,但却有不同的角色和作用。

    kafka定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follower Replica)前者对外提供服务,这里的对外指的是与客户端程序进行交互;而后者只是被动地追随领导者副本而已,不能与外界进行交互。但是比如MySQL的从库是可以处理读操作的,但是在kafka中追随者副本不会对外提供服务。

    副本的工作机制:生成者总是向领导者副本写消息;而消费者总是从领导者副本读消息。至于追随者副本,只做一件事就是向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。

    伸缩性即所谓的Scalability,是分布式系统中非常重要且必须要谨慎对待的问题。什么是伸缩性?如kafka,虽然有了领导者副本和追随者副本,但如果领导者副本积累了太多的数据以至于单台Broker机器都无法容纳,此时该怎么办?一个很自然的想法就是能否把数据分割成多份保存在不同的Broker上,kafka就是这么设计的,这种机制就是所谓的分区(Partitioning)

    kafka中的分区机制指的是将每个主题划分成多个分区,每个分区是一组有序的消息日志。生成者生成的每条消息只会被发送到一个分区中,也就是说如果向一个双分区的主题发送一条消息,这条消息要么在分区0中,要么在分区1中。kafka的分区编号是从0开始的,如果主题有100个分区,那么它们的分区号就是从0到99。

    实际上,副本是在分区这个层级定义的。每个分区下可以配置若干个副本,其中只能有一个领导者副本和N-1个追随者副本。生产者向分区写入消息,每条消息在分区中的位置信息由一个叫位移(Offset)的数据来表征。分区位移总是从0开始,假设一个生产者向一个空分区写入了10条消息,那么这10条消息的位移依次是0、1、2、.....、9。

    kafka的三层消息架构:

    • 第一层是主题层,每个主题可以配置M个分区,而每个分区又可以配置N个副本
    • 第二层是分区层,每个分区的N个副本只能有一个领导者副本,对外提供服务;其他N-1个副本是追随者副本,只是提供数据冗余作用。
    • 第三层是消息层,分区中包含若干条消息,每条消息的位移从0开始,依次递增。
    • 最后,客户端程序只能与分区的领导者副本进行交互

    kafka Broker如何持久化数据:

    kafka使用消息日志(Log)来保存数据,一个日志就是磁盘上一个只能追加写消息的物理文件。因为只能追加写入,故避免了缓慢的随机I/O操作,改为性能较好的顺序I/O写操作,这也是实现kafka高吞吐量特性的一个重要手段。如果不停地向一个日志写入消息,最终也会耗尽所有磁盘空间,因此kafka必然要定期地删除消息以回收磁盘。

    kafka通过日志段机制删除消息。在kafka底层,一个日志又进一步细分成多个日志段,消息被追加写到当前最新的日志段中,当写满了一个日志段后,kafka会自动切分出一个新的日志段,并将老的日志段封存起来。kafka在后台还有定时任务会定期地检查老的日志段是否能够被删除,从而实现回收磁盘空间的目的。

    消费者组:

    在kafka中实现点对点模型的方法就是引入消费者组。所谓的消费者组,指的是多个消费者实例(可以是运行消费者应用的进程,也可以是一个线程,它们都称为一个消费者实例)共同组成一个组来消费一组主题。这组主题中的每个分区都只会被组内的一个消费者实例消费,其他消费者实例不能消费它。引入消费者组主要是为了提升消费者端的吞吐量,多个消费者实例同时消费,加速整个消费端的吞吐量。

    kafka的重平衡:

    消费者组里面的所有消费者实例不仅瓜分订阅主题的数据,而且它们还能彼此协助。假设某个实例挂掉了,kafka会自动检测到,然后把这个挂掉的实例之前负责的分区转移给其他消费者。但是由于重平衡引发的消费者问题比比皆是,目前社区上很多的重平衡Bug都无力解决。

    消费者位移:

    每个消费者在消费消息的过程中必然需要有一个字段记录它当前消费到了分区的哪个位置上,这个字段就是消费者位移(Consumer Offset)。注意,这和上面所说的位移完全不是一个概念。上面的位移表征的是分区内的消息位置,它是不变的,即一旦消息被成功写入到一个分区上,它的位移值就是固定的了。而消费者位置则不同,它可能是随时变化的,毕竟它是消费者消费进度的指示器。每个消费者有着自己的消费者位移,因此一定要区分开两个位移。我个人把消息在分区中的位置称为分区位移,而把消费者端的位移称为消费者位移。

    总结:

    • 消息:Record。这里的消息就是指kafka处理的主要对象。
    • 主题:Topic。主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务。
    • 分区:Partition。一个有序不变的消息叙序列。每个主题下可以有多个分区。
    • 消息位移:Offset。表示分区中每条消息的位置信息,是一个单调递增且不变的值。
    • 副本:Repilca。kafka中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓副本。副本分为领导者副本和追随者副本,各自有不同的角色划分。副本是在分区层级下的,每个分区可配置多个副本实现高可用。
    • 生产者:Producer。向主题发布新消息的应用程序。
    • 消费者:Consumer。从主题订阅新消息的应用程序。
    • 消费者位移:Consumer Offset。表征消费者消费进度,每个消费者都有自己的消费者位移。
    • 消费者组:Consumer Group。多个消费者实例共同组成的一个组,同时消费多个分区以实现高吞吐。
    • 重平衡:Rebalance。消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。这也是kafka消费者端实现高可用的重要手段。

    概念图:

    三、kafka是消息引擎系统,也是一个分布式流处理平台

    kafka是Linkedin公司内部孵化的项目,Linkedin最开始有强烈的数据强实时处理方面的需求,其内部的诸多子系统要执行多种类型的数据处理与分析,主要包括业务系统和应用程序性能监控,以及用户行为数据处理等。

    当时他们碰到的主要问题包括:

     1、数据正确性不足。

    2、系统高度定制化,维护成本高。各个业务子系统都需要对接数据收集模块,引入了大量的定制开销和人工成本。

    为了解决这些问题,Linkedin工程师尝试过使用ActiveMQ来解决这些问题,但效果并不理想,显然是需要有一个系统,而这个系统就是kafka。

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

    1、提供一套API实现生产者和消费者;

    2、降低网络传输和磁盘存储开销;

    3、实现高伸缩性架构。

    开源之后的kafka被越来越多的公司应用到它们企业内部的数据管道中,特别是在大数据工程领域,kafka在承接上下游、串联数据流管道方面发挥了重要作用:所有的数据几乎都要从一个系统流入kafka然后再流向下游的另一个系统中。这样的方式引发了一个思考:与其我把数据从一个系统传递到下一个系统中做处理,我为何不自己实现一套流处理框架呢?基于这个考量,kafka社区于0.10.0.0版本正式推出了流处理组件kafka streams,也正是从这个版本开始,kafka正式变身为分布式的流处理平台,而不仅仅是消息引擎系统了。今天kafka是和Apache Storm、Apace Spark和Apace Flink同等级的实时流处理平台。

    kafka与其他主流大数据流式计算框架相比,优势在两个方面:

    1、更容易实现端到端的正确性(Correctness)。实现正确性是流处理能够匹敌批处理的基石。正确性一直是批处理的强项,而实现正确性的基石则是要求框架能提供精确一次(Exactly-once)处理语义,即处理一条消息有且只有一次机会能够影响系统的状态。目前主流的大数据流处理框架都宣称实现了精确一次处理语义,但这是有限定条件的,即它们只能实现框架内的的精确一次处理语义,无法实现端到端的。因为当这些框架与外部消息引擎系统结合使用时,它们无法影响到外部系统的处理语义,所以如果你搭建了一套环境使得Spark从kafka读取消息之后进行有状态的数据计算,最后再写回kafka,那么你只能保证在Spark内部,这条消息对于状态的影响只有一次。但是计算结果有可能多次写入到kafka,因为它们不能控制kafka的语义处理。相反地,因为kafka所有的数据流转和计算都在kafka内部完成,故kafka可以实现端到端的精确一次处理语义。

    2、它自己对于流式计算的定位。kafka Streams是一个用于搭建实时流处理的客户端库而不是一个完整的功能系统。即你不能期望着kafka提供类似于集群调度、弹性部署等开箱即用的运维特性,你需要自己选择适合的工具或系统来帮助kafka流处理应用实现这些功能。对于大型公司的流处理平台一定是大规模部署的,因此具备集群调度功能以及灵活的部署方案是不可或缺的。但是对于中小企业,它们的流处理数据量并不巨大,逻辑也并不复杂,部署几台或十台机器足以应付。在这样的需求下,搭建重量级的完整平台实在是杀鸡焉用牛刀,而这时使用kafka流处理组件是非常合适的。

    总结:Apace Kafka从一个优秀的消息引擎系统起家,逐渐演变成现在分布式的流处理平台。不仅要熟练掌握它作为消息引擎系统的非凡特性及使用技巧,最好还要多了解下其流处理组件的设计与案例应用。

    四、kafka的版本选择

    你可能听说过Apache Storm、Apache Spark Streaming和Apache Flink,它们在大规模流处理领域可是响当当的名字。而kafka毕竟是从消息引擎半路出家转型成流处理平台,它在流处理方面的表现还需要经过时间的检验。

    kafka的流处理生态圈:

    kafka Streams组件提供实时处理流数据的能力。

    kafka Connect通过一个个具体的连接器(Connector),串联起上下游的外部系统。

    kafka的版本:

    这里不是指它的版本,而是指存在多个组织或公司发布不同的kafka

    1、Apache Kafka

    最“正宗”的kafka,自kafka开源伊始,它便在Apache基金会孵化并最终毕业成为顶级项目,它也被称为社区版kafka。它是后面其他所有版本的基础,Apache Kafka 是我们学习和使用kafka的基础。

    特点:

    (1)优势:它依然是开发人数最多、版本迭代速度最快的kafka。如果你使用碰到任何问题并提交问题到社区,社区都会比较及时地响应你。这对于我们普通使用者来说无疑是非常友好的。

    (2)劣势:它仅仅提供最最基础的组件,特别是前面提到的Kafka Connect而言,社区版只提供一种连接器,即读写磁盘文件的;连接器,而没有与其他外部系统交互的连接器。另外没有提供任何监控框架或工具,显然在线上环境不加监控肯定是不可行的,你必然需要借助第三方的监控框架实现对kafka的监控。目前有一些开源的监控框架可以帮助用于监控kafka(比如kafka manager)

    选择场景:

    如果你仅仅需要一个消息引擎系统亦或是简单的流处理应用场景,同时需要对系统有较大把握度,那么推荐使用Apache Kafka

    2、Confluent Kafka

    Confluent公司是kafka的3个创始人离开Linkedin创办的,专注于提供基于kafka的企业级流处理解决方案。它主要从事商业化kafka工具开发,并在此基础上发布了Confluent Kafka。Confluent Kafka提供了一些Apache Kafka没有的高级特性,比如跨数据中心备份、Schema注册中心以及集群监控工具等。

    特点:

    (1)优势:目前分为免费版和企业版,前者和Apache Kafka非常像,除了常规的组件外,免费版还包含Schema注册中心和REST proxy两大功能,前者是帮助你集中管理kafka消息格式以实现数据前向/后向兼容,后者用开放HTTP接口的方式允许你通过网络访问kafka的各种功能,这两个是Apache Kafka所没有的。除此之外,免费版包含了更多的连接器,可以免费使用。至于企业版,它提供的功能就更多了。最有用的当属跨数据中心备份和集群监控两大功能,多个数据中心之间数据的同步以及对集群的监控历来都是kafka的痛点。

    (2)劣势:Confluent公司暂时没有发展国内业务,相关的资料以及技术支持都很欠缺,所以目前Confluent Kafka在国内的普及率比较低

    选择场景:

    如果你需要用到kafka的一些高级特性,那么推荐使用Confluent Kafka

    3、Cloudera/Hortonworks Kafka

    Cloudera提供的 CDH 和Hortonworks提供的 HDP 是非常著名的大数据平台,里面集成了目前主流的大数据框架,能够帮助用户实现从分布式存储、集群调度、流处理到机器学习、实时数据库等全方位的数据处理。不管是CDH还是HDP里面都集成了Apache Kafka,因此我把这两款产品中的kafka称为CDH Kafka和HDK Kafka。2018年10月两家公司合并,共同打造世界领先的数据平台。

    特点:

    (1)优势:通过便捷化的界面操作将kafka的安装、运维、管理、监控全部统一在控制台中,使用非常方便,所有的操作都可以在前端UI界面上完成,而不必去执行复杂的kafka命令。

    (2)劣势:这样做的结果是直接降低你对kafka集群的掌控程度,毕竟对下层kafka集群一无所知。还有在于它的滞后性,由于它有自己的发布周期,可能包含的kafka版本不是最新的。

    选择场景:

    如果你需要快速地搭建消息引擎系统,或者你需要搭建的是多框架构成的数据平台且kafka只是其中一个组件,那么推荐使用这些大数据云公司提供的kafka。

    很多小公司都觉得CDH很方便,安装之后什么都有了

     
    五、Apache Kafka版本号

    kafka在实际应用时,如何评判当前业务需求需要使用哪个kafka版本,这就首先需要了解各个版本之间的差异和功能变化。并非使用最新版本在任何场景下都适用。

    kafka版本命令:

    在官网下载时,会看到这样的版本:

    前面的版本号是编译kafka源码的Scala编译器版本,kafka服务器端的代码完全由Scala语言编写。对于上面kafka-2.11-2.1.1,真正的kafka版本号实际是2.1.1,那么这个2.1.1又表示什么?前面的2表示大版本号(Major Version);中间的1表示小版本号或次版本号(Minor Version);最后的1表示修订版本号(Patch号)。kafka社区在发布1.0.0版本后,宣布kafka版本命名规则正式从4位演进到3位,比如0.11.0.0版本就是4位版本号。总结来说,kafka版本号由3部分构成,即大版本号-小版本号-Patch号。

    kafka版本演进:

    目前总共演进了7个大版本,分别0.7、0.8、0.9、0.10、0.11、1.0和2.0,其中的小版本和Patch本很多。如果你要向架构师转型或者已然是架构师,那么熟悉哪些版本引入了哪些重大的功能改进,那么这些可以帮助你进行技术选型、架构评估的重要依据。

    1、0.7版本

    最早开源时的的版本,只提供了最基础的消息队列功能,甚至连副本机制都没有,实在没有理由使用这个版本。

    2、0.8版本

    正式引入了副本机制,至此成为了一个真正意义上完备的分布式高可靠消息队列解决方案。那时候生成和消费消息使用的还是老版本的客户端API,所谓的老版本是指当你用它们的API开发生成者和消费者应用时,你需要指定ZooKeeper的地址而非Broker的地址。老版本客户端有很多的问题,特别是生产者API,它默认使用同步方式发送消息,可见其吞吐量一定不会太高。虽然它也支持异步的方式,但实际场景中可能会造成消息的丢失,因此0.8.2.0版本引入了新版本Producer API,即需要指定Broker地址的Producer。建议至少升级到0.8.2.2,因为该版本中老版本消费者API是比较稳定的,另外在该版本中,不要使用新版本Producer API,此时它的Bug还非常多。

    3、0.9版本

    这是一个重量级的大版本更迭,增加了基础的安全认证/权限功能,同时使用java重写了新版消费者API,还引入了Kafka Connect组件用于实现高性能的数据抽取。新版本Producer API在这个版本中算比较稳定了。和0.8.2引入新API类似,不要使用新版本Consumer API,因为Bug超多。

    4、0.10版本

    是里程碑式的大版本,因为该版本引入了kafka Streams。从这个版本起,kafka升级成分布式流处理平台,虽然此时的kafka Streams还基本不能线上部署使用。0.10大版本包含两个小版本:0.10.1和0.10.2,它们主要功能变更都是在kafka Streams组件上。如果把kafka用作消息引擎,实际上该版本并没有太多的功能提升。自0.10.2.2版本起,新版本Consumer API算是比较稳定了,还有该版本修复了一个可能导致Producer性能降低的Bug。基于性能如果你还在使用0.10大版本,你也应该升级到0.10.2.2。

    5、0.11版本

    引入两个重量级的功能变更:

    一个是提供幂等性Producer API以及事务API(kafka实现流处理结果正确性的基石)。此时的事务API存在一些Bug,不算稳定,另外事务API主要是为Kafka Streams应用服务的。

    另一个是对kafka消息格式做了重构。但是因为格式变更引起消息格式转换而导致的性能问题在生产环境中屡见不鲜,所有要谨慎对待0.11版本这个变化。

    该版本中各个大功能组件都变得非常稳定了,国内该版本的用户也很多,应该算是目前最流行的版本之一了。0.11.0.3这个版本的消息引擎功能已经非常完善了

    6、1.0和2.0版本

    这两个大版本主要是Kafka Streams的各种改进,在消息引擎方面并未引入太多的重大功能特性。如果你是Kafka Streams的用户,至少选择2.0.0版本吧。如果你在意的依然是消息引擎,那么这两个大版本都是适合于生产环境的。

    最后建议,不论你用哪个版本,都请尽量保持服务器端版本和客户端版本一致,否则你将损失很多Kafka为你提供的性能优化收益。

  • 相关阅读:
    文章参考
    选择标识符(identifier)
    linux常见命令2
    Django框架之MVT(1)
    Tornado入门二
    2.Flask-jinjia2模板
    JQuery扩展和事件
    JQuery文档操作
    Jquery学习
    Jquery属性操作(入门二)
  • 原文地址:https://www.cnblogs.com/chjxbt/p/11152260.html
Copyright © 2011-2022 走看看