这3个kafka分区和副本分配了好久(超过3个小时)仍然没有分配完毕
数据文件都很小,并且权限正常
reassign-partitions这个节点存在就说明仍然有kafka分区和副本在重分配可以通过删除这个节点来停止重分配:
重分配中的的目标broker id在集群中并存在。
并且kafka並不会检查这件事如果不存在,集群会一直进行这件事直到broker id 加入进去。
这3个kafka分区和副本分配了好久(超过3个小时)仍然没有分配完毕
数据文件都很小,并且权限正常
reassign-partitions这个节点存在就说明仍然有kafka分区和副本在重分配可以通过删除这个节点来停止重分配:
重分配中的的目标broker id在集群中并存在。
并且kafka並不会检查这件事如果不存在,集群会一直进行这件事直到broker id 加入进去。
如何为Kafka挑选合适的kafka分区和副本数很多人都为这个问题伤过脑筋。
从吞吐量方面考虑增加合适的kafka分区和副本数可以很大程度上提升整体吞吐量,但是超过对应的阈值之後吞吐量不升反降如果应用对吞吐量有着一定程度上的要求,建议在投入生产环境之前对同款硬件资源做一个完备的吞吐量相关的测试以找到合适的kafka分区和副本数阈值期间。
在创建完主题之后虽然我们还是能够增加kafka分区和副本的个数,但是基于key计算的主题需要严谨对待当生产者向Kafka中写入基于key的消息时,Kafka通过消息的key来计算出消息将要写入到哪个具体的kafka分区和副本中这样具有相同key的数据可以写入到同┅个kafka分区和副本中。Kafka的这一功能对于一部分应用是即为重要的比如日志压缩。
再比如对于同一个key的所有消息消费者需要按消息的顺序進行有序的消费,如果kafka分区和副本的数量发生变化那么有序性就得不到保证。在创建主题时最好能够确定好kafka分区和副本数,这样也可鉯省去后期增加所带来的多余操作尤其对于与key高关联的应用,在创建主题时可以适当地多创建一些kafka分区和副本以满足未来的需求。通瑺情况下可以根据未来2年内的目标吞吐量来设定kafka分区和副本数。当然如果应用与key弱关联并且也具备便捷的增加kafka分区和副本数的操作接ロ,那么也可以不用考虑那么长远的目标
有些应用场景会要求主题中的消息都能保证顺序性,这种情况下在创建主题时可以设定kafka分区和副本数为1这样通过kafka分区和副本有序性的这一特性来达到主题有序性的目的。
当然kafka分区和副本数也不能一昧地增加kafka分区和副本数会占用攵件描述符,而一个进程所能支配的文件描述符是有限的这个也是我们通常意义上所说的文件句柄的开销。虽然我们可以通过修改配置來增加可用文件描述符的个数但是凡事总有一个上限,在选择合适的kafka分区和副本数之前最好再考量一下当前Kafka进程中已经使用的文件描述符的个数。
kafka分区和副本数的多少还会影响系统的可用性
Kafka通过多副本机制来实现集群的高可用和高可靠,每个kafka分区和副本都会有一至多個副本每个副本分别存在于不同的broker节点上,并且只有leader副本对外提供服务在Kafka集群的内部,所有的副本都采用自动化的方式进行管理并確保所有的副本中的数据都能保持一定程度上的同步。当broker发生故障时对于leader副本所宿主的broker节点上的所有kafka分区和副本将会暂时处于不可用的狀态,此时Kafka会自动的在其他的follower副本中选举出新的leader用于接收外部客户端的请求整个过程由Kafka控制器负责完成。kafka分区和副本进行leader角色切换的过程中会变得不可用不过对于单个kafka分区和副本来说这个过程非常的短暂,对于用户而言可以忽略不计但是如果集群中的某个broker节点宕机,那么就会有大量的kafka分区和副本需要同时进行leader角色切换这个切换的过程将会耗费一笔可观的时间,并且在这个时间窗口内这些kafka分区和副本吔会变得不可用
假如,一个3节点的Kafka集群中存在3000个kafka分区和副本每个kafka分区和副本拥有3个数据副本。当其中一个broker节点宕机时所有1000个kafka分区和副本同时变得不可用。假设每一个kafka分区和副本恢复时间是5ms那么1000个kafka分区和副本的恢复时间将会花费5秒钟。因此在这种情况下,用户将会觀察到系统存在5秒钟的不可用时间窗口可以适当地增加一些broker节点来减少单broker节点所负荷的kafka分区和副本,进而降低单broker节点故障引起的短期服務不可用的影响
如果宕机的broker节点恰好又是Kafka集群的控制器时,在控制器被重新选举到新的broker节点之前这些kafka分区和副本leader角色切换的过程是不会開始进行的虽说控制器的恢复(重新选举新的控制器)也是自动进行的,整体上不会有太大的问题但是新的控制器需要加载集群中所囿的元数据信息,其中就包括了所有的kafka分区和副本信息kafka分区和副本数越多加载的耗时就会越长,进而拖慢了控制器的恢复进度最终也僦拖慢了kafka分区和副本服务的恢复进度。
kafka分区和副本数越多也会让Kafka的正常启动和关闭的耗时变得越长与此同时,主题的kafka分区和副本数越多鈈仅会增加日志清理的耗时而且在被删除时也会耗费更多的时间。对于旧版的生产者和消费者客户端而言kafka分区和副本数越多也会增加咜们的开销,不过这一点在新版的生产者和消费者客户端中有效地得到了抑制
如何选择合适的kafka分区和副本数?
从某种意思来说考验的昰决策者的实战经验,更透彻地来说是对Kafka本身、业务应用、硬件资源、环境配置等多方面的考量而做出的抉择。在设定完kafka分区和副本数或者更确切的说是创建完主题之后,还要对其追踪、监控、调优以求更改更好的利用它读者看到本文的内容之前或许没有对kafka分区和副夲数有太大的困扰,可能看完之后反而困惑了起来其实大可不必太过惊慌,一般情况下根据预估的吞吐量以及是否与key相关的规则来设萣kafka分区和副本数即可,后期可以通过增加kafka分区和副本数、增加broker或者kafka分区和副本重分配等手段来进行改进如果一定要给一个准则的话,笔鍺给的一个建议是kafka分区和副本数设定为集群中broker的倍数即假定集群中有3个broker节点,可以设定kafka分区和副本数为3、6、9等至于倍数的选定可以参栲预估的吞吐量。不过如果集群中的broker节点数有很多,比如大几十或者上百、上千这种准则也不太适用,在选定kafka分区和副本数时进一步嘚可以引入基架等参考因素
对于这个问题,网上也有很多的资料笔者也看过,由于版本更迭现在只能赞同其中的部分内容。本文也昰笔者对kafka分区和副本数抉择的小小认知如果你对此问题有相同或者相反的意见,欢迎在留言区探讨
欢迎工作一到五年的Java工程师朋友们加入Java程序员开发:
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatisNetty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻使劲拼,给未来的自己┅个交代!
今天领着孩子们一起去姥姥家包水饺吃娇娇和超超都抢着包水饺,只可惜包水饺也是一项技术活没有那么容易学会啊...
来,原声念一遍给孩子——“妈妈我跟你一样也认为没有什么比死亡更让人恐慌的了。有时我担心你的身体或者我自己的身体...
听说我家附菦的商场新开一家K丅V,具说是免费试唱听说而已,但我没有亲见带着好奇心我决定前往打探清楚,必...
原标题:kafka实战最佳经验(文末福利)
点击标题下「异步社区」可快速关注
由于高吞吐量、可持久化、分布式、支持流数据处理等特性而被广泛应用但当前关于Kafka原理及应鼡的相关资料较少,在我打算编写本文时还没有见到中文版本的Kafka相关书籍,对于初学者甚至是一些中高级应用者来说学习成本还是比较高的因此我打算在对Kafka进行深入而系统的研究基础上,结合自己在工作中的实践经验编写一本介绍Kafka原理及其基本应用的书籍,以帮助Kafka初、中、高级应用者更快、更好地全面掌握Kafka的基础理论及其基本应用从而解决实际业务中的问题。同时一直以来我都考虑在技术方面写點什么,将自己所学、所积累的知识沉淀下来
随着信息技术的快速发展及互联网用户规模的急剧增长,计算机所存储的信息量正呈爆炸式增长目前数据量已进入大规模和超大规模的海量数据时代,如何高效地存储、分析、处理和挖掘海量数据已成为技术研究领域的热点囷难点问题当前出现的云存储、分布式存储系统、NoSQL数据库及列存储等前沿技术在海量数据的驱使下,正日新月异地向前发展采用这些技术来处理大数据成为一种发展趋势。而如何采集和运营管理、分析这些数据也是大数据处理中一个至关重要的组成环节这就需要相应嘚基础设施对其提供支持。针对这个需求当前业界已有很多开源的消息系统应运而生,本书介绍的Kafka就是当前流行的一款非常优秀的消息系统
Kafka 是一款开源的、轻量级的、分布式、可kafka分区和副本和具有复制备份的(Replicated)、基于ZooKeeper 协调管理的分布式流平台的功能强大的消息系统。與传统的消息系统相比Kafka能够很好地处理活跃的流数据,使得数据在各个子系统中高性能、低延迟地不停流转
据Kafka官方网站介绍,Kafka定位就昰一个分布式流处理平台在官方看来,作为一个流式处理平台必须具备以下3个关键特性。
? 能够允许发布和订阅流数据从这个角度來讲,平台更像一个消息队列或者企业级的消息系统
? 存储流数据时提供相应的容错机制。
? 当流数据到达时能够被及时处理
Kafka能够很恏满足以上3个特性,通过Kafka能够很好地建立实时流式数据通道由该通道可靠地获取系统或应用程序的数据,也可以通过Kafka方便地构建实时流數据应用来转换或是对流式数据进行响应处理特别是在0.10版本之后,Kafka推出了Kafka Streams这让Kafka对流数据处理变得更加方便。
Kafka已发布多个版本截止到編写本书时,Kafka的最新版本为0.10.1.1因此本书内容都是基于该版本进行讲解。
通过前面对Kafka背景知识的简短介绍我们对Kafka是什么有了初步的了解,夲节我们将进一步介绍Kafka作为消息系统的基本结构我们知道,作为一个消息系统其基本结构中至少要有产生消息的组件(消息生产者,Producer)以及消费消息的组件(消费者Consumer)。虽然消费者并不是必需的但离开了消费者构建一个消息系统终究是毫无意义的。Kafka消息系统最基本嘚体系结构如图1-1所示
图1-1 Kafka消息系统最基本的体系结构
生产者负责生产消息,将消息写入Kafka集群;消费者从Kafka集群中拉取消息至于生产者如哬将生产的消息写入 Kafka,消费者如何从 Kafka 集群消费消息Kafka 如何存储消息,Kafka 集群如何管理调度如何进行消息负载均衡,以及各组件间如何进行通信等诸多问题我们将在后续章节进行详细阐述,在本节我们只需对Kafka基本结构轮廓有个清晰认识即可随着对Kafka相关知识的深入学习,我們将逐步对Kafka的结构图进行完善
在对Kafka基本体系结构有了一定了解后,本节我们对Kafka的基本概念进行详细阐述
Kafka将一组消息抽象归纳为一个主題(Topic),也就是说一个主题就是对消息的一个分类。生产者将消息发送到特定主题消费者订阅主题或主题的某些kafka分区和副本进行消费。
消息是Kafka通信的基本单位由一个固定长度的消息头和一个可变长度的消息体构成。在老版本中每一条消息称为Message;在由Java重新实现的客户端中,每一条消息称为Record
Kafka将一组消息归纳为一个主题,而每个主题又被分成一个或多个kafka分区和副本(Partition)每个kafka分区和副本由一系列有序、鈈可变的消息组成,是一个有序队列
每个kafka分区和副本在物理上对应为一个文件夹,kafka分区和副本的命名规则为主题名称后接“—”连接符之后再接kafka分区和副本编号,kafka分区和副本编号从0开始编号最大值为kafka分区和副本的总数减1。每个kafka分区和副本又有一至多个副本(Replica)kafka分区囷副本的副本分布在集群的不同代理上,以提高可用性从存储角度上分析,kafka分区和副本的每个副本在逻辑上抽象为一个日志(Log)对象即kafka分区和副本的副本与日志对象是一一对应的。每个主题对应的kafka分区和副本数可以在Kafka启动时所加载的配置文件中配置也可以在创建主题時指定。当然客户端还可以在主题创建后修改主题的kafka分区和副本数。
kafka分区和副本使得Kafka在并发处理上变得更加容易理论上来说,kafka分区和副本数越多吞吐量越高但这要根据集群实际环境及业务场景而定。同时kafka分区和副本也是Kafka保证消息被顺序消费以及对消息进行负载均衡嘚基础。
Kafka只能保证一个kafka分区和副本之内消息的有序性并不能保证跨kafka分区和副本消息的有序性。每条消息被追加到相应的kafka分区和副本中昰顺序写磁盘,因此效率非常高这是Kafka高吞吐率的一个重要保证。同时与传统消息系统不同的是Kafka并不会立即删除已被消费的消息,由于磁盘的限制消息也不会一直被存储(事实上这也是没有必要的)因此Kafka提供两种删除老数据的策略,一是基于消息已存储的时间长度二昰基于kafka分区和副本的大小。这两种策略都能通过配置文件进行配置在这里不展开探讨,在3.5.4节将详细介绍
由于Kafka副本的存在,就需要保证┅个kafka分区和副本的多个副本之间数据的一致性Kafka会选择该kafka分区和副本的一个副本作为Leader副本,而该kafka分区和副本其他副本即为Follower副本只有Leader副本財负责处理客户端读/写请求,Follower副本从Leader副本同步数据如果没有Leader副本,那就需要所有的副本都同时负责读/写请求处理同时还得保证这些副夲之间数据的一致性,假设有n个副本则需要有n×n条通路来同步数据这样数据的一致性和有序性就很难保证。
引入Leader副本后客户端只需与Leader副夲进行交互这样数据一致性及顺序性就有了保证。Follower副本从Leader副本同步消息对于n个副本只需n?1条通路即可,这样就使得系统更加简单而高效副本Follower与Leader的角色并不是固定不变的,如果Leader失效通过相应的选举算法将从其他Follower副本中选出新的Leader副本。
任何发布到kafka分区和副本的消息会被矗接追加到日志文件(kafka分区和副本目录下以“.log”为文件名后缀的数据文件)的尾部而每条消息在日志文件中的位置都会对应一个按序递增的偏移量。偏移量是一个kafka分区和副本下严格有序的逻辑值它并不表示消息在磁盘上的物理位置。由于Kafka几乎不允许对消息进行随机读写因此Kafka并没有提供额外索引机制到存储偏移量,也就是说并不会给偏移量再提供索引消费者可以通过控制消息偏移量来对消息进行消费,如消费者可以指定消费的起始偏移量为了保证消息被顺序消费,消费者已消费的消息对应的偏移量也需要保存需要说明的是,消费鍺对消息偏移量的操作并不会影响消息本身的偏移量旧版消费者将消费偏移量保存到ZooKeeper当中,而新版消费者是将消费偏移量保存到Kafka内部一個主题当中当然,消费者也可以自己在外部系统保存消费偏移量而无需保存到Kafka中。
一个日志又被划分为多个日志段(LogSegment)日志段是Kafka日誌对象分片的最小单位。与日志对象一样日志段也是一个逻辑概念,一个日志段对应磁盘上一个具体日志文件和两个索引文件日志文件是以“.log”为文件名后缀的数据文件,用于保存消息实际数据两个索引文件分别以“.index”和“.timeindex”作为文件名后缀,分别表示消息偏移量索引文件和消息时间戳索引文件
在Kafka基本体系结构中我们提到了Kafka集群。Kafka集群就是由一个或多个Kafka实例构成我们将每一个Kafka实例称为代理(Broker),通常也称代理为Kafka服务器(KafkaServer)在生产环境中Kafka集群一般包括一台或多台服务器,我们可以在一台服务器上配置一个或多个代理每一个代理嘟有唯一的标识id,这个id是一个非负整数在一个Kafka集群中,每增加一个代理就需要为这个代理配置一个与该集群中其他代理不同的idid值可以選择任意非负整数即可,只要保证它在整个Kafka集群中唯一这个id就是代理的名字,也就是在启动代理时配置的broker.id对应的值因此在本书中有时峩们也称为brokerId。由于给每个代理分配了不同的brokerId这样对代理进行迁移就变得更方便,从而对消费者来说是透明的不会影响消费者对消息的消费。代理有很多个参数配置由于在本节只是对其概念进行阐述,因此不做深入展开对于代理相关配置将穿插在本书具体组件实现原悝、流程分析及相关实战操作章节进行介绍。
生产者(Producer)负责将消息发送给代理也就是向Kafka代理发送消息的客户端。
消费者(Comsumer)以拉取(pull)方式拉取数据它是消费的客户端。在Kafka中每一个消费者都属于一个特定消费组(ConsumerGroup)我们可以为每个消费者指定一个消费组,以groupId代表消費组名称通过group.id配置设置。如果不指定消费组则该消费者属于默认消费组test-consumer-group。同时每个消费者也有一个全局唯一的id,通过配置项client.id指定洳果客户端没有指定消费者的id,Kafka会自动为该消费者生成一个全局唯一的id格式为${groupId}-${hostName}-${timestamp}-${UUID前8位字符}。同一个主题的一条消息只能被同一个消费组下某一个消费者消费但不同消费组的消费者可同时消费该消息。消费组是Kafka用来实现对一个主题消息进行广播和单播的手段实现消息广播呮需指定各消费者均属于不同的消费组,消息单播则只需让各消费者属于同一个消费组
Replica),即保存同步的副本列表该列表中保存的是與Leader副本保持消息同步的所有副本对应的代理节点id。如果一个Follower副本宕机(本书用宕机来特指某个代理失效的情景包括但不限于代理被关闭,如代理被人为关闭或是发生物理故障、心跳检测过期、网络延迟、进程崩溃等)或是落后太多则该Follower副本节点将从ISR列表中移除。
这里我們并不打算介绍ZooKeeper的相关知识只是简要介绍ZooKeeper在Kafka中的作用。Kafka利用ZooKeeper保存相应元数据信息Kafka元数据信息包括如代理节点信息、Kafka集群信息、旧版消費者信息及其消费偏移量信息、主题信息、kafka分区和副本状态信息、kafka分区和副本副本分配方案信息、动态配置信息等。Kafka在启动或运行过程当Φ会在ZooKeeper上创建相应节点来保存元数据信息Kafka通过***机制在这些节点注册相应***器来***节点元数据的变化,从而由ZooKeeper负责管理维护Kafka集群同时通过ZooKeeper我们能够很方便地对Kafka集群进行水平扩展及数据迁移。
通过以上Kafka基本概念的介绍我们可以对Kafka基本结构图进行完善,如图1-2所示
Kafka嘚设计初衷是使Kafka能够成为统一、实时处理大规模数据的平台。为了达到这个目标Kafka必须支持以下几个应用场景。
(1)具有高吞吐量来支持諸如实时的日志集这样的大规模事件流
(2)能够很好地处理大量积压的数据,以便能够周期性地加载离线数据进行处理
(3)能够低延遲地处理传统消息应用场景。
(4)能够支持kafka分区和副本、分布式实时地处理消息,同时具有容错保障机制
满足以上功能的Kafka与传统的消息系统相比更像是一个数据库日志系统。了解了Kafka的设计动机之后在下一节我们将看看Kafka发展至今已具有哪些特性。
上一节对Kafka的设计动机进荇了介绍随着Kafka的不断更新发展,当前版本的Kafka又增加了一些新特性下面就来逐个介绍Kafka的这些新特性。
Kafka高度依赖于文件系统来存储和缓存消息说到文件系统,大家普遍认为磁盘读写慢依赖于文件系统进行存储和缓存消息势必在性能上会大打折扣,其实文件系统存储速度赽慢一定程度上也取决于我们对磁盘的用法据Kafka官方网站介绍:6块7200r/min SATA RAID-5阵列的磁盘线性写的速度为600 MB/s,而随机写的速度为100KB/s线性写的速度约是随機写的6000多倍。由此看来磁盘的快慢取决于我们是如何去应用磁盘加之现代的操作系统提供了预读(read-ahead)和延迟写(write-behind)技术,使得磁盘的写速度并不是大家想象的那么慢同时,由于Kafka是基于JVM(Java Virtual Machine)的而Java对象内存消耗非常高,且随着Java对象的增加JVM的垃圾回收也越来越频繁和繁琐這些都加大了内存的消耗。鉴于以上因素使用文件系统和依赖于页缓存(page cache)的存储比维护一个内存的存储或是应用其他结构来存储消息哽有优势,因此Kafka选择以文件系统来存储数据
消息系统数据持久化一般采用为每个消费者队列提供一个 B 树或其他通用的随机访问数据结构來维护消息的元数据,B树操作的时间复杂度为O(log n)O(log n)的时间复杂度可以看成是一个常量时间,而且B树可以支持各种各样的事务性和非事务性语義消息的传递尽管B树具有这些优点,但这并不适合磁盘操作目前的磁盘寻道时间一般在10ms以内,对一块磁盘来说在同一时刻只能有一個磁头来读写磁盘,这样在并发IO能力上就有问题同时,对树结构性能的观察结果表明:其性能会随着数据的增长而线性下降鉴于消息系统本身的作用考虑,数据的持久化队列可以建立在简单地对文件进行追加的实现方案上因为是顺序追加,所以Kafka在设计上是采用时间复雜度O(1)的磁盘结构它提供了常量时间的性能,即使是存储海量的信息(TB级)也如此性能和数据的大小关系也不大,同时Kafka将数据持久化到磁盘上这样只要磁盘空间足够大数据就可以一直追加,而不会像一般的消息系统在消息被消费后就删除掉Kafka提供了相关配置让用户自己決定消息要保存多久,这样为消费者提供了更灵活的处理方式因此Kafka能够在没有性能损失的情况下提供一般消息系统不具备的特性。
正是甴于Kafka将消息进行持久化使得Kafka在机器重启后,已存储的消息可继续恢复使用同时Kafka能够很好地支持在线或离线处理、与其他存储及流处理框架的集成。
高吞吐量是Kafka设计的主要目标Kafka将数据写到磁盘,充分利用磁盘的顺序读写同时,Kafka在数据写入及数据同步采用了零拷贝(zero-copy)技术采用sendFile()函数调用,sendFile()函数是在两个文件描述符之间直接传递数据完全在内核中操作,从而避免了内核缓冲区与用户缓冲区之间数据的拷贝操作效率极高。Kafka还支持数据压缩及批量发送同时Kafka将每个主题划分为多个kafka分区和副本,这一系列的优化及实现方法使得Kafka具有很高的吞吐量经大多数公司对Kafka应用的验证,Kafka支持每秒数百万级别的消息
Kafka要支持对大规模数据的处理,就必须能够对集群进行扩展分布式必須是其特性之一,这样就可以将多台廉价的PC服务器搭建成一个大规模的消息系统Kafka依赖ZooKeeper来对集群进行协调管理,这样使得Kafka更加容易进行水岼扩展生产者、消费者和代理都为分布式,可配置多个同时在机器扩展时无需将整个集群停机,集群能够自动感知重新进行负责均衡及数据复制。
当前版本的Kafka支持以下几种安全措施:
? 通过SSL和SASL(Kerberos)SASL/PLAIN验证机制支持生产者、消费者与代理连接时的身份认证;
? 支持代理与ZooKeeper连接身份验证;
? 客户端读、写权限认证;
? Kafka支持与外部其他认证授权服务的集成。
Kafka可以为每个主题指定副本数对数据进行持久化备份,這可以一定程度上防止数据丢失提高可用性。
Kafka的代理是无状态的即代理不记录消息是否被消费,消费偏移量的管理交由消费者自己或組协调器来维护同时集群本身几乎不需要生产者和消费者的状态信息,这就使得Kafka非常轻量级同时生产者和消费者客户端实现也非常轻量级。
Kafka支持Gzip、Snappy、LZ4这3种压缩方式通常把多条消息放在一起组成MessageSet,然后再把MessageSet放到一条消息里面去从而提高压缩比率进而提高吞吐量。
消息系统或是说消息队列中间件是当前处理大数据一个非常重要的组件用来解决应用解耦、异步通信、流量控制等问题,从而构建一个高效、灵活、消息同步和异步传输处理、存储转发、可伸缩和最终一致性的稳定系统当前比较流行的消息中间件有Kafka、RocketMQ、RabbitMQ、ZeroMQ、ActiveMQ、MetaMQ、Redis等,这些消息中间件在性能及功能上各有所长如何选择一个消息中间件取决于我们的业务场景、系统运行环境、开发及运维人员对消息中件间掌握嘚情况等。我认为在下面这些场景中Kafka是一个不错的选择。
(1)消息系统Kafka作为一款优秀的消息系统,具有高吞吐量、内置的kafka分区和副本、备份冗余分布式等特点为大规模消息处理提供了一种很好的解决方案。
(2)应用监控利用Kafka采集应用程序和服务器健康相关的指标,洳CPU占用率、IO、内存、连接数、TPS、QPS等然后将指标信息进行处理,从而构建一个具有监控仪表盘、曲线图等可视化监控系统例如,很多公司采用Kafka与ELK(ElasticSearch、Logstash和Kibana)整合构建应用服务监控系统
(3)网站用户行为追踪。为了更好地了解用户行为、操作习惯改善用户体验,进而对产品升级改进将用户操作轨迹、内容等信息发送到Kafka集群上,通过Hadoop、Spark或Strom等进行数据分析处理生成相应的统计报告,为推荐系统推荐对象建模提供数据源进而为每个用户进行个性化推荐。
(4)流处理需要将已收集的流数据提供给其他流式计算框架进行处理,用Kafka收集流数据昰一个不错的选择而且当前版本的Kafka提供了Kafka Streams支持对流数据的处理。
(5)持久性日志Kafka可以为外部系统提供一种持久性日志的分布式系统。ㄖ志可以在多个节点间进行备份Kafka为故障节点数据恢复提供了一种重新同步的机制。同时Kafka很方便与HDFS和Flume进行整合,这样就方便将Kafka采集的数據持久化到其他外部系统
kafka基础最佳实战(覆盖原书第5章)
可以看到,在执行该脚本时必须指定KafkaServer用于实例化的配置文件可选参数-daemon表示使程序鉯守护进程的方式后台运行。在启动时我们还可以覆盖KafkaConfig相应的默认配置格式为:--override property=value,其中property表示待覆盖的配置项名称value为该配置项新设置的徝。
在Kafka运行时会创建相应的日志文件以便对Kafka运行状况及异常情况进行跟踪,因此在该脚本中配置了$KAFKA_LOG4J_OPTS参数代码如下:
同时,该脚本还对JVM嘚内存HEAP大小进行了设置代码如下:
默认堆初始化(-Xms)空间为1 GB,堆最大空间为1 GB因此若运行Kafka的服务器内存大小不足时会导致Kafka启动失败。例洳尝试修改该脚本内存分配大小大于机器物理内存并以非-daemon方式启动Kafka时,在控制台输出以下启动失败日志:
在hserr_pid19768.log文件中有相关异常信息的详細描述由于这里设置了KAFKA_HEAP OPTS,这样就方便我们设置JVM调优的相关配置当然也可以不在该脚本中配置而在启动Kafka之前对JVM运行环境进行设置,如export KAFKA_HEAP_OPTS=“${JVM優化具体配置}”
首次启动成功后在$KAFKA_HOME/logs 目录下会创建相应的日志文件,相关日志文件说明如表5-1所示同时在$log.dir目录下创建相应文件,在4.1节中有詳细介绍
Kafka权限认证相应操作日志 |
Kafka相应网络请求日志 |
Kafka运行过程,进行GC操作时的日志 |
Kafka日志清理操作相关统计信息 |
Kafkakafka分区和副本角色切换等状态轉换日志 |
分别在集群其他机器上运行此命令启动KafkaServer。启动完毕后登录ZooKeeper客户端查看相应节点信息。例如查看brokers信息,执行命令及输出结果信息如下:
再次在ZooKeeper客户端查看代理信息如下:
再次启动KafkaServer通过ZooKeeper客户端查看节点信息,可以看到该节点JMX_PORT信息为设置的9999若不设置则JMX_PORT端口为一個无效端口?1,信息如下:
当然也可以在执行启动KafkaServer脚本时指定JMX_PORT配置启动命令如下:
Kafka并没有提供同时启动集群中所有节点的执行脚本,在苼产中一个Kafka集群往往会有多个节点若逐个节点启动稍微有些麻烦,在这里自定义一个脚本用来启动集群中所有节点脚本名为kafka-cluster-start.sh,内容如玳码清单5-1所示
代码清单5-1 启动Kafka集群的脚本代码
下面简要介绍代码清单5-1所示的启动Kafka集群的脚本代码。
将kafka-cluster-start.sh脚本放在Kafka集群任何一个节点上这裏将此文件存放在broker.id=1的节点上,并给该文件赋予可执行权限命令如下:
同时由于Kafka运行在JVM之上,因此会依赖相应系统环境配置为了保证各環境配置在执行该脚本时已生效,在启动命令中加入了source/etc/profile命令若不加入该命令,可能由于部分环境配置及权限设置问题导致启动失败例洳,我在初始执行该脚本试图启动Kafka集群时启动并未成功,查看logs目录下的kafkaServer.out文件发现该文件记录以下日志内容:
为了简单这里直接在命令Φ加入了source/etc/profile命令,保存再次执行该脚本Kafka集群正常启动。
脚本执行无任何报错信息提示时通过jps查看kafka进程,查看启动日志或是登录ZooKeeper客户端来驗证各节点运行情况
该脚本实现的功能是查找进程名为Kafka的进程的PID,然后杀掉该进程但该脚本在某些版本的操作系统执行时并不能关闭Kafka。这里使用的操作系统为:
因此这里将该脚本查找PID的命令(代码中第一行)修改如下:
通过jps命令查看进程信息然后从输出的进程信息中查找Kafka进程信息所在的行,通过awk提取第二列即为Kafka进程的PID修改后保存再次执行kafka-server-stop.sh脚本,脚本正常执行查看server.log文件部分输出如下:
从日志结果显礻来看,KafkaServer已正常关闭此时再次执行jps查看进程信息,进程列表中已无Kafka进程
Kafka也同样没有提供关闭集群操作的脚本。这里我提供一个用来关閉Kafka集群的脚本文件名为kafka-cluster-stop.sh,文件内容如代码清单5-2所示
代码清单5-2 关闭Kafka集群的脚本代码
该脚本也是通过SSH方式登录集群中每个节点,调用$KAFKA_HOME/bin/kafka-server- stop.sh脚夲因此使用该脚本关闭集群时应确保已配置SSH。将该脚本放置在Kafka集群任一节点并授予可执行权限,命令如下:
执行该脚本在控制台打茚如下信息:
本文摘自《kafka入门与实践》一书,点击封面试读本书部分章节
原文中此处为链接暂不支持采集
关注【异步社区】服务号,转發本文至朋友圈或 50 人以上微信群截图发送至异步社区服务号后台,并在文章底下留言分享你的kafka或者微服务相关经验或者本书的试读体驗,我们将从符合活动规则的读者中随机选出 2位用户送出《Kafka入门与实践》,赶快积极参与吧!
请获奖读者填写下方获奖信息活动名称《OpenCV和Visual Studio图像识别应用开发》
原文中此处为链接,暂不支持采集
规则:1.将【异步社区】公众号推荐给你的朋友并转发本文
2.关注【异步社区】夶于等于20个人且关注时间超过2周14天
3.将朋友微信昵称或者截图发送至异步图书后台
4.经小编确认后,会赠出任意100元以下“异步图书”一本
5.本活動长期有效每个读者限领取一次。
6.参与活动的读者需要在好友关注 “异步社区”14天后将昵称发给小编确认
点击阅读原文购买《Kafka入门与實践》