博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
性能测试工具的 Coordinated Omission 问题
阅读量:6229 次
发布时间:2019-06-21

本文共 2365 字,大约阅读时间需要 7 分钟。

作者:唐刘

很早之前就看过 Gil 大神的一篇文章,里面提到了性能测试工具 coordinated omission 的问题,但当时并没有怎么在意。这几天有人在我们自己的性能测试工具 ()上面问了这个问题,我才陡然发现,原来我们也有。

什么是 coordinated omission

首先来说说什么是 coordinated omission。对于绝大多数 benchmark 工具来说,通常都是这样的模型——启动多个线程,每个线程依次的发送 request,接受 response,然后继续下一次的发送。我们记录的 latency 通常就是 response time - request time。这个看起来很 make sense,但实际是有问题的。

一个简单的例子,当我们去 KFC 买炸鸡,然后我们排在了一个队伍后面,前面有 3 个人,开始 2 个人都好快,30 秒搞定,然后第三个墨迹了半天,花了 5 分钟,然后到我了,30 秒搞定。对于我来说,我绝对不会认为我的 latency 是 30 秒,而是会算上排队的时间 2 x 30 + 300,加上服务时间 30 秒,所以我的总的时间耗时是 390 秒。这里不知道大家看到了区别了没有,就是市面上大多数的性能测试工具,其实用的是服务时间,但并没有算上等待时间。

再来看一个例子,假设我们需要性能测试工具按照 10 ops/sec 的频繁发送请求,也就是希望每 100 ms 发送一个。前面 9 个请求,每个都是 50 us 就返回了,但第 10 个请求持续了 1 s,而后面的又是 50 us。可以明显地看到,在 1 s 那里,系统出现了卡顿,但这时候其实只有 1 个请求发上去,并没有很好地对系统进行测试。

YCSB

对于第一个排队的例子,为了更好的计算 latency,YCSB 引入了一个 intended time 的概念,即记录下操作实际的排队时间。它使用了一个 local thread 变量,在 throttle 的时候,记录:

private void throttleNanos(long startTimeNanos) { //throttle the operations if (_targetOpsPerMs > 0)    { // delay until next tick long deadline = startTimeNanos + _opsdone*_targetOpsTickNs;        sleepUntil(deadline);        _measurements.setIntendedStartTimeNs(deadline);    }}复制代码

然后每次操作的时候,使用 intended time 计算排队时间:

public Status read(String table, String key, Set
fields, Map
result) { try (final TraceScope span = tracer.newScope(scopeStringRead)) { long ist = measurements.getIntendedtartTimeNs(); long st = System.nanoTime(); Status res = db.read(table, key, fields, result); long en = System.nanoTime(); measure("READ", res, ist, st, en); measurements.reportStatus("READ", res); return res; }}复制代码

需要注意,只有 YCSB 开启了 target,intended time 才有作用。

我当初在看 YCSB 代码的时候,一直没搞明白为什么会有两种时间,而且也不知道 intended time 到底是什么,后来重新回顾了 coordinated omission 才清楚。也就是说 YCSB 通过 intended time 来计算排队时间。

但 YCSB 还是没解决上面说的第二个问题,如果系统真的出现了卡主,测试客户端仍然会跟着卡主,因为是同步发送请求的。在网上搜索了一下,看到了一篇 Paper,里面提到了将同步改成异步的方式,也就是说,每次的任务是一个 Future,首先根据 target 按照频率发 Future 就行,至于这个 Future 什么时候完成,后面再说。而且因为是异步的,所以并不会卡主后面的请求。

Go YCSB

那么具体到 go-ycsb,我们如何解决这个问题呢?我现在唯一能想到的就是利用 Go 的 goroutine,按照一定的频率去生成 goroutine,执行测试。当然 Go 自身也会有调度的开销,这里也需要排除。如果要测试的服务出现了卡顿,就会导致大量的 goroutine 没法释放,最终 OOM。虽然这样子看起来比较残暴,但这才是符合预期的。

这个只是一个想法,具体还没做。一个原因是不同于其他语言,Go 的 goroutine 其实天生就能开很多,所以通常我都是上千并发进行测试的,假设我们有 1000 个并发,按照 1 ms 一次的频率,其实也就等同于每个 goroutine 依次发送了。当然,有总比没有好,如果你对这块感兴趣,欢迎给我们提交 PR,或者给我发邮件详细讨论 tl@pingcap.com。

原文:

转载地址:http://wjxna.baihongyu.com/

你可能感兴趣的文章
html弄多个按钮_HTML表单上的多个提交按钮 - 将一个按钮指定为默认按钮
查看>>
django判断checkbox是否选中_django视图层之请求与响应
查看>>
group by 怎么用java对象接收_生产服务宕机,线上业务挂了!Promtheus 怎么又不报警了呢?...
查看>>
himawari-8卫星叶绿素a产品、_走过50年,看“风云”眼中的世界| 卫星看中国特别版...
查看>>
mybatis使用$报空指针_打破你的认知!Java空指针居然还能这样玩,90%人不知道…...
查看>>
windows mysql 重置root密码_在Windows下Mysql如何重置root用户密码
查看>>
mysql5.6 linux下载_mysql-5.6.45-linux-glibc2.12-x86_64.tar.gz下载安装
查看>>
r语言操作mysql_R语言 RMySQL连接操作mysql数据库
查看>>
mysql 整形相除_整型相除截断的技巧
查看>>
mysql备份字符集_浅谈MySQL备份字符集的问题
查看>>
dos下设置mysql密码_dos命令下修改mysql密码的方法
查看>>
交换机如何设置我能访问它但他不能访问我_“交换机”有什么作用?怎样使用?...
查看>>
数据结构基本操作_R中的数据结构简介及类别变量的基本操作
查看>>
微分方程解法总结_视频教学:线性微分方程解的结构、问题类型及求解思路与方法...
查看>>
blt功能_bitblt()用法
查看>>
MySQL中level的用法_leveldb使用 (转载)
查看>>
卷积神经网络由谁提出_科研人员提出一种基于卷积循环神经网络的单通道渐进语音增强方法...
查看>>
python 曲线拟合求参数_Python:查找任意曲线的拟合参数数量
查看>>
python批量生成图片_python日常实用技能:如何利用Python批量生成任意尺寸的图片...
查看>>
python爱好者社区公众号历史文章合集_GitHub - thinkingpy/weixin_crawler: 高效微信公众号历史文章和阅读数据爬虫powered by scrapy...
查看>>