背景html
国内某大型税务系统,业务应用分布式上云改造。服务器
业务难题网络
如上图所示是模拟客户的业务网页构建的一个并发访问模型。用户在页面点击从而产生一个HTTP请求,这个请求发送到业务生产进程,就会启动一个投递线程(Deliver Thread)调用Kafka的SDK接口,并发送3条消息到DMS(分布式消息服务),每条消息大小3k,须要等待3条消息都被处理完成后才会返回请求响应⑧。当消息达到DMS后,业务消费进程调用Kafka的消费接口把消息取出来,而后将每条消息放到一个响应线程(Response Thread)中进行处理,响应线程处理完后,经过HTTP请求通知投递线程,投递线程收到响应后返回回复响应。架构
100并发访问时延500ms,未达成用户业务要求并发
客户提出了明确的要求:每1个两核的ECS要可以支撑并发访问量100,每条消息端到端的时延范围是几十毫秒,即从生产者发送开始到接收到消费者响应的时间。客户实测在使用了DMS的Kafka 队列后,并发访问量为100时时延高达到500ms左右,甚至出现达到秒级的时延,远未达到客户提出的业务诉求。相比较而言,客户在Pod区使用的是本身搭建的原生Kafka,在并发访问量为100时测试到的时延大约只有10~20ms左右。那么问题来了,在并发访问量相同的条件下,DMS的Kafka队列与Pod区自建的原生Kafka相比为何时延会有这么大的差别呢?咱们DMS的架构师 Mr. Peng对这个时延难题进行了一系列分析后完美解决了这个客户难题,下面就让咱们来看看他的心路历程。异步
难题剖析分布式
根据模拟的客户业务模型,Mr. Peng在华为云类生产环境上也构造了一个测试程序,一样模拟构造了100的并发访问量,经过测试发现,类生产环境上压测获得的时延平均时间在60ms左右。类生产上的时延数值跟客户在真实生产环境上测到的时延差距这么大,这是怎么回事呢?问题变得扑朔迷离起来。性能
Mr. Peng当机立断,决定就在华为云现网上运行构造的测试程序,来看看究竟是什么缘由。同时,在客户的ECS服务器上,也部署了相同的测试程序,模拟构建了100的并发量,获得以下的时延结果对比表:测试
调优前时延优化 |
现网时延(ms) |
类生产时延(ms) |
100并发 |
500ms ~ 4000ms |
40ms ~ 80 ms |
1并发 |
31ms |
6ms |
Ping测试 |
0.9ms ~ 1.2ms |
0.3ms ~ 0.4ms |
表1 华为云现网与类生产环境时延对比表
从时延对比表的结果看来,Mr. Peng发现,即便在相同的并发压力下,华为云现网的时延比类生产差不少。Mr. Peng意识到,如今有2个问题须要分析:为何华为云现网的时延会比类生产差?DMS的Kafka队列时延比原生自建的Kafka队列时延表现差的问题怎么解决?Mr. Peng进行了以下分析:
时延分析
回归问题的本质,DMS Kafka队列的时延究竟是怎么产生的?可控的端到端时延具体分为哪些?Mr. Peng给出了以下的计算公式:
总时延 = 入队时延 + 发送时延 + 写入时延 + 复制时延 + 拉取时延
让咱们来依次了解一下,公式中的每一项都是指什么。
入队时延: 消息进入Kafka sdk后,先进入到要发送分区的队列,完成消息打包后再发送,这一过程所用的时间。
发送时延:消息从生产者发送到服务端的时间。
写入时延:消息写入到Kafka Leader的时间。
复制时延:消费者只能够消费到高水位如下的消息(即被多个副本都保存的消息),因此消息从写入到Kafka Leader,到全部副本都写入该消息直到上涨至高水位这段时间就是消息复制的时延。
拉取时延:消费者采用pull模式拉取数据,拉取过程所用的时间。
(1) 入队时延
现网是哪一部分的时延最大呢?经过咱们的程序能够看到,入队列等待发送时延很是大,以下图:
即消息都等待在生产端的队列中,来不及发送!
咱们再看其余时延分析,由于没法在现网测试,咱们分别在类生产测试了相同压力的,测试其余各类时延以下:
(2) 复制时延
如下是类生产环境测试的1并发下的
从日志上看,复制时延包括在remoteTime里面,固然这个时间也会包括生产者写入时延比较慢致使的,可是也从必定的程度反映复制时延也是提高性能时延的一个因素。
(3) 写入时延
由于用户使用的是高吞吐队列,写入都是异步落盘,咱们从日志看到写入时延很是低(localTime),能够判断不是瓶颈
发送时延与拉取时延都是跟网络传输有关系,这个优化主要是经过调TCP的参数来决定的。轻轻松松把Kafka消息时延秒降10倍,就用华为云DMS!