此文已由作者张洪箫授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

问题描述

随着考拉业务的增长和规模的扩大,很多的应用都开始重度依赖缓存服务,也就是杭研的nkv。但是在使用过程中,发现服务端压力并不是特别大的情况下,客户端的rt却很高,导致应用在到达一定并发的情况下,服务的质量下降的非常严重,甚至出现不可用的情况。这个在大促阶段尤其严重,所以在杭研性能测试团队(这里特别感谢霞姐和小宝的大力支持)的协助下,在线下进行了压测和问题定位。

问题发现过程

测试使用了dubbo接口调用形式对fee工程进行加压,fee会在被调用后通过nkv客户端访问nkv服务端。

第一阶段

在逐步加压的过程中,发现并发到达150时,rt已经涨到50ms左右,此时使用jstack打印堆栈,发现大量的线程在等待消息的返回。反观此时服务端的情况,基本无压力,故此时定位,瓶颈在客户端。
review客户端代码,客户端调用服务端采用的是netty的异步方式,同步接口会在调用netty发送消息后使用future来获得响应;异步则将future返回给应用,交由应用处理。简单的过了一遍代码,并没有发现什么异常。
因为从哨兵监控上观察应用并没有异常,只是上下文切换的次数稍多,差不多有8w左右,怀疑有可能是因为线程数过多导致上下文切换过于频繁导致,所以将dubbo的线程数从400降低到了200,再次压测,发现在同等并发数下,rt比之前低,在40ms左右。
因为40ms并不能满足要求,而且不过压测机的并发数提高多少,qps最高只能在1500-1700左右徘徊,无法继续加压,所以只能继续找问题。

第二阶段

在之后的阶段卡了很久。后来观察到qps不高,load却比较高,邵峰提出是否是netty的一个bug,即在并发不高的情况下,占用大量的cpu,导致响应较慢,尝试把netty的更换到一个较高的版本,再次尝试,问题依然。

第三阶段

百思不得其解的时候,霞姐偶然在监控堆栈的地方看到有几率出现在一个锁的地方停留,然后回过头仔细看了下那段代码,终于发现了问题。
nkv在调用netty发送消息前会做这两个操作,第一个是将channal和seq的信息放到一个DelayQueue中,然后再将seq和channal的对应放到一个ConcurrentHashMap里

然后再收到响应后,从DelayQueue中删除收到消息对应的信息,再根据seq找到channal,然后唤醒等待的线程。

DelayQueue在这里主要是为了防止在某些异常情况下,导致channal未释放,会有另一个线程定时扫描DelayQueue清除超时对象。
但是在大并发下,由于DelayQueue的删除是上锁后遍历整个列表的,所以收到响应后的清除操作,会将网络回调线程和业务的发送线程阻塞,虽然很快就收到服务端的响应,但是回调线程却无法回调,所以导致整体响应非常慢。

第四阶段

找到原因后,解决方案的选择就比较多,后来选择的方案是将DelayQueue去掉,在调用发送后,将获取future的结果的操作放入try-finally中,释放chnnal的操作放在finally,则同步操作时释放肯定会被执行。异步操作则是在网络线程的回调后清除channal。
修改完成后,再次压测,再qps接近3倍的情况下,平均rt降低到原来的1/4,基本满足了本次调优的目标。

第五阶段

调优是没有止境的,所以再过了一遍代码,发现在调用netty发送后,客户端调用了await来等待网络的回调,

但是因为nkv的rt正常情况下非常低,很多操作都是毫秒内的,但是await的单位是毫秒,这样很有可能导致有些情况下本来需要1.1.毫秒的操作,却变成了2ms。
所以就将await改成了awaitNanos,纳秒级等待。
修改后测试,在使用batch操作时,平均rt降低1.6ms,可能有些人觉得才1.6ms,差别不大,但是在99%响应在10ms内的缓存服务中,降低1.6毫秒的影响已经很大了。

总结

  • 需要好的工具,像霞姐他们的性能测试工具,这样事半功倍

  • 往往优化的点就是备忽略的点,还是得自己review

  • 优化无止境,小的点也会有很大的影响

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 限时购校验小工具&dubbo异步调用实现限
【推荐】 一个体验好的Windows 任务栏缩略图开发心得

nkv客户端性能调优的更多相关文章

  1. web前端性能调优

    最近2个月一直在做手机端和电视端开发,开发的过程遇到过各种坑.弄到快元旦了,终于把上线了.2个月干下来满满的的辛苦,没有那么忙了自己准备把前端的性能调优总结以下,以方便以后自己再次使用到的时候得于得心 ...

  2. [网站性能2]Asp.net平台下网站性能调优的实战方案

    文章来源:http://www.cnblogs.com/dingjie08/archive/2009/11/10/1599929.html 前言    最近帮朋友运营的平台进行了性能调优,效果还不错, ...

  3. Asp.net平台下网站性能调优的实战方案(转)

    转载地址:http://www.cnblogs.com/chenkai/archive/2009/11/07/1597795.html 前言 最近帮朋友运营的平台进行了性能调优,效果还不错,所以写出来 ...

  4. JVM内存模型与性能调优

    堆内存(Heap) 堆是由Java虚拟机(JVM,下文提到的JVM特指Sun hotspot JVM)用来存放Java类.对象和静态成员的内存空间,Java程序中创建的所有对象都在堆中分配空间,堆只用 ...

  5. iOS-------应用性能调优的25个建议和技巧

    性能对 iOS 应用的开发尤其重要,如果你的应用失去反应或者很慢,失望的用户会把他们的失望写满App Store的评论.然而由于iOS设备的限制,有时搞好性能是一件难事.开发过程中你会有很多需要注意的 ...

  6. iOS应用性能调优建议

    本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelofabri.com/,你还可以 ...

  7. iOS应用性能调优的25个建议和技巧

    本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelofabri.com/,你还可以 ...

  8. Advacned Puppet: Puppet Master性能调优

    本文是Advanced Puppet系列的第一篇:Puppet master性能调优,谈一谈如何优化和提高C/S架构下master端的性能. 故事情节往往惊人地类似:你是一名使用Puppet管理线上业 ...

  9. 性能调优:理解Set Statistics Time输出

    在性能调优:理解Set Statistics IO输出我们讨论了Set Statistics IO,还有如何帮助我们进行性能调优.这篇文章会讨论下Set Statistics Time,它会告诉我们执 ...

随机推荐

  1. HDU 1255 覆盖的面积 (线段树扫描线+面积交)

    自己YY了一个的写法,不过时间复杂度太高了,网上的想法太6了  题意:给你一些矩阵,求出矩阵的面积并 首先按照x轴离散化线段到线段树上(因为是找连续区间,所以段建树更加好做). 然后我们可以想一下怎样 ...

  2. 大话设计模式--观察者模式 Observer -- C++ 实现实例

    大话设计模式--1.观察者模式: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有的 观察者对象,使他们能够自动更新自己. 使用场合: 当一 ...

  3. webserver的编写中出现的问题

    在webserver编写过程中,出现过问题.就是标签<input>编写过程中少了name属性,导致程序无法读到<form>提交的数据.

  4. java: jdk1.8以后就不支持桥接的方式

    java: jdk1.8以后就不支持桥接的方式 如果想继续使用桥接的方式,请使用jdk1.7及以下版本.

  5. java:Map借口及其子类HashMap四

    java:Map借口及其子类HashMap四 使用非系统对象作为key,使用匿名对象获取数据 在Map中可以使用匿名对象找到一个key对应的value. person: public class Ha ...

  6. 关于VS中包含库、附加包含库、

    转载:https://blog.csdn.net/qing101hua/article/details/53841827 VS中C++的包含目录.附加包含目录和库目录和附加库目录的区别 对Visual ...

  7. 利用perlin noise 生成 wood texture

    %%% Perlin Noise %%% Wood_texture clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image P ...

  8. 判断CPU是大端还是小端

    #include "stdafx.h" #include <iostream> using namespace std; /* #大端模式(Big_endian):字数 ...

  9. ACdream1430SETI(后缀自动机)

    问题: Amateur astronomers Tom and Bob try to find radio broadcasts of extraterrestrial civilizations i ...

  10. 基于C#的数据库文件管理助手2018-09-02

    数据库文件管理助手说明 目录 一. 数据库的文件导出2 1. web格式 2 2. winform格式 5 3. 二进制格式 5 二. 文件批量工具8 1. 文件批量改名GUID 8 2. 文件批量下 ...