写点什么

跟我一起认识 Little’s Law

  • 2019-10-28
  • 本文字数:3899 字

    阅读完需:约 13 分钟

跟我一起认识Little’s Law

1.前言

开发的同学或多或少都会跟“性能”这个玩意打交道,本文将要介绍的 Little’s Law 跟衡量性能的常见指标关系密切,所以在引出今天的主角 Little’s Law 之前,有必要先统一一下我们描述“性能”的“基本语言”,毕竟语言不通是没法交流的不是。另外,以下叙述都是我的个人理解,不当之处请指正。

2.“性能”的“基本语言”

不同的服务设备对性能的定义也不同,例如 CPU 主要看主频,磁盘主要看 IOPS。本文主要针对后端的软件服务性能(比如 api 服务、数据库服务等)展开讨论。限定好范围后就应该给出一个性能的定义了:性能就是服务的处理请求的能力


衡量性能的指标常见的有三个:并发用户数、吞吐量、响应时间。

2.1 并发用户数

指真正对服务发送请求的用户数量,需要注意和在线用户数的区别;


比如,某一时刻,在线用户数为 1000,其中只有 100 个用户的操作触发了与远端服务的交互,那么这时对远端服务来说,并发用户数是 100,而不是 1000。

2.2 吞吐量

单位时间内处理的请求数。

2.3 响应时间

对应的英文是 response time,也有的地方用 latency 表示,即延迟。需要统计一个时间段内的响应时间,求出特征值来表示响应时间。


常见的特征值包括平均值、最大值、最小值、分位值。

3.主角 Little’s Law 登场

3.1 Little’s Law 的定义

稳定的系统中同时被服务的用户数量等于用户到达系统的速度乘以每个用户在系统中驻留的时间,适用于所有需要排队的场景。


对应公式表示为:


N = X * R,其中N 表示系统中同时活动的用户,X 表示用户相继到达系统的速率,在稳定(这个词非常重要!!!)状态(用户到达系统的速度等于用户离开系统的速度)时即为系统吞吐量,R 表示每个用户在系统中平均的驻留时间。
复制代码


比如说,你正在排队进入一个体检中心,你可以通过估计人们进入的速率来知道自己还要等待多长时间。


体检中心能容纳约600人,每个人完成体检的时间是2个小时,即R=2小时,N=600人,根据公式计算:X=N/R=600人/2小时=300人/小时所以以每小时300人的速度进入。如果现在你的前面还有300个人,那么大约还要等上一个小时才会进入体检中心。
复制代码

3.2 Little’s Law 与性能指标的关系

前一部分说的三个指标的关系可以用 Little’s Law 来表示,因为对用户请求不断发送到服务端进行处理的情况来说,就是一种排队的场景,把 Little’s Law 具体到这种场景那么对应的公式为:


并发数=吞吐量*响应时间
复制代码

3.3 通过实例感受 Little’s Law 的存在

下面主要从接口服务和 mysql 服务两个实例来观察 Little’s Law 的存在。

3.3.1 接口服务的实例

3.3.1.1 准备过程介绍
  1. 基于 springboot 暴露一个接口


接口本身会根据参数值休眠一段时间,这样客户端的压测工具就可以控制接口的响应时间了。


@RestControllerpublic class ApiLatency {
@RequestMapping("/test/latency/{ms}") public String latency(@PathVariable long ms) {
try { Thread.sleep(ms); } catch (InterruptedException e) { e.printStackTrace(); }
return "Hello World!"; }}
复制代码


  1. 通过 jmeter 设置不同的并发数对上面的接口进行压测

3.3.1.2 结果展示与分析



初始阶段响应时间基本稳定,吞吐量随着并发数的增加而增加;


随着并发数增加,系统到达“拐点”,吞吐量开始出现下降的趋势,同时响应时间也开始增大;继续增加并发数,系统负载超负荷,从而进入过饱和区,此时响应时间急剧增大,吞吐量急剧下降。在“拐点”之前和刚进入拐点这段区域,此时可以认为系统为“稳定”的,此时并发数、吞吐量、平均响应时间是符合 Little’s Law 公式的。

3.3.2 mysql 服务的实例

3.3.2.1 准备过程介绍
  1. 准备一个腾讯云 mysql 服务(5.6 版本,配置为 2 核 4G)和一台云服务器(腾讯云内网测试)

  2. 用 sysbench(0.5 版本)对 mysql 服务进行测试


## 数据预置sysbench --mysql-host=192.168.0.10 --mysql-port=3306 --mysql-user=root --mysql-password=test --mysql-db=loadtest --mysql-table-engine=innodb --test=/usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua --oltp_tables_count=8 --oltp-table-size=4000000  --rand-init=on prepare
## 执行shell脚本进行测试for i in 5 7 8 10 12 25 50 128 200 400 700 1000dosysbench --mysql-host=192.168.0.10 --mysql-port=3306 --mysql-user=root --mysql-password=test --mysql-db=loadtest --test=/usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua --oltp_tables_count=8 --oltp-table-size=4000000 --num-threads=${i} --oltp-read-only=off --rand-type=special --max-time=180 --max-requests=0 --percentile=99 --oltp-point-selects=4 --report-interval=3 --forced-shutdown=1 run | tee -a sysbench.${i}.oltp.txtdone
## 清理数据sysbench --mysql-host=192.168.0.10 --mysql-port=3306 --mysql-user=root --mysql-password=test --mysql-db=loadtest --mysql-table-engine=innodb --test=/usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua --oltp_tables_count=8 --oltp-table-size=4000000 --rand-init=on cleanup
## 脚本中参数的含义--oltp_tables_count=8,表示本次用于测试的表数量为8张。--oltp-table-size=4000000,表示本次测试使用的表行数均为400万行。--num-threads=n,表示本次测试的客户端连接并发数为n。--oltp-read-only=off ,off 表示测试关闭只读测试模型,采用读写混合模型。--rand-type=special,表示随机模型为特定的。--max-time=180,表示本次测试的执行时间180秒。--max-requests=0,0 表示不限制总请求数,而是按 max-time 来测试。--percentile=99,表示设定采样比例,默认是95%,即丢弃1%的长请求,在剩余的99%里取最大值。--oltp-point-selects=4,表示 oltp 脚本中 sql 测试命令,select 操作次数为4,默认值为1。
复制代码
3.3.2.2 结果展示与分析



初始阶段响应时间基本稳定,吞吐量随着并发数的增加而增加;


随着并发数增加,系统到达“拐点”,吞吐量开始出现下降的趋势,同时响应时间也开始增大;继续增加并发数,系统负载超负荷,从而进入过饱和区,此时响应时间急剧增大,吞吐量急剧下降。在“拐点”之前和刚进入拐点这段区域,此时可以认为系统为“稳定”的,此时并发数、吞吐量、平均响应时间是符合 Little’s Law 公式的。

4.总结

4.1 Little’s Law 公式系统“稳定”时成立


基于前述的两个实测的例子,对于并发数、吞吐量、响应时间三者的关系,我们可以用上图表示。


  • 刚开始为“线性增长区”,此时响应时间基本稳定,吞吐量随着并发用户数的增加而增加;

  • 当系统的资源利用率饱和时,系统到达“拐点”,随着并发用户数增加,吞吐量开始出现下降的趋势,同时响应时间也开始增大;

  • 继续增加并发用户数,系统负载超负荷,从而进入过饱和区,此时响应时间急剧增大,吞吐量急剧下降。


在“拐点”之前和刚进入拐点这段区域,此时可以认为系统为“稳定”的,此时并发数、吞吐量、平均响应时间是符合 Little’s Law 公式的。

4.2 并发数并不是实际用户数


比如你这样设置 jmeter 的线程数为 80,测出的结果并不是说你的服务在 80 个用户使用情况下的性能表现,实际场景中可能 1000 个真实用户产生的压力也没有这里的 80 个线程(或者叫虚拟用户数)产生的压力大。我倾向于把并发数理解为一种压力的度量,80 的并发对服务的压力肯定是大于 60 的并发对服务的压力的。

4.3 低延迟(响应时间)不一定高吞吐,高延迟(响应时间)也不一定低吞吐

  • 假如一个程序只有 1 个线程,这个线程每秒可以处理 10 次事件,那么我们说这个程序处理单次事件的延迟为 100ms,吞吐为 10 次/秒。

  • 假如一个程序有 4 个线程,每个线程每秒可以处理 5 次事件,那么我们说这个程序处理单次事件的延迟为 200ms,吞吐为 20 次/秒。

  • 假如一个程序有 1 个线程,每个线程每秒可以处理 20 次事件,那么我们说这个程序处理单次事件的延迟为 50ms,吞吐为 20 次/秒。


由 Little’s Law 我们知道,并发数=吞吐量*响应时间,所以延迟和吞吐的关系是受并发数影响的,抛开并发数去找另外两者的关系是没有规律的。

4.4 响应时间要和吞吐量挂钩

性能如果只看吞吐量,不看响应时间是没有意义的。从前面的分析我们知道,随着并发数的逐渐增加,吞吐量有一个先上升再下降的过程,也就是存在同一个吞吐量的值,在不同并发下,会对应不同的响应时间。比如某接口吞吐量为 10000TPS,响应时间达到 5 秒,那这个 10000TPS 也没什么意义了。

4.5 响应时间、吞吐量和成功率要挂钩

比如在接口测试中,当并发数达到 4000 时,错误率达到了 40%,那么此时的 1270.8TPS 就没什么意义了。


4.6 又多又快又好

我理解的服务的性能就是又多又快又好的处理请求,“多”就是吞吐量大,“快”就是响应时间短,“好”就是错误率尽量低。

4.7 last but not least

在 Little’s Law 中我们一直用的响应时间是“平均响应时间”,而实际工作中我们通常用响应时间的“分位值”来作为响应时间的统计值来衡量性能的,平均值只是作为一个辅助参考。原因你应该懂得,比如“平均工资”通常没多大参考价值,有可能很多人是被平均的。

5.扩展

Eric Man Wong 于 2004 年发表的《Method for Estimating the Number of Concurrent Users》论文中介绍了一种对系统并发用户数估算的公式:



这个公式和 Little’s Law 是等价的,具体论述过程参考Eric’s并发用户数估算与Little定律的等价性

6.参考


2019-10-28 13:503205

评论

发布
暂无评论
发现更多内容

Java:既然有了synchronized,为什么还要提供Lock

华为云开发者联盟

Java 开发 华为云 企业号十月 PK 榜

Vue模板是怎样编译的

yyds2026

Vue

引擎上新|卡片焕新升级,信息高效呈现

Jianmu

DevOps 持续集成 CI/CD

【文本检测与识别白皮书-3.2】第二节:场景文本识别方法

合合技术团队

人工智能 深度学习 文字识别 OCR 文本识别

云安全系列2:访问安全和身份管理

HummerCloud

云计算 云安全 iam 身份和访问管理 10月月更

彻底搞懂nodejs事件循环

coder2028

node.js

SAP | 功能模块

暮春零贰

SAP 功能块 10月月更

长安链源码分析同步服务器1

小样本学习在文心ERNIE3.0多分类任务应用--提示学习

汀丶人工智能

nlp 文本分类

Vue虚拟dom是如何被创建的

yyds2026

Vue

SAP | 子例程

暮春零贰

SAP 10月月更 子例程

Workflow,要不要了解一下

华为云开发者联盟

人工智能 华为云 企业号十月 PK 榜

Webpack配置实战

Geek_02d948

webpack

原生拖拽太拉跨了,纯JS自己手写一个拖拽效果,纵享丝滑

茶无味的一天

CSS html HTML5, CSS3 拖拉拽 原生js

文读懂NodeJs知识体系和原理浅析

coder2028

node.js

京东云开发者|ElasticSearch降本增效常见的方法

京东科技开发者

elasticsearch ES 降本增效 数据压缩 存储计算分离

Vue组件是怎样挂载的

yyds2026

Vue

【1024程序员节专访】聚焦行业前沿,共话IT发展趋势

博睿数据

程序员 可观测性 智能运维 博睿数据 IT行业

5 why 分析法,一种用于归纳抽象出解决方案的好方法

程序员泥瓦匠

Docker进阶 dockerfile指令构建docker镜像

Python-派大星

10月月更

从 wepy 到 uniapp 变形记

vivo互联网技术

wepy uni-app 前端 编译器

云小课|MRS基础原理之Oozie任务调度

华为云开发者联盟

大数据 华为云 企业号十月 PK 榜

线上数据问题排查案例分享-因为 HMS 和底层 orc 文件中某字段的数据精度不一致造成的数据丢失问题

明哥的IT随笔

hadoop hive DataX

深入nodejs的event-loop

coder2028

node.js

云计算基础:云计算运用越来越广泛,我们应该如何去学习云计算

Python-派大星

10月月更

一文读透react精髓

xiaofeng

React

redux原理是什么

xiaofeng

React

【沙丘大会】九科信息研发中心自动化负责人郑文茂受邀分享央企数字员工实践案例

九科Ninetech

webpack模块化的原理

Geek_02d948

webpack

webpack实战,手写loader和plugin

Geek_02d948

webpack

漏洞评分高达9.8分!Text4Shell 会是下一个 Log4Shell吗?

SEAL安全

安全 log4j 漏洞分析 Log4j2 漏洞 软件供应链安全

跟我一起认识Little’s Law_文化 & 方法_xinnong_InfoQ精选文章