在这篇《360度测试:KAFKA会丢数据么?其高可用是否满足需求?》中,我们详细介绍了KAFKA是否适合在业务系统中使用。但是有些朋友不知道KAFKA是什么,为什么存在。这在工作和面试中都是一个劣势,因为不知道从什么时候开始,KAFKA似乎已经成为了工程师的必备技能。一些概念上的修改从0.9版本开始,Kafka的标语从“一个高吞吐量的分布式消息系统”变成了“一个分布式流媒体平台”。Kafka不仅仅是一个队列,更是一个具有超强积累能力的存储。Kafka不仅适用于吞吐量大的大数据场景,也适用于有事务需求的业务系统,但性能较低。Kafka并不是说topic越多越好。由于其设计原理,在数量达到阈值后,其性能与主题数量成反比。引入消息队列就相当于引入了异步,不管你的目的是什么。这通常意味着业务流程的改变,甚至是产品体验的改变。消息系统的典型场景是什么?上图展示了一些小型系统的典型架构。考虑到一个订单的业务场景,有大量的请求指向我们的业务系统。如果我们通过复杂的业务逻辑直接进入业务表,会导致大量请求超时失败。所以我们添加了一个中间缓冲表(或Redis)来接受用户请求。然后就是定时任务,不断从缓冲表中获取数据,进行真正的业务逻辑处理。这种设计存在以下问题:定时任务的轮询间隔不易控制。业务处理容易出现延误。处理能力无法横向扩展,会引入分布式锁、顺序保证等问题。当其他业务也需要这些订单数据时,必须将业务逻辑添加到定时任务中。当访问量越来越大,业务逻辑越来越复杂时,消息队列就呼之欲出了。请求会暂时存储在消息队列中,然后通过推送(或拉取)的方式进行实时处理。在这种情况下,消息队列充当调峰和冗余组件。消息系统的作用是削峰填谷。用于接受超过业务系统处理能力的请求,使业务顺利运行。这样可以节省很多成本。例如,某些限时抢购活动并非针对高峰容量而设计。Buffering作为缓冲层存在于服务层和慢速登陆层,作用类似于调峰,但主要用于服务内部的数据流转。比如群发短信。解耦项目启动,具体需求无法确定。消息队列可以作为接口层来解耦重要的业务流程。您只需要遵守数据的协议和程序,就可以获得可扩展性。冗余的消息数据可以被多个不相关的服务以一对多的方式使用。健壮性消息队列可以积累请求,所以即使消费端业务短时间挂掉,也不会影响主业务的正常进行。消息系统需求既然消息系统如此重要,那么除了要保证高可用之外,对于自身的特性也有很高的要求。总的来说有以下几点:高性能,包括消息传递和消息消费,要快。通常,并行处理能力是通过增加分片数量来获得的。消息必须可靠在某些场景下,消息不能丢失。生产端、消费端、MQ端都不能丢消息。一般可以通过加副本和强制刷盘的方式解决。可扩展性更好。它可以陪你把项目做大,陪你到时间的尽头。添加节点后,集群不会降低性能。生态成熟度监控、运维、多语言支持、社区活跃。KAFKA术语解释基本功能Kafka是一个分布式消息(存储)系统。分布式系统通过碎片增加并行性;通过副本增加可靠性,Kafka也不例外。让我们看一下它的结构并沿途解释术语。你在一台机器上安装了Kafka,那么这台机器就叫做Broker,KAFKA集群中包含一个或多个这样的实例。负责向KAFKA写入数据的组件称为Producer,消息的生产者一般写在业务系统中。发送给KAFKA的消息可能有很多种,如何区分它们的类别?就是Topic的概念。一个topic被分发后,可能存在于多个Broker上。将Topic拆分成多个段,提高并行度。每个部分称为一个Partition,分区一般均匀分布在所有机器上。那些在Kafka中消费数据的应用程序称为消费者。我们给某个topic的某个消费业务起个名字,所以名字叫ConsumerGroupExtendedFunctionConnectorConnectorTask,包括Source和Sink两个接口,为用户提供自定义数据流的可能。比如从JDBC导入到Kafka,或者直接将Kafka数据落地到DB。Stream类似于SparkStream,能够进行流式数据处理。但是它本身并没有集群,它只是在KAFKA集群上的一个抽象。如果您想要实时流处理并且不需要来自Hadoop生态系统的东西,那么这就是为您准备的。主题我们的新闻写在主题中。对于多个主题,可以对消息进行分类和隔离。比如登录信息写在user_activity_topic中,日志信息写在log_topic中。每个主题都可以调整其分区数。假设我们的集群有3个Broker,那么当partition数量为1时,消息只会写在其中一个节点上;当我们的partition为3时,消息会根据hash写入三个节点;当我们的partition是6时,那么每个node都会有2个partition信息。增加分区可以增加并行度,但不是越多越好。一般6-12最好,最好能被节点数整除,避免数据倾斜。每个分区由一系列有序的不可变消息组成,这些消息按顺序附加。分区中的每条消息都有一个连续的序列号,称为偏移量。Kafka会在配置的时间内保留所有消息,所以它也是一个临时存储。在此期间,所有的消息都可以被消费,并且可以通过改变offset的值来重复多次消费。Offset一般由消费者管理,当然也可以通过程序根据需要设置。偏移量只有在提交后才会改变,否则,你将永远得到重复的数据。新的Kafka把这些Offsets放到了一个专门的topic中:__consumer_offsets,也就是上图中的紫色区域。值得一提的是消费者的数量不要超过分区的数量。否则,额外的消费者将不会收到任何数据。ISR分布式系统保证数据可靠性的常用方法是增加副本数,ISR就是基于这种方法。ISR的全称是“In-SyncReplicas”,是保证HA和一致性的重要机制。副本数对Kafka的吞吐量有一定的影响,但是大大增强了可用性。一般2-3个为宜。副本有两个要素,一是数量要足够,二是不要落在同一个实例上。ISR是针对Partition的,每个partition都有一个同步列表。N个副本中,其中一个副本为leader,其他为follower。leader处理分区的所有读写请求,其他都是备份。同时,follower会被动的周期性的复制leader上的数据。如果一个flower落后于leader太远,或者在一定时间内没有发起数据复制请求,leader会将其从ISR中移除。当ISR中的所有Replica都向leader发送ACK时,leadercommit。Kafka的ISR的管理最终会反馈给Zookeeper节点。具体位置为:/brokers/topics/[topic]/partitions/[partition]/state。当Leader节点失效时,它也会依赖Zk进行新的Leader选举。在Kafka内部将Offset转移到Topic之后,Kafka对ZK的依赖越来越小。Reliability消息传递语义Atleastonce消息可能会丢失,但不会重复Atmostonce消息不会丢失,但可能会重复,所以消费者必须是幂等的exactlyonce消息不会丢失,只传递一次全局消息传递生产者和消费者都需要保证语义。KAFKA默认是Atmostonce,也可以配置事务实现Exactlyonce,但是效率很低,不推荐。ACK当producer向leader发送数据时,可以通过request.required.acks参数设置数据可靠性级别:1(默认)数据发送给kafka后,leader确认消息成功接收后,传输成功。在这种情况下,如果领导者宕机,数据就会丢失。0生产者不关心发送数据,也不等待任何返回。这种情况下,数据传输效率最高,但数据可靠性确实最低。-1producer需要等待ISR中所有follower确认收到数据才算发送完成,可靠性最高。为什么KAFKA快?CacheFilesystemCachePageCacheCache顺序写入由于现代操作系统提供预读和写入技术,因此在大多数情况下顺序写入磁盘比随机写入内存更快。Zero-copy零拷贝,少一次内存交换。批处理消息批处理。合并小的请求,然后以流的方式交互,达到网络的上限。拉取模式使用拉取模式获取消息并消费,与消费者的处理能力一致。传递业务消息和用户活动日志的使用场景?日志流处理,比如监控项,比如一些聚合的CommitLogs,作为一些重要业务的冗余下面是一个典型的日志使用场景。压力测量KAFKA自带压力测量工具,如下。./kafka-producer-perf-test.sh--topictest001--num-records1000000--record-size1024--throughput-1--producer.config../config/producer.properties配置管理关注点应该不同应用场景有不同的配置策略和不同的SLA服务级别。你需要弄清楚你的消息是否允许丢失或重复,然后设置相应的副本数和ACK模式。滞后留意消息的积压。滞后太高意味着处理能力有问题。如果你的消息在低峰时期积压,那么当高流量来临时,难免会出问题。扩容扩容后会涉及分区重新分配,你的网络带宽可能是瓶颈。磁盘已满。建议设置过期天数,或者设置最大磁盘使用率。log.retention.bytesexpireddelete磁盘空间有限,建议保留最近的记录,其余会自动删除。log.retention.hourslog.retention.minuteslog.retention.ms监控管理工具KafkaManagerYahoo出品,可以管理多个Kafka集群,是目前最全面的管理工具。但是注意,当你的topic太多的时候,监控数据会占用你大量的带宽,导致你的机器负载增加。其监控功能薄弱,不满足需要。KafkaOffsetMonitor程序以jar包的形式运行,更方便部署。只有监控功能,使用更安全。KafkaWebConsole具有完善的监控功能,可以预览消息,监控Offset、Lag等信息。不建议在生产环境中使用。Burrow是LinkedIn开发的用于监控消费者滞后的开源框架。支持告警,只提供HTTP接口,不提供webui。AvailabilityMonitorforKafka微软开源的Kafka可用性和延迟监控框架提供了一个JMX接口,这个接口很少被使用。Rebalance消费者端的上线和下线会导致分区和消费者的关系重新分配,从而产生Rebalance。业务可能会出现超时和抖动。服务器端重新分配服务器的扩缩容、节点的启停都会造成数据倾斜,需要对分区进行重新分配。这个过程可以在Kafkamanager后台手动触发,让分区的分布更加均匀。这个过程会造成集群间大量的数据拷贝。当您的集群数据量很大时,这个过程会持续数小时或数天,请谨慎操作。Linkedin开源了其自动化管理工具cruise-control。需要自动化运维的小伙伴不妨看看。最后,这篇文章是KAFKA相关的最基础的知识,基本上涵盖了大部分简单的面试题。为了实现exactlyonce的语义,Kafka做了很多努力,但是努力的结果是几乎不可用,吞吐量太低。真要谈“高可靠性”,还不如做“补偿策略”。如果性能不好,最终的结果可能是整体不可用;在极端情况下,数据丢失只是小数据的一部分。你会怎么权衡呢?大流量下的KAFKA很吓人,数据经常会把网卡塞满。Broker一旦宕机,如果单个节点在T上有数据,则需要半小时才能启动,同时还要充当follower追赶其他master分区的数据。所以,不要让你的Kafka集群太大,故障恢复将是一场灾难。启动后,如果执行reassign,又是一个折腾。
