揭露QPS增高后的秘密
导读 | 很多人在实际的开发中害怕系统的QPS增高,因为觉得QPS太高会导致系统挂掉;基于这种心理会想着尽量的降低系统的请求量,甚至有人会将很多处理放置到服务中来处理,这样外部发一起请求,服务就把所有的业务处理完了。 |
这种方式降低了系统的请求量,但是降低了系统的QPS吗?这种做法系统更安全了还是更危险了?
首先来介绍一下基本概念。
- 系统吞吐量(Throughput)
吞吐量指单位时间内系统处理的请求数量,体现系统的整体处理能力。
- 响应时间(系统延迟Latency)
请求的平均响应时间
一般来说,一个系统的性能收到系统吞吐量和响应时间两个条件的约束,缺一不可。比如,我的系统可以顶得住一百万的并发,但是系统的延迟是2分钟以上,那么,这个一百万的负载毫无意义。系统延迟很短,但是吞吐量很低,同样没有意义。
一般情况下,针对一个系统
• 吞吐量(Throughput)越大,系统延迟(Latency)越差。因为请求量过大,系统太繁忙,所以响应速度自然会低。
• 系统延迟(Latency)越好,能支持的吞吐量(Throughput)就会越高。因为Latency短说明处理速度快,于是就可以处理更多的请求。
• 并发数
系统同时能够处理的请求数/事务数。
• QPS(也称TPS,Query per second/transaction per second)
并发数/响应时间
整体来看QPS能够概括系统吞吐量和延迟两方面指标,因此也是系统最重要的指标之一。但当系统的QPS升高,到底会对系统产生哪些影响,或者在我们如何避免QPS升高而对系统造成的危害呢?
我们紧接这来看看服务化系统的主要模式及系统资源的消耗。
一个最基础的服务,一般就包含两种操作:业务逻辑处理和DB的读写。
当一个请求发过来的时候,会消耗哪些系统资源呢?
请求对系统资源的占用
当一个请求发过来之后,常规的这个请求会消耗一下资源:CPU(负责计算)、系统内存、网络链接等系统自身资源;如果我们的系统是基于Java的,那还涉及到JVM资源的占用,JVM的heap和stack资源,其中Heap是更重要的指标。如果在这个请求需要与DB有交互,在连接DB进行操作的过程中,会消耗系统的数据库链接池资源。对应的在DB侧,会消耗DB的计算资源,而DB的计算最重要的指标就是DB的响应时间和DB的连接数。
这种服务相对基础服务是另一个极端,这种服务只依赖与其他的服务,并没有自己的数据。
请求对系统资源的占用
在这个系统里面,我们可以将依赖服务当作DB来看待,只不过在请求的过程中不再消耗系统的数据库连接池资源。
这种系统结构是我们最常用的结构,既有自身的业务数据,也会有部分计算依赖与其他服务。
混合服务的资源消耗
这种结构里面会集成上面两种结构的系统消耗。
系统负载
- •系统CPU利用率
如果系统的CPU使用率已经很高,说明我们的系统是个计算度很复杂的系统,这时候如果QPS已经上不去了,就需要赶紧扩容,通过增加机器分担计算的方式来提高系统的吞吐量。
- •系统内存
如果CPU使用率一般,但是系统的QPS已经负载不了了,说明我们的机器并没有忙于计算,而是收到其他资源的限制,如内存或者io。这时候首先看下内存是不是已经不够了,如果内存不够了,那就赶紧扩容了。
针对Java项目来说,JVM中Heap信息也是内存的一个直接反应,如Java的老年代的内存占比,是否发生Full GC的情况等。
- •系统IO
系统的IO一般是和CPU使用率相反的,CPU利用率高的时候,IO使用率就不大,而IO使用率高的时候CPU一般利用率不高。
- •网络带宽(可支持的网络链接数)
当我们自身系统的网络带宽被占用完毕的时候,相当于把系统的入口和出口给堵死了,这时候外界的需求排不进来了,QPS自然上不去。
在我们的系统中时常会使用连接池的方式来连接DB,也会使用HTTP连接池的方式向依赖系统发起服务,或者使用线程池的方式提供给其他服务使用。很多时候因为系统的本身连接池自身有最大连接数的限制,会导致系统连接数耗尽,单系统其他资源依然属于正常情况。这时候可以适当增加连接数的方式,来增加系统的吞吐能力,但这种方法需要慎重,因为过多的连接池,会更快的消耗系统资源,并且会将压力传递给依赖系统。
依赖系统的性能
- •DB 性能
DB性能很多时候是系统的根本,因为一旦DB出现了大问题,不单单会导致一个系统出问题,很可能会导致所有依赖此DB的系统出现业务逻辑问题。
一般开发在实践中,遇到最多的问题就是不当的SQL导致DB读写性能很低,如未使用索引的读写SQL;如数据库表不适当的锁范围;另外,如果DB本身的读写已经达到了自身的限度,这时候可以考虑更换机器,更换系统的硬盘,或者增加读库等方法,但这方面的优化内容非常复杂,在后面会有专门的篇幅来讨论。
- •依赖服务的性能 依赖别人的服务,很多不确定其系统性能如何,在可能情况下,可以让下游系统紧急扩容的方式来解决其自身性能问题;但对于自身系统而言,可以采用快速失败和接口降级的方式来实现。
如果上面所说的系统自身指标和依赖系统的指标都相对正常,但系统的QPS依然无法负载,说明系统内部出现问题,如系统被阻塞了。
在进行系统优化之前需要进行Profile测试分析,根据2:8原则来说,20%的代码耗了你80%的性能,找到那20%的代码,你就可以优化那80%的性能。
- •调用接口异步化
调用依赖服务时,采用异步并行的方式调用,将多个耗时的请求合并发出,可以降低很多无谓的等待时间。
- •IO异步化缓存化 系统中最常用的文件io是记录日志,在记录日志的时候设置合适的日志缓存,并使用异步化的方式写入日志文件;在必要的地方记录日志,避免日志滥用,不仅对io造成压力,且会浪费系统硬盘空间,在一些极端情况下,会因为硬盘空间耗尽而导致系统吞吐量显著下降。
针对其他需要进行文件读写的操作,建议使用异步化的方式,降低阻塞的可能。
- •API的request及response不使用过大的对象
过大的request和response会增加网络带宽的压力,且过大的字节传入容易造成数据丢失。
- •适当使用缓存
这个是在互联网服务中最常用的优化方式了,在此不再详述。
- •慎重使用线程
有人说,thread is evil,因为多线程瓶颈就在于互斥和同步的锁上,以及线程上下文切换的成本,怎么样的少用锁或不用锁是根本。另外在系统中使用线程池时,避免因为使用线程池模式和数量限制设置不当,而成为系统瓶颈。
- •数据库的锁的方式。
并发情况下,锁是非常非常影响性能的。各种隔离级别,行锁,表锁,页锁,读写锁,事务锁,以及各种写优先还是读优先机制。性能最高的是不要锁,所以,分库分表,冗余数据,减少一致性事务处理,可以有效地提高性能。
- •使用索引
在读写数据的时候都需要在where条件中检查索引的使用。
- •避免在SQL级的join操作
SQL中的join操作对索引的优化是个很复杂的问题,因为互联网的项目经常会发生变化,针对数据表的索引也会不断优化,如果使用join很可能会无法正确索引;且SQL级的索引的功能维护性也非常差。
- •部分结果集
在查询上增加适当的limit
- a.不要select * ,而是明确指出各个字段,如果有多个表,一定要在字段名前加上表名,不要让引擎去算。
- b.不要用Having,因为其要遍历所有的记录。性能差得不能再差。
- c.尽可能地使用UNION ALL 取代 UNION。
- d.索引过多,insert和delete就会越慢。而update如果update多数索引,也会慢,但是如果只update一个,则只会影响一个索引表。
- e.关于MySQL的优化,现在相关的资料也非常多,推荐高性能MySQL(第二版),这本书对MySQL的高性能有着更深入的讨论。
揭露QPS增高后的秘密的更多相关文章
- [转]细说Redis监控和告警
原文 https://zhuoroger.github.io/2016/08/20/redis-monitor-and-alarm/? 对于任何应用服务和组件,都需要一套完善可靠谱监控方案. 尤其r ...
- 电商大促准备流程v2
1 概述 对于电商企业而言,每年都会有几次大的促销活动,像双十一.店庆等,对于第一次参加这个活动的新手,难免会有些没有头绪,因而将自己参加双十一.双十二活动中的过程心得进行下总结,一方面供以后工作中继 ...
- h.264并行解码算法分析
并行算法类型可以分为两类 Function-level Decomposition,按照功能模块进行并行 Data-level Decomposition,按照数据划分进行并行 Function-le ...
- HTTP与HTTPS有哪些区别?
大纲 这里写图片描述一.前言: 这里写图片描述这里写图片描述先来观察这两张图,第一张访问域名http://www.12306.cn,谷歌浏览器提示不安全链接,第二张是https://kyfw.1230 ...
- HTTP和HTTPS协议,看一篇就够了
https://blog.csdn.net/xiaoming100001/article/details/81109617 因为http请求是无状态的,所以需要三次握手.四次挥手来确定状态. 大纲 这 ...
- 谈谈 TCP 的 TIME_WAIT
由来 最近有同事在用 ab 进行服务压测,到 QPS 瓶颈后怀疑是起压机的问题,来跟我借测试机,于是我就趁机分析了一波起压机可能成为压测瓶颈的可能,除了网络 I/O.机器性能外,还考虑到了网络协议的问 ...
- 细说C#继承
简介 继承(封装.多态)是面向对象编程三大特性之一,继承的思想就是摈弃代码的冗余,实现更好的重用性. 继承从字面上理解,无外乎让人想到某人继承某人的某些东西,一个给一个拿.这个语义在生活中,就像 家族 ...
- sync or async connect redis in golang
Head of head 在golang的整个生态里,redis client lib全部都使用多连接或者连接池.这是让人难以理解的,所以我和xiaofei一起写了一个同时支持同步和异步的redis ...
- New Concept English three (30)
27W/m 32 words the death of ghost For years, villagers believed that Endley Farm was hunted. The far ...
随机推荐
- css中 Span 元素的 width 属性无效果原因及多种解决方案
先运行下程序看下: <span style='width:300px;'>123</span> 输出:123 可以看到 span会自动根据包含的内容来变化宽度 这是因为:对于内 ...
- aircrack-ng 多网卡启动后环境清理
#!/bin/sh pkill airodump airmon-ng stop wlan0mon service network-manager restart rm -rf sadsad*
- 10月20日MySQL数据库作业解析
设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表(四)所示,数据如表1-2的表 ...
- 移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传
现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实.所以理解的解决方案就是在上传先进行图片 ...
- PHP内存溢出解决方案
一.内存溢出解决方案 在做数据统计分析时,经常会遇到大数组,可能会发生内存溢出,这里分享一下我的解决方案.还是用例子来说明这个问题,如下: 假定日志中存放的记录数为500000条,那么解决方案如下: ...
- Robot Framework--10 万能的evaluate
转自:http://blog.csdn.net/tulituqi/article/details/10124559 这一讲我们重点来介绍一下一个常用的关键字evaluate. 我觉得这个关键字在RF里 ...
- 本地wampserver如何配置伪静态
本地wamp实现虚拟主机后,我把自己的站放进去就出现了500错误看日志看到.htaccess: Invalid command ‘RewriteEngine’, perhaps misspelled ...
- CSS3导航效果
来自codepen http://codepen.io/mouradhamoud/pen/RRvVZp <!DOCTYPE html> <html> <head> ...
- 使用supervisor监控进程
在linux下监控进程,可以使用inittab,最近找到了supervisor,也很好用,记录一下:1.系统要安装python,并安装与之对应的setuptools,下载地址在此2.安装:# sh s ...
- virtualBox下面安装linux系统如何共享目录
背景: 系统是win+virtualBox 在虚拟机中安装了linuxMint系统. 如何共享目录呢 第一步: 在虚拟机中安装增强功能 2,在virtualBox中设置共享目录 3,在linux下创建 ...