观察 iostat 的输出 ,
我们发现 , 磁盘 sda 每秒的写数据(wkB/s)为 2.5MB , I/O 使用率(%util)是 0 。
看来 , 虽然有些 I/O 操作 , 但并没导致磁盘的 I/O 瓶颈 。
排查一圈儿下来 , CPU 和内存使用没问题 , I/O 也没有瓶颈 , 接下来好像就没啥分析方向了?
碰到这种情况 , 还是那句话 , 反思一下 , 是不是又漏掉什么有用线索了 。
你可以先自己思考一下 , 从分析对象(案例应用)、系统原理和性能工具这三个方向下功夫 , 回忆它们的特性 , 查找现象的异常 , 再继续往下走 。
回想一下 , 今天的案例问题是从 Redis 缓存中查询数据慢 。
对查询来说 , 对应的 I/O 应该是磁盘的读操作 , 但刚才我们用 iostat 看到的却是写操作 。
虽说 I/O 本身并没有性能瓶颈 , 但这里的磁盘写也是比较奇怪的 。
为什么会有磁盘写呢?那我们就得知道 , 到底是哪个进程在写磁盘 。
要知道 I/O 请求来自哪些进程 , 还是要靠我们的老朋友 pidstat 。在终端一中运行下面的 pidstat 命令 , 观察进程的 I/O 情况:
$ pidstat -d 112:49:35 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command12:49:36 0 368 0.00 16.00 0.00 86 jbd2/sda1-812:49:36 100 9085 0.00 636.00 0.00 1 redis-server从 pidstat 的输出 , 我们看到 , I/O 最多的进程是 PID 为 9085 的 redis-server , 并且它也刚好是在写磁盘 。这说明 , 确实是 redis-server 在进行磁盘写 。 当然 , 光找到读写磁盘的进程还不够 , 我们还要再用 strace+lsof 组合 , 看看 redis-server 到底在写什么 。
接下来 , 还是在终端一中 , 执行 strace 命令 , 并且指定 redis-server 的进程号 9085:
# -f表示跟踪子进程和子线程 , -T表示显示系统调用的时长 , -tt表示显示跟踪时间
$ strace -f -T -tt -p 9085[pid 9085] 14:20:16.826131 epoll_pwait(5, [{EPOLLIN, {u32=8, u64=8}}], 10128, 65, NULL, 8) = 1 <0.000055>[pid 9085] 14:20:16.826301 read(8, "*2rn$3rnGETrn$41rnuuid:5b2e76cc-"..., 16384) = 61 <0.000071>[pid 9085] 14:20:16.826477 read(3, 0x7fff366a5747, 1) = -1 EAGAIN (Resource temporarily unavailable) <0.000063>[pid 9085] 14:20:16.826645 write(8, "$3rnbadrn", 9) = 9 <0.000173>[pid 9085] 14:20:16.826907 epoll_pwait(5, [{EPOLLIN, {u32=8, u64=8}}], 10128, 65, NULL, 8) = 1 <0.000032>[pid 9085] 14:20:16.827030 read(8, "*2rn$3rnGETrn$41rnuuid:55862ada-"..., 16384) = 61 <0.000044>[pid 9085] 14:20:16.827149 read(3, 0x7fff366a5747, 1) = -1 EAGAIN (Resource temporarily unavailable) <0.000043>[pid 9085] 14:20:16.827285 write(8, "$3rnbadrn", 9) = 9 <0.000141>[pid 9085] 14:20:16.827514 epoll_pwait(5, [{EPOLLIN, {u32=8, u64=8}}], 10128, 64, NULL, 8) = 1 <0.000049>[pid 9085] 14:20:16.827641 read(8, "*2rn$3rnGETrn$41rnuuid:53522908-"..., 16384) = 61 <0.000043>[pid 9085] 14:20:16.827784 read(3, 0x7fff366a5747, 1) = -1 EAGAIN (Resource temporarily unavailable) <0.000034>[pid 9085] 14:20:16.827945 write(8, "$4rngoodrn", 10) = 10 <0.000288>[pid 9085] 14:20:16.828339 epoll_pwait(5, [{EPOLLIN, {u32=8, u64=8}}], 10128, 63, NULL, 8) = 1 <0.000057>[pid 9085] 14:20:16.828486 read(8, "*3rn$4rnSADDrn$4rngoodrn$36rn535"..., 16384) = 67 <0.000040>[pid 9085] 14:20:16.828623 read(3, 0x7fff366a5747, 1) = -1 EAGAIN (Resource temporarily unavailable) <0.000052>[pid 9085] 14:20:16.828760 write(7, "*3rn$4rnSADDrn$4rngoodrn$36rn535"..., 67) = 67 <0.000060>[pid 9085] 14:20:16.828970 fdatasync(7) = 0 <0.005415>[pid 9085] 14:20:16.834493 write(8, ":1rn", 4) = 4 <0.000250>
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 响应速度与智能化如何平衡,携程酒店搜索实践
- 使用Redis轻松实现秒杀系统
- 慢性咽喉炎的症状
- mongodb,redis,hbase,三者都是nosql数据库,他们的最大区别和不同定位是什么?
- Redis、传统数据库、HBase以及Hive的区别
- 聊聊Mysql索引和redis跳表
- Redis:缓存被我写满了,该怎么办?
- 肾结石严重吗?专业人士来回答!
- 老人心肌梗塞严重吗
- ios15.1更新后电池,苹果11升级ios14.4.1耗电严重-
