前言说完,进入正题。今天给大家带来的是我们的老朋友卡夫卡的前世今生。随着对实时性的要求越来越高,在庞大的数据传输过程中如何保证数据的快速传递,于是,消息队列就产生了。“消息”是在两台计算机之间传输的数据单元。消息可以像文本字符串一样简单,也可以更复杂并且可能包含嵌入式对象。消息被发送到队列。“消息队列”是在传输过程中保存消息的容器。Kafka是一个分布式消息队列,掌握它是我们必不可少的。本文详细介绍了Kafka的基本组件及其基本应用的实现细节。同时也熬了几天画图,希望能让大家更深入的了解Kafka的核心知识,最后总结一下Kafka在实际业务中的应用。让我们和小鱼一起了解一下这些属于Kafka的小秘密:Kafka概念Kafka是一个高吞吐量、分布式、基于发布/订阅的消息系统,最初由LinkedIn开发,用Scala语言编写,目前是Apache的开源项目。Kafka主要组件broker:Kafka服务器,负责消息的存储和转发topic:消息类别,Kafka根据topic分区:topic分区,对消息进行分类,一个topic可以包含多个partition,topic消息保存在每个partition中offset:消息在log可以理解为消息在partition上的偏移量,也是代表消息的唯一序号Producer:消息生产者Consumer:消息消费者ConsumerGroup:消费者组,每个Consumer必须属于一个组Zookeeper:save此外,它还负责broker故障发现、partitionleader选举、负载均衡等功能。Kafka的优势解耦:消息系统在处理过程中间插入了一个隐式的、基于数据的接口层,两边的处理都必须实现这个接口。这允许您独立地扩展或修改两侧的处理,只要它们遵守相同的接口约束。冗余:消息队列将数据持久化,直到它们被完全处理,通过这种方式避免了数据丢失的风险。在很多消息队列采用的“插入-获取-删除”范式中,在从队列中删除消息之前,您需要您的处理系统清楚地表明该消息已被处理,以确保您的数据被安全保存。直到你用完它。可扩展性:因为消息队列解耦了你的处理,所以很容易增加消息入队和处理的频率,只要增加额外的处理。无需更改代码,无需调整参数。扩展就像打开电源按钮一样简单。灵活性和峰值处理能力:使用消息队列可以使关键组件能够承受突然的访问压力,而不会因突然的过载请求而完全崩溃。可恢复性:消息队列降低了进程之间的耦合度,因此即使一个消息处理进程挂掉了,加入到队列中的消息在系统恢复后仍然可以继续处理。顺序保证:大多数消息队列都是排序的,可以保证数据按照特定的顺序进行处理。Kafka保证Partition中消息的顺序。缓冲:消息队列通过缓冲层帮助任务最有效地执行。尽快处理对队列的写入。这种缓冲有助于控制和优化数据流经系统的速度。异步通信:消息队列提供了一种异步处理机制,允许用户将消息放入队列,但不立即处理。将任意多的消息放入队列,并在需要时处理它们。Kafka应用场景活动追踪:追踪网站用户与前端应用的交互,如:网站PV/UV分析及消息传递:系统间的异步信息交互,如:营销活动(注册后发送优惠码福利)Profit)日志收集:收集系统和应用的指标和日志,如:应用监控和告警提交日志:发布数据库更新到Kafka,如:事务统计Kafka数据存储设计分区数据文件分区中的每条Message包含三个属性:offset,MessageSize,data,其中offset表示Message在本分区的偏移量,offset并不是Message在分区数据文件中的实际存储位置,而是一个逻辑值,它在分区中唯一确定了一个Message,可以认为offset是分区中Message的id;MessageSize表示消息内容数据的大小;data是Message的具体内容。数据文件分段segmentpartition在物理上由多个段文件组成,每个段大小相等,顺序读写。每个段数据文件以段中最小的偏移量命名,文件扩展名为.log。这样,在查找指定偏移量的Message时,可以通过二分查找的方式定位到该Message在哪个segment数据文件中。数据文件索引Kafka为每个segmented数据文件创建一个索引文件。文件名与数据文件名相同,但文件扩展名为.index。索引文件不为数据文件中的每一个Message建立索引,而是采用稀疏存储的方式,每隔一定字节的数据建立一个索引。这样可以避免索引文件占用过多的空间,从而可以将索引文件保存在内存中。zookeeper在kafka中的作用,无论是kafka集群,还是生产者和消费者,都依赖zookeeper来保证系统的可用性,集群保存一些元信息。Kafka使用zookeeper作为其分布式协调框架,很好的结合了消息生产、消息存储、消息消费的过程。同时,在zookeeper的帮助下,kafka可以在无状态的情况下建立生产者和消费者之间的订阅关系,实现生产者和消费者之间的负载均衡。Producer设计负载均衡由于消息topic由多个partition组成,partition会平均分配给不同的broker。因此,为了有效利用broker集群的性能,提高消息的吞吐量,producer可以随机或者hash将消息平均发送到多个partition,实现负载均衡。批量发送是提高消息吞吐量的重要方式。将内存中的多条消息合并后,Producer端可以一次请求发送一批消息给broker,从而大大减少了broker存储消息的IO操作次数。但也在一定程度上影响了消息的实时性,相当于以延迟为代价换取更好的吞吐量。压缩Kafka支持批量发送消息。在此基础上,Kafka还支持消息集合的压缩。Producer端可以将消息集合压缩为GZIP或Snappy格式。在Producer端压缩后,需要在Consumer端解压。压缩的好处是减少传输的数据量,减轻网络传输的压力。在处理大数据时,瓶颈往往体现在网络上,而不是CPU上(压缩和解压会消耗一部分CPU资源)。那么如何区分消息是压缩的还是未压缩的呢?Kafka在消息头中添加一个描述压缩属性的字节。该字节的最后两位表示用于消息压缩的编码。如果最后两位为0,则表示消息没有被压缩。Consumer设计ConsumerGroup同一个ConsumerGroup中的多个Consumer实例不会同时消费同一个partition,相当于队列模式。分区中的消息是有序的,Consumer通过pull来消费消息。Kafka不会删除消费过的消息。对于partition,顺序读写磁盘数据,提供时间复杂度O(1)的消息持久化能力。Kafka作为消息系统的实际应用kafka通过在主题中具有并行性(分区)的概念,Kafka能够提供排序保证和跨消费者进程池的负载平衡。这是通过将主题中的分区分配给消费者组中的消费者来实现的,以便每个分区仅由组中的一个消费者消费。通过这样做,我们确保消费者是分区的唯一读者并顺序消费数据。由于有许多分区,这仍然可以在许多消费者实例之间平衡负载。但是要注意,一个消费者组中的消费者实例不能超过分区。Kafka作为存储系统Kafka是一个非常优秀的存储系统。写入Kafka的数据被写入磁盘并复制以实现容错。Kafka允许生产者等待确认,以便写入在完全复制之前不会被视为完成,并且即使写入的服务器发生故障也能保证持久存在。磁盘上结构化的Kafka很好地利用了规模——无论您在服务器上有50KB还是50TB的持久数据,Kafka都会执行相同的操作。由于它非常重视存储并允许客户端控制从何处读取,因此您可以将Kafka视为一种专为高性能、低延迟提交日志存储、复制和传播而设计的分布式文件系统。KafkaforStreamProcessing对于复杂的转换,Kafka提供了一个完全集成的StreamsAPI。这允许构建执行重要处理、计算流聚合或将流连接在一起的应用程序。该工具有助于解决此类应用程序面临的挑战:处理乱序数据、在代码更改时重新处理输入、执行有状态计算等。流式API建立在Kafka提供的核心原则之上:它使用生产者和消费者APIinput,使用Kafka做有状态存储,流处理器实例之间使用同组机制实现容错*。
