写点什么

跟我一起认识 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:502597

评论

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

这次我让你彻底弄懂 RESTful

yes

RESTful

前端: 如何快速将应用封装成js-sdk?

徐小夕

Java 大前端

Spring 源码学习 03:创建 IoC 容器的几种方式

程序员小航

spring 源码 ioc 源码阅读

写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理

楼下小黑哥

spring 重构

LeetCode题解:455. 分发饼干,贪心for循环,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

【Linux开发】编写属于你的第一个Linux内核模块

程序员小灰

c++ Linux 后台开发 架构师 服务器开发

面试官问我:Object o = new Object() 占用了多少个字节?

moon聊技术

JVM Java虚拟机 JVM虚拟机原理

写在日更之前,持续书写,见证文字的力量

boshi

随笔 随笔杂谈

架构师训练营W07作业

Geek_f06ede

甲方日常 60

句子

工作 随笔杂谈 日常

每一位程序员都应该保存的计算机网络总结,哪怕你刚进大学

996小迁

Java 架构 面试

极客大学 - 架构师训练营 第十一周作业

9527

30分钟玩转「正则表达式」

Yano

正则表达式

《机器学习》By:周志华,PDF免费下载

计算机与AI

学习

《华为数据之道》读书笔记:第 9 章 打造“安全合规”的数据可控共享能力

方志

大数据 数据中台 数据安全

基于区块链的区域股权市场创新试点

CECBC

区块链

AWS IoT Greengrass设计解析

soolaugust

边缘计算 工业4.0 工业物联网 iiot

区块链数字物流应用落地解决方案

t13823115967

区块链落地 区块链+ 数字物流应用落地解决方案

Jenkins使用ansible时出现!unreachable错误

Griffenliu

线程池ForkJoinPool简介

Java老k

Java 线程池 forkjoin

聊聊OpenAPI Specification(OAS)

尤利西斯的微笑

全栈工程师 软件设计 swagger OpenAPI

金融科技带来套利?专家认为监管应关注平台垄断、权力滥用等问题

CECBC

金融科技

云上看警博会黑科技,得益于华为云打造的“云之盾”

脑极体

学Linux到底学什么?未来职业到底是怎么样的?

Linux服务器开发

Linux 后端 Linux服务器 底层应用开发 web服务器

一文带你彻底了解Java异步编程

Java老k

Java 响应式编程 reactor 异步编程

盖洛普

成周

架构师训练营 - 第 11 周课后作业(1 期)

Pudding

划重点!DWS开发的五大要点

华为云开发者联盟

数据库 sql DWS

区块链系统面临哪些风险以及有哪些防范措施

CECBC

区块链

万字长文深度剖析面向对象的javascript

程序那些事

Java nodejs 程序那些事 面向对象js

年轻人不讲武德,竟然重构出这么优雅后台 API 接口

楼下小黑哥

重构 Spring MVC

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