性能文章>系统性能优化,必知的一些延时数据(CPU仅1s,磁盘1个月,TCP包重传100年)>

系统性能优化,必知的一些延时数据(CPU仅1s,磁盘1个月,TCP包重传100年)原创

3970111

Google AppEngine Numbers

以下这组数字,来自于Brett Slatkin在2008年谷歌I/O大会的演讲《Building Scalable Web Applications with Google App Engine》。
英文原文:
http://highscalability.com/blog/2009/2/18/numbers-everyone-should-know.html
演讲视频和PPT:
https://sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine

写操作是昂贵的

  • 数据存储是事务性的:写操作需要进行磁盘访问;
  • 磁盘访问,意味着需要进行磁盘寻道;
  • 经验法则:一次磁盘寻道需要10ms;
  • 简单的数学计算:1s / 10ms = 100次寻道/s(最大值);
  • 影响因素包括:
    • 数据的大小和形式(数据实体有多少个属性,属性的大小,是否为索引属性等);
    • 分批进行处理(批量写入和读取)。

读操作是廉价的

  • 读操作要保证一致性,但不需要具备事务性;
  • 一旦从磁盘读取了数据,就可以很容易的将它缓存起来;
  • 而后续的所有读取操作,可以直接从内存中读取;
  • 经验法则:从内存中读取1MB数据需要250us(微秒);
  • 简单的数学计算:1s / 250us = 4000MB/s = 4GB/s(最大值);
    • 对于1MB的实体数据,1s可以读取4000次。

数字杂项

以下这组数字,来自于Jeff Dean在Google的Engineering All-Hands Meeting上的演讲。
  • 访问L1缓存:0.5ns;
  • 分支预测失败:5ns;
  • 访问L2缓存:7ns;
  • 对互斥量(Mutex)的加锁/解锁操作:100ns;
  • 访问主存:100ns;
  • 使用Zippy压缩1KB数据:10,000ns = 10us;
  • 通过1Gbps的网络发送2KB数据:20,000ns = 20us = 0.02ms;
  • 从内存中顺序读取1MB数据:250,000ns = 250us = 0.25ms;
  • 同一个数据中心的RTT(往返时间):500,000ns = 500us = 0.5ms;
  • 磁盘寻道:10,000,000ns = 10ms;
  • 从网络中顺序读取1MB数据:10,000,000ns = 10ms;
  • 从磁盘中顺序读取1MB数据:30,000,000ns = 30ms;
  • 发送一个包,从加拿大到荷兰的RTT:150,000,000ns = 150ms;

经验教训

  • 写操作的成本,是读操作的40倍;
  • 全局共享数据非常昂贵。这是分布式系统的基本限制。对共享对象的大量写操作产生的锁竞争,会由于事务的串行化和缓慢而导致性能下降。
  • 支持可扩展写的架构;
  • 尽可能消除写入的竞争;
  • 尽可能让写操作并行化。

时间

响应时间

一次操作完成的时间。包括用于等待和服务的时间,也包括用来返回结果的时间。
也就是说,响应时间包括了(操作前等待的)延时和操作时间(执行指定操作所花费的时间)。
例如执行一个网络请求。需要先等待网络连接的建立,这个是请求的延时。然后执行实际的请求操作,这个就是操作时间。

延时

延时,是指操作中用来等待服务的时间,即操作执行之前所要的等待时间。在某些情况下,它可以指整个操作时间,等同于响应时间。
延时可以在不同的点进行测量,我们通常要指明延时测试的对象。
例如加载一个网页,从三个不同点测得的时间如下:
  • DNS延时。指整个DNS操作的时间;
  • TCP连接延时。指连接的初始化,即TCP三次握手;
  • TCP数据传输时间。

时间单位

时间的量级和缩写如下表所示:
(《性能之颠》)

系统的各种延时

系统各组件的操作所处的时间量级差别巨大,大到了难以体会的地步。
下表提供的延时示例,从访问3.3GHz的CPU寄存器的延时开始,阐释了我们所打交道的时间量级的差别。
表中是发生单次操作的时间均值,为了能有更为直观的感受,进行如下等比放大:
一次寄存器访问时间0.3ns(十亿分之一秒的三分之一),(放大后)相当于现实生活中的1秒。
注意观察相对时间比例这一列,体会一下各组件之间延时的巨大差异。
(《性能之颠》)

磁盘IO延时

磁盘I/O的时间尺度千差万别,从几十微秒到数千毫秒。
下表列出了磁盘I/O延时时间可能出现的一个大致范围。如果想得到准确和时下的数值,请查阅磁盘供应商的文档,并自己做一些微基准测试。
为了更好地演示相关的时间数量级,表中"比例"一列以在理想状况下磁盘缓存命中时间为1s,按比例放大
一块磁盘可以返回两种延时:
  • 一种是磁盘缓存命中(低于100us);
  • 另一种是缓存未命中(1~8ms,甚至更慢,取决于访问模式和磁盘类型)。
由于这两种延时磁盘都返回,以一个平均延时来表达(例如iostat(1))难免有误导之嫌。事实上这是一种双峰分布。
(《性能之颠》)

常用系统操作响应时间表

(《大型网站技术架构》)

常用硬件性能参数

对于15000转的SATA盘的顺序读取,带宽可以达到100MB以上。
磁盘带宽为100MB,那么读取1MB要10ms(1000ms/100MB=10ms/MB)。
如果磁盘寻道时间为10ms,则顺序读取1MB数据的时间为:
寻道时间+数据读取时间=10ms+10ms=20ms。
(《大规模分布式存储系统》)
这组参数,看起来应该是参考了开篇中Google的数据。

总结

文中所提到的这些数据,可以拿来做架构设计和技术选型时评估使用。
如果需要关注具体的数值,以生产环境的实测数据为准。

读取1MB数据

  • 从网络中顺序读取:10ms。1秒可以读取100次,或是1s最大读取100M(1000/10=100)。
  • 从磁盘中顺序读取:30ms。1秒可以读取33次,或是1s最大读取33M(1000/30=33)。
  • 从内存中顺序读取:0.25ms。1秒可以读取4000次,或是1s最大读取4G(1000/0.25=4000)。

访问时间数量级比较

为便于理解记忆,我们这里只是关注和对比各组件之间数量级上的差异:
  • 访问CPU L1缓存:1ns;
  • 访问主存:100ns。约为访问CPU L1缓存时间的100倍;
  • 访问机械磁盘:10ms = 10,000,000ns。约为访问主存时间的10w倍;
  • 访问固态磁盘:100us = 100,000ns。约为访问机械磁盘时间的1/100倍,访问主存时间的1000倍;

题图:pixabay.com

参考

http://highscalability.com/blog/2009/2/18/numbers-everyone-should-know.html
《性能之颠》
《大规模分布式存储系统》
《大型网站技术架构》
请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

记一次 Java 服务性能优化
背景前段时间我们的服务遇到了性能瓶颈,由于前期需求太急没有注意这方面的优化,到了要还技术债的时候就非常痛苦了。在很低的 QPS 压力下服务器 load 就能达到 10-20,CPU 使用率 60% 以
代码优化日记 ——火焰图找问题代码
一、问题背景- 排序服务,用于推荐item分数预测,详细项目背景及排序请求执行逻辑可参考之前的一篇文章 :《[性能优化:线程资源回收](https://heapdump.cn/user/708
再聊 TCP backlog
这篇文章我们以 backlog 参数来深入研究一下建连的过程。通过阅读这篇文章,你会了解到下面这些知识:- backlog、半连接队列、全连接队列是什么- linux 内核是如何计算半连接队列、全连接
在被线上大量日志输出导致性能瓶颈毒打了很多次之后总结出的经验
由于线上业务量级比较大(日请求上亿,日活用户几十万),同时业务涉及逻辑很复杂,线上日志级别我们采用的是 info 级别,导致线上日志量非常庞大,经常遇到因为日志写入太慢导致的性能瓶颈(各微服务每小时日
收藏:一些比较好的Redis 性能优化思路总结
在一些网络服务的系统中,Redis 的性能,可能是比 MySQL 等硬盘数据库的性能更重要的课题。比如微博,把热点微博[1],最新的用户关系[2],都存储在 Redis 中,大量的查询击中 Redis
记一次线程池调优经历
原文链接:https://www.cnblogs.com/superfj/p/8313469.html作者:Janti 背景最近的一个项目需要用到招标,临时加了给我们的系统增加了一个性能需求,多少呢?
近期业务大量突增微服务性能优化总结-4.增加对于同步微服务的 HTTP 请求等待队列的监控
最近,业务增长的很迅猛,对于我们后台这块也是一个不小的挑战,这次遇到的核心业务接口的性能瓶颈,并不是单独的一个问题导致的,而是几个问题揉在一起:我们解决一个之后,发上线,之后发现还有另一个的性能瓶颈问
Java性能优化之影响性能的那些细节
 CRUD麻木了吗?被xxx吐槽系统慢吗?你真的了解你的代码吗?今天聊聊一些关于java性能的细节。