kafka总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kafka总结相关的知识,希望对你有一定的参考价值。
参考技术A创建消息。一般情况下一个消息会被发布到一个特定的主题上。生产者在默认情况下把消息均衡地分布到主题的所有分区上,而并不关心特定消息会被写到哪个分区。不过,在某些情况下,生产者会把消息直接写到指定的分区。通常是通过消息键和分区器来实现,分区器为键生成一个散列值,并将其映射到指定的分区上。这样可以保证包含同一个键的消息会被写到同一个分区上。生产者也可以使用自定义的分区器。
读取消息。消费者订阅一个或多个主题,并按照消息生产的顺序读取它们。消费者通过检查消息的偏移量来区分已经读取过的消息。偏移量是另一种元数据,他是一个不断递增的整数值,在创建消息时,Kafka回吧它添加到消息里。在给定的分区里,每个消息的偏移量都是唯一的。消费者把每个分区最后读取的消息偏移量保存在Zookeeper或者Kafka上,如果消费者关闭或重启,它的读取状态不会丢失。
kafka通过partition的概念,保证了partition内消息有序性,缓解了上面的问题。 partition内消息会复制分发给所有分组 ,每个分组只有一个consumer能消费这条消息。这个语义保证了某个分组消费某个分区的消息,是同步而非并发的。如果一个topic只有一个partition,那么这个topic并发消费有序,否则只是单个partition有序。
消费者是消费者群组的一部分,也就是说,会有一个或多个消费者共同读取一个主题。群组保证每个分区只能被一个消费者使用。
假设这么个场景:我们从Kafka中读取消息,并且进行检查,最后产生结果数据。我们可以创建一个消费者实例去做这件事情,但如果生产者 写入消息的速度比消费者读取的速度快 怎么办呢?这样随着时间增长,消息堆积越来越严重。对于这种场景,我们需要 增加多个消费者来进行水平扩展 。
我们可以 通过增加消费组的消费者来进行水平扩展提升消费能力 。这也是为什么建议创建主题时使用比较多的分区数,这样可以在消费负载高的情况下增加消费者来提升性能。另外,消费者的数量不应该比分区数多,因为多出来的消费者是空闲的,没有任何帮助。
Kafka一个很重要的特性就是,只需写入一次消息,可以支持任意多的应用读取这个消息。换句话说,每个应用都可以读到全量的消息。为了使得 每个应用都能读到全量消息,应用需要有不同的消费组 。对于上面的例子,假如我们新增了一个新的消费组G2,而这个消费组有两个消费者,那么会是这样的:
总结起来就是:如果应用需要读取全量消息,那么请为该应用设置一个消费组;如果该应用消费能力不足,那么可以考虑在这个消费组里增加消费者 。
可以看到,当新的消费者加入消费组,它会消费一个或多个分区,而这些分区之前是由其他消费者负责的;另外,当消费者离开消费组(比如重启、宕机等)时,它所消费的分区会分配给其他分区。这种现象称为 重平衡(rebalance) 。重平衡是Kafka一个很重要的性质,这个性质保证了高可用和水平扩展。不过也需要注意到,在重平衡期间,所有消费者都不能消费消息,因此会造成整个消费组短暂的不可用。而且,将分区进行重平衡也会导致原来的消费者状态过期,从而导致消费者需要重新更新状态,这段期间也会降低消费性能。后面我们会讨论如何安全的进行重平衡以及如何尽可能避免。
消费者通过定期发送心跳(hearbeat)到一个作为组协调者(group coordinator)的broker来保持在消费组内存活。这个broker不是固定的,每个消费组都可能不同。当消费者拉取消息或者提交时,便会发送心跳。
如果消费者超过一定时间没有发送心跳,那么它的会话(session)就会过期,组协调者会认为该消费者已经宕机, 然后触发重平衡 。可以看到,从消费者宕机到会话过期是有一定时间的,这段时间内该消费者的分区都不能进行消息消费;通常情况下,我们可以进行优雅关闭,这样消费者会发送离开的消息到组协调者,这样组协调者可以立即进行重平衡而不需要等待会话过期。
在0.10.1版本,Kafka对心跳机制进行了修改,将发送心跳与拉取消息进行分离,这样使得发送心跳的频率不受拉取的频率影响。另外更高版本的Kafka支持配置一个消费者多长时间不拉取消息但仍然保持存活,这个配置可以避免活锁(livelock)。活锁,是指应用没有故障但是由于某些原因不能进一步消费。
Kafka总结:Kafka概述
Kafka是什么?
KafKa是一个高吞吐量、分布式的发布——订阅消息系统。据KafKa官网介绍,当前的KafKa已经定位为一个分布式流式处理平台(a distributed streaming platform),它以可水平扩展和具有高吞吐量等特性而著称。越来越多的开源分布式处理系统(Flume、Apache Storm 、Spark、Flink等)支持与KafKa集成。
1.Kafka简介
1.Kafka背景
计算机所存储的信息量正在呈爆炸式的增长,目前数据量已经进入大规模和超大规模的海量数据时代,如何高效的存储、分析、处理和挖掘海量数据已经成为技术研究的热点和难点问题。
当前出现的云存储、分布式存储系统、NoSQL数据库以及列存储等前沿技术在海量数据的驱使下,正在日新月异的向前发展,采用这些技术来处理大数据称为一种发展趋势。
而如何采集和运营管理、分析这些数据也是大数据处理中的一个至关重要的组成环节,这就需要相应的基础设施对其提供支持。
针对这个需求,当前业界已有很多开源的消息系统应运而生,KafKa就是当前流行的一款非常优秀的消息系统;
KafKa是一款开源的、轻量级的、分布式、可分区和具有复制备份的(Replicated)、基于ZooKeeper的协调管理的分布式流平台的功能强大的消息系统。与传统的消息系统相比,KafKa能够很好的处理活跃的流数据,使得数据在各个子系统中高性能、低延迟地不停流转。
据KafKa官网介绍,KafKa定位就是一个分布式流处理平台,作为一个流式处理平台,必须具备以下三个特征:
能够允许发布和订阅流数据。从这个角度来讲,平台更像是一个消息队列或者企业级的消息系统;
存储流数据的时候提供相应的容错机制;
当流数据达到的时候能够即时的被处理;
kafka能够很好的满足以上3个特性,通过kafka能够很好的建立实时流式数据通道,由该通道可靠地获取系统或者应用程序的数据,也可以通过kafka方便的构建实时流数据应用来转换或者是对流数据进行响应处理。特别是在0.10版本之后,KafKa推出KafKa Streams,这让KafKa对流数据处理变得更加的方便。
2. KafKa基本结构
KafKa的结构需要解决如下的问题:
生产者负责生产消息,如何写入KafKa集群。
消费者如何从KafKa集群中拉取消息
KafKa如何存储消息
KafKa集群如何管理调度
如何进行负载均衡
各组件之间如何进行通信
3. KafKa基本概念
【1】主题
KafKa将一组消息抽象归纳为一个主题(Topic),也就是说,一个主题就是对消息的一个分类。生产者将消息发送到特定主题,消费者订阅主题或者主题的某些分区进行消费。
【2】消息
消息是KafKa通信的基本单位,由一个固定长度的消息头和一个可变长度的消息体构成。在老版本中,每一条消息称为Message;在由Java重新实现的客户端中,每一条消息称为Record。
【3】分区和副本
KafKa将一组消息归纳为一个主题,而每个主题又被分为一个或者多个分区(Partition)。每个分区有一系列有序、不可变的消息组成,是一个有序队列;
每个分区在物理上对应一个文件夹,分区命令规则:主题名称—分区编号
分区编号从0开始。每个分区又有一至多个副本(Replica),分区的副本分布在集群的不同代理上,以提高可用性。从存储的角度分析,分区的每个副本在逻辑上抽象为一个日志(Log)对象,即分区的副本与日志对象是一一对应的关系。每个主题对应的分区数可以在KafKa启动的时候所加载的配置文件中配置,也可以在创建主题的时候指定。客户端还可以在创建主题之后修改主题的分区数;
分区使得KafKa在并发处理上变得更加简单,理论上来讲,分区数越多吞吐量越高,但是这需要根据集群实际的环境和业务场景来决定。同时分区也是KafKa保证消息被顺序消费以及对消息进行负载均衡的基础;
注意:KafKa只能保证一个分区之内的消息的有序性,并不能保证跨分区消息的有
序性。每条消息被追加到相应的分区中,是顺序写磁盘,效率非常高,这是KafKa高吞吐率的一个重要保证。
与传统消息不同的一点:KafKa并不会立即删除已经被消费的数据,KafKa提供了两种删除老数据的方式:
第一种:基于消息已经存储的时间长度;
第二种:基于分区的大小;
以上两种策略都能够通过配置文件进行配置;
【4】Leader副本和Follower副本
由于KafKa副本的存在,就需要保证一个分区的多个副本之间数据的一致性,KafKa会选择该分区的一个副本作为Leader副本,而该分区其他副本作为Follower副本,只有Leader副本才负责处理客户端读/写请求,Follower副本从Leader副本同步数据。如果Leader副本失效,通过相应的选举算法将从其他Follower副本中选出新的Leader副本。
【5】偏移量
任何发布到分区的消息会直接追加到日志文件(分区目录下以.log为文件名后缀的数据文件)的尾部,而每条消息在日志中的位置都会对应一个按顺序递增的偏移量。偏移量是一个分区下严格有序的逻辑值,它并不表示消息在磁盘上的物理位置。由于KafKa几乎不允许对消息进行随机读写,因此KafKa并没有提供额外的索引机制到存储偏移量,也就是说并不会给偏移量再提供索引。
消费者可以通过控制消息偏移量来对消息进行消费,如消费者可以指定消费的起始偏移量。为了保证消息顺序消费,消费者已经消费的信息对应的偏移量也需要保存。
需要说明的是:消费者对消息偏移量的操作并不会影响消息本身的偏移量。旧版消费者将消费偏移量保存到ZooKeeper当中,而新版的消费者是将消费偏移量保存到KafKa内部的一个主题当中。
当然消费者也可以自己在外部系统保存消费偏移量,而无需保存到KafKa中;
【6】日志段
一个日志又被划分为多个日志段(LogSegment),日志段是KafKa日志对象分片中的最小单位。与日志对象一样,日志段也是一个逻辑概念,一个日志段对应磁盘上的一个日志文件(.log)和两个索引文件:(.index)表示消息偏移量索引文件,(.timeindex)表示消息时间戳索引文件。
【7】代理
KafKa集群就是由一个或者多个KafKa实例构成,每一个KafKa实例称为代理(Broker),通常也称代理为KafKa服务器(KafKaServer)。在生产环境中KafKa集群一般包括一台或者多台机器,我们可以在一台机器上配置一个或者多个代理。每一个代理具有唯一的与该集群中其他代理都不同的非负整数的id,这个id就是代理的名字,也就是在启动代理的时候配置的broker.id对应的值。
代理有很多相关的参数配置;
【8】生产者
生产者(Producer)负责将消息发送给代理,也就是向KafKa代理发送消息的客户端;
【9】消费者和消费组
消费者(Consumer)以拉取(Pull)方式拉取数据,它是消费的客户端。在KafKa中每一个消费者都属于一个特定的消费者组(ConsumerGroup),我们可以为每个消费者指定一个消费组,以groupId代表消费组名称,通过group.id配置设置。我们不指定消费组,则该消费者属于默认的消费组test-consumer-group。同时,每个消费者也有一个全局唯一的id,通过配置项client.id指定,如果客户端没有指定消费者的id,KafKa会自动为该消费者生成一个全局唯一的id,格式如下:
${groupId}-${timestamp}-${UUID前8位字符}。
注意:同一个主题的一条消息只能被同一个消费组下某一个消费者消费,但是不同消费组的消费者可以同时消费该消息。消费组是KafKa用来实现对一个主题消息进行广播和单播的手段,实现消息广播只需要指定各个消费者均属于不同的消费组,消息单播则只需让各个消费者属于同一个消费组。
【10】ISR
KafKa在ZooKeeper中动态维护了一个ISR(In-sync Replica)即保存同步的副本列表,该列表中保存的是与Leader副本保持消息同步的所有副本对应的代理节点id。
如果一个Follower副本宕机(本书用宕机来特指某个代理失效的情景,包括但不咸鱼代理被关闭,如代理被人为关闭或是发生物理故障、心跳检测过期、网络延迟、进程崩溃等)或者落后太多,则该Follower副本节点将从ISR列表中移除;
【11】ZooKeeper
这里我们并不打算介绍ZooKeeper的相关知识,只是简要的介绍ZooKeeper在KafKa中的作用。KafKa利用ZooKeeper保存相应元素据信息,KafKa元素据包括如代理节点信息、KafKa集群信息、旧版消费者信息以及消费偏移量信息、主题信息、分区状态信息、分区副本分配方案信息、动态配置信息等。KafKa在启动或者运行过程中会在ZooKeeper上创建相关的节点来保存元数据信息,KafKa通过监听机制在这些节点注册相应监听器来监听节点元素据的变化,从而由ZooKeeper负责管理维护KafKa集群,同时通过ZooKeeper我们能够很方便的对KafKa集群进行水平扩展以及数据迁移;
4. KafKa设计概述
1. KafKa设计动机
KafKa设计的初衷是是KafKa能够成为统一的、实时处理大规模平台数据。为了达到这个目标,KafKa必须支持以下的几个应用场景:
具有高吞吐量来支持诸如实时的日志集这样的大规模事件流;
能够很好的处理大量积压的数据,以便能够周期性的加载离线数据进行处理。
能够低延迟的处理传统消息应用场景;
能够支持分区、分布式、实时地处理消息,同时具有容错保障机制。
满足了以上功能的KafKa与传统的消息系统相比更像是一个数据库日志系统。
2. KafKa特性
【1】消息持久化
KafKa高度依赖于文件系统来存储和缓存消息。说到文件系统,大家普遍任务磁盘读写慢,依赖于文件系统进行存储和缓存消息势必在性能上会大打折扣,其实文件系统存储速度快慢一定程度上也取决于我们对磁盘的用法。
KafKa官网介绍:磁盘线性写的速度约是随机写的速度的6000多倍。由此看来,磁盘的快慢取决于我们是如何应用磁盘的。
KafKa是基于JVM的,Java对象的增加会导致JVM的垃圾回收也越来越繁琐,这些都加大了内存的消耗。鉴于以上因素,使用文件系统和依赖于页缓存(page cache)的存储比维护一个内存的存储或者是应用其他结构存储消息更有优势,因此KafKa选择以文件系统来存储数据;
因为是顺序追加,所以KafKa在设计上是采用的时间复杂度为O(1)的磁盘结构,它提供了常量的时间性能,即使是存储海量信息(TB级别)也是如此,性能和数据的大小关系也不大,同时KafKa将数据持久化到磁盘上,这样只要磁盘空间足够大数据就可以一直追加,而不会想消息系统在消息被消费之后就删除掉,KafKa提供了相关配置让用户决定消息需要保存多久,因此,KafKa能够在没有性能损失的情况下提供一般消息系统不具备的特性;
正式因为KafKa将消息持久化,使得KafKa在机器重启之后,已存储的消息可以继续恢复使用。同时KafKa能够很好的支持在线或者离线的处理、与其他存储以及流处理框架集成;
【2】高吞吐量
高吞吐量是KafKa设计的主要目标,KafKa将数据写到磁盘,充分利用磁盘的顺序读写。同时KafKa在数据写入以及数据同步采用了零拷贝(zero-copy)技术,采用sendFile()函数调用,该函数是在两个文件描述符之间直接传递数据,完全在内核中操作,从而避免了内核缓冲区与用户缓冲区之间数据的拷贝,操作效率极高。KafKa还支持数据压缩以及批量发送,同时KafKa将每个主题划分为多个分区,这一系列的优化以及实现方法使得KafKa具有很高的吞吐量。
KafKa支持每秒钟数百万级别的消息;
【3】扩展性
KafKa依赖ZooKeeper来对集群进行协调管理,这样使得KafKa更加容易进行水平扩展。生产者、消费者和代理都为分布式,可以配置多个。同时在机器扩展的时候无需将整个集群停机,集群可以自动的感知,重新进行负载均衡以及数据复制;
【4】多客户端支持
KafKa支持多种连接器和多种语言接入,与当前大多数主流的数据框架都可以很好的集成;
【5】KafKa Streams
KafKa Streams是一个用Java语言实现的用于流处理的jar文件;
【6】安全机制
通过SSL和SASL(Kerberos),SASL/PLAIN验证机制支持生产者、消费者与代理连接时的身份认证;
支持代理与ZooKeeper连接身份验证;
通信的时候数据加密;
客户端读、写权限认证;
KafKa支持与外部其他认证授权服务的集成;
【7】数据备份
KafKa可以为每个主题指定副本数,对数据进行持久化备份,这可以在一定的程度上方式数据的丢失,提高可用性;
【8】轻量级
KafKa的代理是无状态的,代理不记录消息是否被消费,消息偏移量的管理工作交由消费者自身或者组协调器来完成。同时集群本身不需要生产者和消费者的状态信息,这就使得KafKa非常的轻量级;
【9】消息压缩
KafKa支持Gzip、Snappy以及LZ4这三种压缩方式,通常把多条消息放在一起组成MessageSet,然后将MessageSet放到一条消息里面,从而提高压缩比率进而提高吞吐量;
3. KafKa应用场景
消息系统或者是说消息队列中间件是当前处理大数据的一个非常重要的组件,用来解决应用解耦、异步通信、流量控制等问题,从而构建一个高效、灵活、消息同步和异步传输处理、存储转发、可伸缩和最终一致性的稳定系统。
当前比较流行的消息中间件有:KafKa、RocketMQ、RabbitMQ、ZeroMQ、ActiveMQ、Redis等,这些消息中间件在性能以及功能上各有所长。如何选择一个消息中间件取决于我们的业务场景、系统运行环境、开发人员以及运维人员对消息中间件的情况等。
以下的场景可以选择使用KafKa:
(1):消息系统:
KafKa作为一个优秀的消息系统,具有高吞吐量、内置的分区、备份冗余分布式的特点,为大规模的消息处理提供了一种很好的解决方案;
(2):应用监控:
利用KafKa采集应用程序和服务器健康相关指标,如CPU占用率、IO、内存、连接数、TPS、QPS等,然后将指标信息进行处理,从而可以构建一个具有监控仪表盘、曲线图等可视化监控系统。例如:很多公司采用KafKa与ELK(Elasticsearch、Logstash和Kibana)真核构建应用服务监控系统;
(3):网站用户行为追踪:
为了更好的了解用户的行为,操作习惯,改善用户体验,进而对产品进行升级,将用户的操作轨迹、内容等信息发送到KafKa集群上,通过Hadoop、Spark或者Strom等进行数据分析处理,生成相应的统计报告,未推荐系统推荐对象提供数据源,进而为每个用户进行个性化推荐;
(4):流处理:
需要将已经收集的流数据提供给其他流式计算框架进行处理,KafKa已经提供了KafKa Streams支持对流数据的处理;
(5):持久性日志:
KafKa可以为外部系统提供一种持久性日志的分布式系统。日志可以在多个节点之间进行备份,KafKa为故障节点数据恢复提供了一种重新同步机制。同时,KafKa很方便的与HDFS和Flume进行整合,这样就可以方便的将KafKa采集的数据持久化到其他的外部系统;
以上是关于kafka总结的主要内容,如果未能解决你的问题,请参考以下文章