当前位置: 首页 > 科技观察

卡夫卡老少皆宜的长文,让你明白什么是本分

时间:2023-03-17 16:04:41 科技观察

转载本文请联系味觉小姐姐公众号。看完这篇文章,你就会明白为什么一个简单的消息队列可以有这么多的知识点;了解Kafka的主要功能和应用场景;您可以了解Kafka的主要技术术语。明白什么是义务!Kafka作为一个分布式消息系统,必须要有职责的思想。它需要弄清楚自己的定位,明白它为谁创造了什么样的价值,它赖以生存的人,它的职责是什么。很少有系统能在如此压抑的一连串问题下保持冷静,但卡夫卡顶住了,它是一个真正的勇士。Kafka的职责核心是作为消息队列使用。那么什么是消息队列呢?如果你看不懂这道题,证明卡夫卡的思想觉悟不是很高,还需要继续思考和研究。为了弄清这个问题,我们采访了一位送奶工。1、送奶工的故事牛奶美味又营养,无论是奶瓶里挤出来的鲜奶还是合成奶,都让社区里很多人点了。每天早上,送奶工拉着一车牛奶开始送牛奶。一开始,他按照书上的门牌号,逐户敲门,然后把牛奶塞到顾客手里。有时,客户不在家,他只好翻通讯录找客户电话联系。但过了一段时间,随着生意越做越大,送奶工对这份工作的评价只有一句话:*请客,吃力不讨好。有的顾客睡眼惺忪地开门,抱怨他打扰了他们的生活;牛奶是最后送的,我就跟他抱怨送的不及时。幸运的是,送奶工曾经是一名程序员。想了想,他说服了老板:给每位顾客配备一个牛奶盒。他的工作是定期将新鲜牛奶放入盒子中。他不管顾客什么时候拿,拿完洗脸搓手。从此以后,他再也没见过睡衣下若隐若现的身躯。我们注意到在上面的场景中,有两个主要参与者:送牛奶的人和顾客。在加入牛奶箱之前,他们之间的交互是阻塞的,信息处理效率低下,并且存在严重的耦合问题,以至于送奶工看到了他不该看的东西。当然,添加奶盒后,交互逻辑发生了变化,需要适配;而且,牛奶盒是有成本的。如果业务量不是很大,加这个东西会增加成本。我们来看一下:上面的牛奶盒子就是消息系统。每个牛奶盒都是一个消息队列。送奶工是生产者;客户是消费者;牛奶是新闻。客户还没有取走牛奶,这意味着有消息积压。客户发消息给你确认收到奶,就是ACK...2.最简单的通用消息系统消息系统!就是提供一个中间层。生产者只需要将消息提交到特定的中间层,而消费者只需要从中间层获取信息就足够了。因此,它最简单的表现形式就是数据库。上图是一些小系统的典型架构。考虑到一个订单的业务场景,有大量的请求指向我们的业务系统。如果我们通过复杂的业务逻辑直接进入业务表,会导致大量请求超时失败。所以我们添加了一个中间缓冲表来接受用户请求。然后就是定时任务,不断从缓冲表中获取数据,进行真正复杂的业务逻辑处理。别怀疑,这其实是最简单的消息系统,但是它却存在着很多问题。定时任务的轮询间隔不易控制。业务处理容易出现延误。处理能力无法横向扩展,会引入分布式锁、顺序保证等问题。当其他业务也需要这些订单数据时,必须将业务逻辑添加到定时任务中。当访问量越来越大,业务逻辑越来越复杂时,更高层次的消息模型呼之欲出。3.消息系统的基本需求我们对消息系统的主要需求是:高性能,包括消息传递和消息消费,必须是快速的。通常,并行处理能力是通过增加分片数量来获得的。数据库显然是一个瓶颈。消息必须可靠在某些场景下,消息不能丢失。生产端、消费端、MQ端都不能丢消息。一般可以通过加副本和强制刷盘的方式解决。数据库显然也是有master备份的。可扩展性更好。它可以陪你把项目做大,陪你到时间的尽头。添加节点后,集群不会降低性能。数据库的扩展性肯定值得怀疑,你可能会引入一些复杂的分库分表组件。生态成熟度监控、运维、多语言支持、社区活跃。这就决定了你使用的消息队列值不值得你信任。更甚者,xjjdog还有另一篇文章对其进行了说明:分布式消息系统,设计要点。画龙画虎难。画骨骼要求那么多,模型却这么简单。困难在哪里?为什么有的同学看到卡夫卡就头疼?4.完成你的任务有多难?就是一个简单的生产者消费者模型,为什么现在的消息系统这么复杂呢?其实它的复杂性主要体现在分布式这三个词上,跟消息队列关系不大。它需要处理所有分布式系统都面临的一些问题。4.1副本单机上的任何数据都是不可信任的,因为会损坏硬盘,断电,挖光缆。因此,数据安全一般都是通过冗余的多副本来保证的。副本的另一个作用是提供额外的计算能力,比如一些请求,会落在副本上。副本越多,可用性越高。添加副本后,涉及到数据同步。即使是最快的LAN也有延迟,更不用说机器性能差异造成的同步延迟了。这里有一个问题。只读副本的请求读取的数据可能不是最新的,这意味着数据的一致性发生了变化。当然,有一些手段可以保证数据的一致性,但是副本越多,延迟就越大。副本的加入也引入了主从问题。master节点挂掉后,必须有replica节点接手。这个过程的协调需要时间,其中一些是不可用的。所有的消息系统都需要大量的代码来处理这些异常。4.2分区当一类数据足够大时(比如某张表),对它的操作已经很耗时了,就需要对这类数据进行切分,分布到多台机器上。这个切分过程就是分片,通过一定的分片规则,减小单个查询数据的大小,增加集群容量。一个shard的数据,只能有一个写的地方,就是master,其他的copy都是从master上拷贝数据。副本可以增加读操作的并行度,但是会读到脏数据。如果要读取的数据是一致的,可以使用同步写副本的方式,比如KAFKA的ack=-1。只有全部同步成功,才能认为提交成功。但是如果你有太多的副本,这个过程会很慢。您可能希望通过分配写入和读取的份数来协调写入和读取的效率。Quorum的R+W>N是一个trade-off的策略。5.Kafka名词解释我们依次来看一下Kafka的名词定义,就简单多了。Kafka是一个分布式消息(存储)系统。分布式系统通过碎片增加并行性;通过副本增加可靠性,Kafka也不例外。它的结构逃脱不了我们上面介绍的基本分布式理论。如果把replica、partition、topicchannel、producer、consumer这些名词放在一起,图会变得很大。你在一台机器上安装了Kafka,那么这台机器就叫做Broker,KAFKA集群中包含一个或多个这样的实例。它只是一个名称,没有任何具体含义。负责向KAFKA写入数据的组件称为Producer,消息的生产者一般写在业务系统中。而我们的送奶工是一个维度。发送给KAFKA的消息可能有很多种。如何区分它们的类别?就是Topic的概念。一个topic被分发后,可能存在于多个Broker上。将Topic拆分成多个段,提高并行度。每个部分称为一个Partition,分区一般均匀分布在所有机器上。那些在Kafka中消费数据的应用程序称为消费者。我们给某个topic的某个consumer业务起个名字,所以这个名字就叫ConsumerGroup。查看KafkaServer的配置文件。最重要的两个参数:partitions和replication.factor其实很好理解。先说最重要的概念。Kafka通过ISR解决了replicas之间的同步问题,这是面试Kafka的必考点之一。ISR的全称是“In-SyncReplicas”,是保证HA和一致性的重要机制。副本数对Kafka的吞吐量有一定的影响,但是大大增强了可用性。一般2-3个为宜。副本有两个要素,一是数量要足够,二是不要落在同一个实例上。ISR是针对Partition的,每个partition都有一个同步列表。N个副本中,其中一个副本为leader,其他为follower。leader处理分区的所有读写请求,其他都是备份。同时,follower会被动的周期性的复制leader上的数据。如果花落后于领导者太远,或者超过一定时间没有发起数据复制请求,领导者将其从ISR中删除。当ISR中的所有Replica都向leader发送ACK时,leadercommit。6、消息系统的作用说了这么多,是时候用计算机术语解释一下消息队列的作用了:削峰是用来接受超过业务系统处理能力的请求,使业务运行顺利。这样可以节省很多成本。例如,某些限时抢购活动并非针对高峰容量而设计。Buffering作为缓冲层存在于服务层和慢速登陆层,作用类似于调峰,但主要用于服务内部的数据流转。比如群发短信。解耦在项目开始时,无法确定具体的需求。消息队列可以作为接口层来解耦重要的业务流程。您只需要遵守数据的协议和程序,就可以获得可扩展性。冗余的消息数据可以被多个不相关的服务以一对多的方式使用。健壮性消息队列可以积累请求,所以即使消费端业务短时间挂掉,也不会影响主业务的正常进行。不过,由于卡夫卡是个优秀的人,所以很内向,能做的事情也比较多。它的范围更广,包括但不限于:业务消息的传递用户活动日志监控项和其他日志流处理,比如一些聚合的CommitLogs,作为一些重要业务的冗余EventSources,实践可追溯性,在DDD中如下日志记录的典型使用场景。7、KAFKA为什么快?一般使用Kafka是看中了它的速度。曾几何时,人们认为它只能处理一些日志消息。事实上,Kafka甚至支持最复杂的事务性消息,这与其速度相形见绌。那么,为什么这么快?归纳起来有以下几个原因:CacheFilesystemCachePageCacheCachesequentialwrite由于现代操作系统提供了预读和写技术,所以顺序磁盘写在大多数情况下比随机写内存更快Fastzero-copy零拷贝,少一个内存exchangeBatching消息批处理。合并小的请求,然后以流的方式交互,达到网络的上限。拉取模式使用拉取模式来获取和消费消息,与消费者的处理能力是一致的。主要是这5点。至于压缩,JVM性能优化等等,对,都是小儿科,不能摆在台面上。从End可以看出,Kafka是一个全能选手,既能处理消息,又能存储数据。它的工作没有抱怨或遗憾。虽然效率极高,但必须不停地工作,体现了工人最悲惨的命运。它的分布式系统设计也很好。这是它的设计者为它量身定做的系统:如果一个Kafka节点宕机,就会有更多的Kafka节点上来。痛苦,然后你就可以完全忘记它的牺牲了。Kafka是一个专用的分布式消息系统,但不要无限压抑它。只给它分配了1核cpu和512M内存。这是在艰苦的环境中磨练出不屈不挠的意志啊!如果丢了数据骂TA不稳定,良心不会痛吗?作者简介:小姐姐品味(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。