一、客户端与服务端的交互面试
二、频繁网络通讯带来的性能低下问题网络
三、batch机制:多条消息打包成一个batch架构
四、request机制:多个batch打包成一个request并发
“ 这篇文章,给你们聊一个消息中间件相关的技术话题,对于一个优秀的消息中间件而言,客户端与服务端通讯的时候,对于这个网络通讯的机制应该如何设计,才能保证性能最优呢?甚至经过优秀的设计,让性能提高10倍以上。负载均衡
咱们本文就以Kafka为例来给你们分析一下,Kafka在客户端与服务端通讯的时候,底层的一些网络通讯相关的机制如何设计以及如何进行优化的。分布式
假如咱们用kafka做为消息中间件,势必会有客户端做为生产者向他发送消息,这个你们应该均可以理解。微服务
对于Kafka来讲,他自己是支持分布式的消息存储的,什么意思呢?高并发
好比说如今你有一个“Topic”,一个“Topic”你就能够理解为一个消息数据的逻辑上的集合。性能
好比如今你要把全部的订单数据都发送到一个“Topic”里去,那么这个“Topic”就叫作“OrderTopic”,里面都放的是订单数据。学习
接着这个“Topic”的数据可能量很大很大,不可能放在一台机器上吧?
因此呢,咱们就能够分散存储在多台Kafka的机器上,每台机器存储一部分的数据便可。
这就是Kafka的分布式消息存储的机制,每一个Kafka服务端叫作一个Broker,负责管理一台机器上的数据。
一块儿来看看下面的图:
一个“Topic”能够拆分为多个“Partition”,每一个“Partition”存储一部分数据,每一个Partition均可以放在不一样的Kafka Broker机器上,这样就实现了数据分散存储在多台机器上的效果了。
而后客户端在发送消息到Kafka Broker的时候,好比说你限定了“OrderTopic”的订单数据拆分为3个“Partition”,那么3个“Partition”分别放在一个Kafka Broker上,那么也就是要把全部的订单数据分发到三个Kafka Broker上去。
此时就会默认状况下走一个负载均衡的策略,举个例子,假设订单数据一共有3万条,就会给每一个Partition分发1万条订单消息,这样订单数据均匀分散在了3台Broker机器上。
整个过程,以下图所示:
好了,如今问题来了,客户端在发送消息给Kafka Broker的时候,好比说如今要发送一个订单到Kafka上去,此时他是怎么发送过去呢?
是直接一条订单消息就对应一个网络请求,发送到一台Broker上去吗?
若是是这样作的话,那势必会致使频繁的跟一台broker进行网络通讯,频繁的网络通讯,每次都涉及到复杂的网络链接、传输的流程,那么进而会致使客户端性能的低下。
给你们举个例子,好比说每次经过一个网络通讯发送一条订单到broker,须要耗时10ms。
那么若是一个订单就一次网络通讯发送到broker,每秒最多就是发送100个订单了,你们想一想,是否是这个道理?
可是假如说你每秒有10000个订单要发送,此时就会形成你的发送性能远远跟不上你的需求,也就是性能的低下,看起来你的系统发送订单到kafka的速度就是特别的慢。
因此首先针对这个问题,kafka作的第一个优化,就是实现了batch机制。
这个意思就是说,他会在客户端放一个内存缓冲区,每次你写一条订单先放到内存缓冲区里去,而后在内存缓冲区里,会把多个订单给打包起来成为一个batch。
好比说默认kafka规定的batch的大小是16kb,那么意思就是,你默认就是多条订单凑满16kb的大小,就会成为一个batch,而后他就会把这个batch经过网络通讯发送到broker上去。
假如说一个batch发送到broker,一样也是耗费10ms而已,可是一个batch里能够放入100条订单,那么1秒是否是能够发送100个batch?
此时,1秒是否是就能够发送10000条订单出去了?
并且在打包消息造成batch的时候,是有讲究的,你必须是发送到同一个Topic的同一个Partition的消息,才会进入一个batch。
这个batch里就表明要发送到同一个Partition的多条消息,这样后续才能经过一个网络请求,就把这个batch发送到broker,对应写入一个Parititon中。
事情到这里就结束了吗?尚未!
好比如今咱们要是手头有两个Topic,每一个Topic都有3个Partition,那么每一个Broker是否是就会存放2个Partition?其中1个Partition是Topic01的,1个Partition是Topic02的。
如今假如说针对Topic01的Partition02造成了一个batch,针对Topic02的Partition02也造成了一个batch,可是这两个batch其实都是发往同一个Broker的,如上图的第二个Broker。
此时,仍是一个网络请求发送一个batch过去吗?
其实就彻底不必了,彻底此时能够把多个发往同一个Broker的batch打包成一个request,而后一个request经过一次网络通讯发送到 那个Broker上去。
假设一次网络通讯仍是10ms,那么这一次网络通讯就发送了2个batch过去。
经过这种多个batch打包成一个request一次性发往Broker的方式,又进一步提高了网络通讯的效率和性能。
其实 batch机制 + request 机制,都是想办法把不少数据打包起来,而后一次网络通讯尽可能多发送一些数据出去,这样能够提高单位时间内发送数据的数量。
这个单位时间内发送数据的数量,也就是所谓的“吞吐量”,也就是单位时间内能够发送多少数据到broker上去。
好比说每秒钟能够发送3万条消息过去,这就是表明了客户端的“吞吐量”有多大。
所以,经过搞清楚这个原理,就能够学习到这种很是优秀的设计思想。并且在面试的时候,若是跟面试官聊到kafka,也能够跟面试官侃侃kafka底层,是如何有效的提高网络通讯性能的。
最后再来一张图,做为全文总结。
一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,
欢迎关注公众号:石杉的架构笔记
周一至周五早八点半!精品技术文章准时送上!!!
十余年BAT架构经验倾囊相授