Linux性能优化实战
倪朋飞
微软资深工程师,Kubernetes项目维护者
立即订阅
23407 人已学习
课程目录
已完结 64 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (2讲)
开篇词 | 别再让Linux性能问题成为你的绊脚石
免费
01 | 如何学习Linux性能优化?
CPU 性能篇 (13讲)
02 | 基础篇:到底应该怎么理解“平均负载”?
03 | 基础篇:经常说的 CPU 上下文切换是什么意思?(上)
04 | 基础篇:经常说的 CPU 上下文切换是什么意思?(下)
05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
07 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)
08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)
09 | 基础篇:怎么理解Linux软中断?
10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?
11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?
12 | 套路篇:CPU 性能优化的几个思路
13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
14 | 答疑(二):如何用perf工具分析Java程序?
内存性能篇 (8讲)
15 | 基础篇:Linux内存是怎么工作的?
16 | 基础篇:怎么理解内存中的Buffer和Cache?
17 | 案例篇:如何利用系统缓存优化程序的运行效率?
18 | 案例篇:内存泄漏了,我该如何定位和处理?
19 | 案例篇:为什么系统的Swap变高了(上)
20 | 案例篇:为什么系统的Swap变高了?(下)
21 | 套路篇:如何“快准狠”找到系统内存的问题?
22 | 答疑(三):文件系统与磁盘的区别是什么?
I/O 性能篇 (10讲)
23 | 基础篇:Linux 文件系统是怎么工作的?
24 | 基础篇:Linux 磁盘I/O是怎么工作的(上)
25 | 基础篇:Linux 磁盘I/O是怎么工作的(下)
26 | 案例篇:如何找出狂打日志的“内鬼”?
27 | 案例篇:为什么我的磁盘I/O延迟很高?
28 | 案例篇:一个SQL查询要15秒,这是怎么回事?
29 | 案例篇:Redis响应严重延迟,如何解决?
30 | 套路篇:如何迅速分析出系统I/O的瓶颈在哪里?
31 | 套路篇:磁盘 I/O 性能优化的几个思路
32 | 答疑(四):阻塞、非阻塞 I/O 与同步、异步 I/O 的区别和联系
网络性能篇 (13讲)
33 | 关于 Linux 网络,你必须知道这些(上)
34 | 关于 Linux 网络,你必须知道这些(下)
35 | 基础篇:C10K 和 C1000K 回顾
36 | 套路篇:怎么评估系统的网络性能?
37 | 案例篇:DNS 解析时快时慢,我该怎么办?
38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
40 | 案例篇:网络请求延迟变大了,我该怎么办?
41 | 案例篇:如何优化 NAT 性能?(上)
42 | 案例篇:如何优化 NAT 性能?(下)
43 | 套路篇:网络性能优化的几个思路(上)
44 | 套路篇:网络性能优化的几个思路(下)
45 | 答疑(五):网络收发过程中,缓冲区位置在哪里?
综合实战篇 (13讲)
46 | 案例篇:为什么应用容器化后,启动慢了很多?
47 | 案例篇:服务器总是时不时丢包,我该怎么办?(上)
48 | 案例篇:服务器总是时不时丢包,我该怎么办?(下)
49 | 案例篇:内核线程 CPU 利用率太高,我该怎么办?
50 | 案例篇:动态追踪怎么用?(上)
51 | 案例篇:动态追踪怎么用?(下)
52 | 案例篇:服务吞吐量下降很厉害,怎么分析?
53 | 套路篇:系统监控的综合思路
54 | 套路篇:应用监控的一般思路
55 | 套路篇:分析性能问题的一般步骤
56 | 套路篇:优化性能问题的一般方法
57 | 套路篇:Linux 性能工具速查
58 | 答疑(六):容器冷启动如何性能分析?
加餐篇 (4讲)
加餐(一) | 书单推荐:性能优化和Linux 系统原理
加餐(二) | 书单推荐:网络原理和 Linux 内核实现
用户故事 | “半路出家 ”,也要顺利拿下性能优化!
用户故事 | 运维和开发工程师们怎么说?
结束语 (1讲)
结束语 | 愿你攻克性能难关
Linux性能优化实战
登录|注册

28 | 案例篇:一个SQL查询要15秒,这是怎么回事?

倪朋飞 2019-01-23
你好,我是倪朋飞。
上一节,我们分析了一个单词热度应用响应过慢的案例。当用 top、iostat 分析了系统的 CPU 和磁盘 I/O 使用情况后,我们发现系统出现了磁盘的 I/O 瓶颈,而且正是案例应用导致的。
接着,在使用 strace 却没有任何发现后,我又给你介绍了两个新的工具 filetop 和 opensnoop,分析它们对系统调用 write() 和 open() 的追踪结果。
我们发现,案例应用正在读写大量的临时文件,因此产生了性能瓶颈。找出瓶颈后,我们又用把文件数据都放在内存的方法,解决了磁盘 I/O 的性能问题。
当然,你可能会说,在实际应用中,大量数据肯定是要存入数据库的,而不会直接用文本文件的方式存储。不过,数据库也不是万能的。当数据库出现性能问题时,又该如何分析和定位它的瓶颈呢?
今天我们就来一起分析一个数据库的案例。这是一个基于 Python Flask 的商品搜索应用,商品信息存在 MySQL 中。这个应用可以通过 MySQL 接口,根据客户端提供的商品名称,去数据库表中查询商品信息。
非常感谢唯品会资深运维工程师阳祥义,帮助提供了今天的案例。

案例准备

本次案例还是基于 Ubuntu 18.04,同样适用于其他的 Linux 系统。我使用的案例环境如下所示:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Linux性能优化实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(30)

  • ninuxer
    打卡day29
    echo 1>/proc/sys/vm/drop_caches表示释放pagecache,也就是文件缓存,而mysql读书的数据就是文件缓存,dataservice不停的释放文件缓存,就导致MySQL都无法利用磁盘缓存,也就慢了~

    作者回复: 赞,正解

    2019-01-23
    36
  • 大坏狐狸
    这个地方因为之前了解过,所以来打个卡,这个算法在高性能mysql里有介绍,叫最优前缀.
    有时候需要索引很长的字符列,这会让索引变得大且慢。通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。但这样也会降低索引的选择性。索引的选择性是指不重复的索引值(也称为基数,cardinality)和数据表的记录总数的比值,范围从1/#T到1之间。索引的选择性越高则查询效率越高,因为选择性高的索引可以让MySQL在查找时过滤掉更多的行。唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。

    一般情况下某个前缀的选择性也是足够高的,足以满足查询性能。对于BLOB,TEXT,或者很长的VARCHAR类型的列,必须使用前缀索引,因为MySQL不允许索引这些列的完整长度。

    诀窍在于要选择足够长的前缀以保证较高的选择性,同时又不能太长(以便节约空间)。前缀应该足够长,以使得前缀索引的选择性接近于索引的整个列。换句话说,前缀的”基数“应该接近于完整的列的”基数“。
    select count(distinct city)/count(*) from city_demo; 根据这个算出一个比例,然后 count(distinct left(city,3)) 把这个3逐渐的加大,一直到算出来的数值接近上面的比例,这样算出来的前缀索引是性能最好的。

    作者回复: 赞,谢谢分享详细的前缀选择算法

    2019-02-11
    9
  • 某、人
    非常赞,这篇案例很好的展示了怎么从操作系统层面去排查慢查询的问题
    2019-01-24
    8
  • rm -rf 😊ི
    有个疑问,老师之前不是说过数据库有自己一套缓存机制吗?为何删除cached也会影响到mysql的读写呢

    作者回复: 数据库的缓存还要看选择了存储引擎,MyISAM不会缓存数据

    2019-04-04
    6
  • 王星旗
    老师,请教一个问题啊,既然只是iowait占比高,cpu占比不高,为什么执行其它命令会感觉卡呢?在等待io的时候,CPU不应该去执行其它进程吗?

    作者回复: 执行命令也需要IO操作(比如读目录找到binary,加载命令和依赖的库等等)

    2019-08-20
    2
  • 小老鼠
    即停止DataService ,又增加索3引是不是性能会更好?

    作者回复: 是的,利用缓存后性能会更好

    2019-01-26
    1
  • guoew
    以前遇到数据库慢的问题都是直接进数据库show processlist ,没有一个循序渐进的过程。感谢老师
    2019-01-25
    1
  • 李逍遥
    mysql打开慢查询日志,排查SQL性能问题更方便

    作者回复: 嗯嗯,慢查询推荐总是开启

    2019-01-23
    1
  • tux
    回顾阶段,再运行案例,发现总会出两种现象:
    1.卡在 进度条(出现最多)
    root@t-s:mysql-slow:: make run
    ...
    1f212fb371f9: Downloading [==========================> ] 1.137MB/1.27MB
    ...

    2.卡在 Waiting
    root@t-s:mysql-slow:: make run
    ...
    44fa5ea1d96b: Waiting
    ...


    此篇,从上周到这周,没有make run成功过。
    I/0性能篇,抛开此篇,其它篇需要docker run好几次,才能运行案例。

    是个例吗?

    作者回复: 默认的镜像是从dockerhub上面拉下来的,有时候可能会比较慢,可以试试通过代理访问

    2019-10-21
  • 辉晖
    mysql进程每秒写入8M/S,until接近100%,iowait有40%。可是反复运行show full processlist;一直查不到耗时长(除了Sleep)的语句,要怎么排查?
    2019-09-20
  • 之前运行make init的时候,会报错连不上本地数据库,后来发现是因为mysql还没启动好,app就已经启动了,所以一直连不上。将app重启一次就好了

    作者回复: 谢谢分享您的步骤,可能是有的环境mysql初始化比较慢

    2019-08-21
  • 一想再想N
    可以把不走索引的查询记录到日志中去
    2019-08-05
  • 西瓜就咸菜
    我把insert条数增大到1000000,curl 的响应时间很短,0.0011873245239257812 sec,跟实验的结果不一样,我看系统的状态也没有io问题,通过pidstat也没有mysql的 iodelay

    作者回复: 再增加数据(比如10倍)试试?😓

    2019-07-08
  • Musisan
    man确实是个好东西,以前给忽略了哈,^_^
    2019-05-20
  • LYy
    硬核 赞👍
    2019-05-18
  • 无名老卒
    实例插入了3W条数据,这样子才使得get data的时间变大了一些,后面增加了索引之后,就变正常了。
    ```
    root@fdm:~#while :;do curl http://192.168.254.131:10000/products/geektime;done
    Got data: () in 2.335655689239502 sec
    Got data: () in 2.3957033157348633 sec
    Got data: () in 5.153362274169922 sec
    Got data: () in 6.846464157104492 sec
    Got data: () in 3.2172300815582275 sec
    Got data: () in 0.04523611068725586 sec
    Got data: () in 0.0017778873443603516 sec
    Got data: () in 0.00156402587890625 sec
    Got data: () in 0.0016543865203857422 sec
    ```

    但是后面把dataservice停止之后,还是没有什么提高的效果,所以有可能硬盘使用了SSD,以及内存只有2G的原因导致的。另外说明一点的是,插入3W条数据之后,看到的products.MYD有1.5G了~

    作者回复: 插入更多的数据试试?

    2019-04-25
  • 王伟
    打卡
    2019-04-23
  • 大飞
    打卡
    2019-04-03
  • 如果
    DAY28,打卡
    2019-03-13
  • 陈云卿
    打卡day29 ,之前在工作中遇到过 释放缓存的情况,但是也会发现echo 1在某些情况下没有办法有效地释放缓存,这会是什么原因引起的呢?

    作者回复: 试试 echo 3

    2019-02-06
收起评论
30
返回
顶部