Linux性能優化實戰學習筆記:第二十八講

1、案例環境描述

一、環境準備

2CPU,4GB內存python

預先安裝docker sysstat工具mysql

apt install docker.io sysstat nake git

案例總共由三個容器組成:linux

一、包括一個 MySQL 數據庫應用、
二、一個商品搜索應用
三、一個數據處理的應用。ios

其中,商品搜索應用以 HTTP 的形式提供了一個接口:git

/:返回 Index Page;
/db/insert/products/:插入指定數量的商品信息
/products/:查詢指定商品的信息,並返回處理時間。github

二、架構圖

今天的案例須要兩臺虛擬機,其中一臺做爲案例分析的目標機器,運行 Flask 應用,它的 IP 地址是 192.168.0.10;另外一臺則是做爲客戶端,請求單詞的熱度。我畫了一張圖表示它們的關係。sql

三、測試環境準備

首先、咱們在第一個終端中執行下面命令,拉去本次案例所需的腳本:

git clone https://github.com/feiskyer/linux-perf-examples
$ cd linux-perf-examples/mysql-slow

接着,執行下面的命令,運行本次的目錄應用,正常狀況下,你應該能夠看到下面的輸出

[root@luoahong mysql-slow]# make run
docker run --name=mysql -itd -p 10000:80 -m 800m feisky/mysql:5.6
eb934a265f31aaedc262c89c9dcd201c4b77f704b65119dc683b63726f578a3e
docker run --name=dataservice -itd --privileged feisky/mysql-dataservice
d7183422cf1213ccc1797a1f5a79fc8f14a997ef3942cf999dab8c2c72dc8b2b
docker run --name=app --network=container:mysql -itd feisky/mysql-slow
f08ca0395fccbd187a57eba932cd072c8460b1a9decff0e1cde46472c8eb409d

注意容器下面的碎字符串是容器ID,每次運行均會不一樣,而且你不須要關注它,由於咱們只會用到名字  docker

而後,再次運行docker ps命令,確認三個容器都處在運行(Up)狀態;

[root@luoahong mysql-slow]# docker ps 
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                             NAMES
f08ca0395fcc        feisky/mysql-slow          "python /app.py"         27 seconds ago      Up 26 seconds                                         app
d7183422cf12        feisky/mysql-dataservice   "python /dataservice…"   28 seconds ago      Up 26 seconds                                         dataservice
eb934a265f31        feisky/mysql:5.6           "docker-entrypoint.s…"   29 seconds ago      Up 27 seconds       3306/tcp, 0.0.0.0:10000->80/tcp   mysql
[root@luoahong mysql-slow]# 

MySQL數據庫的啓動過程,須要作一些初始化工做,這一般須要花費幾分鐘時間,你能夠運行dockers log命令、查看它的啓動過程數據庫

[root@luoahong mysql-slow]# docker logs -f mysql
Initializing database
2019-05-30 06:27:03 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2019-05-30 06:27:03 0 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
2019-05-30 06:27:25 1 [Note] Server socket created on IP: '::'.
......
2019-05-30 06:27:25 1 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2019-05-30 06:27:25 1 [Warning] 'proxies_priv' entry '@ root@eb934a265f31' ignored in --skip-name-resolve mode.
2019-05-30 06:27:25 1 [Note] Event Scheduler: Loaded 0 events
2019-05-30 06:27:25 1 [Note] mysqld: ready for connections.
Version: '5.6.42-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

確認商品搜索應用在10000端口監聽,確認它也已經正常運行bootstrap

[root@luoahong tools]# curl http://127.0.0.1:10000/
Index Page[root@luoahong tools]# 

2、故障現象

一、發現故障

運行make init命令,初始化數據庫、插入10000條商品信息(這個過程比較慢,大約須要十幾分鐘的時

[root@luoahong mysql-slow]# make init
docker exec -i mysql mysql -uroot -P3306 < tables.sql
curl http://127.0.0.1:10000/db/insert/products/20000
insert 20000 lines

在第二個終端,訪問一下商品搜索的接口、看看能不能找到想要的商品、執行以下的curl命令

[root@luoahong mysql-slow]# curl http://192.168.118.115:10000/products/geektime
Got data: () in 8.804400205612183 sec 

二、故障現象

稍等一下子,你會發現,這個接口返回的是空數據,並且處理時間超過15秒,這麼慢的響應速度讓人沒法忍受,到底出了什麼問題呢?

3、分析過程

在第二個終端繼續執行下面的命令

[root@luoahong ~]# while true; do curl http://192.168.118.115:10000/products/geektime; sleep 5; done
Got data: () in 8.62768268585205 sec 
Got data: () in 9.515994548797607 sec 
Got data: () in 8.497008562088013 sec 
Got data: () in 8.946581602096558 sec 
Got data: () in 8.66761040687561 sec 
Got data: () in 9.343888998031616 sec 
Got data: () in 8.72763991355896 sec 
Got data: () in 8.446544647216797 sec 
Got data: () in 8.668050289154053 sec 
Got data: () in 9.259597539901733 sec 
Got data: () in 8.74580430984497 sec 
Got data: () in 8.766760110855103 sec 
Got data: () in 8.431026220321655 sec 

一、首先、咱們在中斷執行top命令、分析系統的CPU使用狀況:

觀察top的輸出,咱們發現:

一、兩個CPU的iowat都比較高、特別是cpu0,iowat已經超過了60%

二、而具體到各個進程, CPU 使用率並不高,最高的也只有17.2 

二、既然CPU嫌疑不大,那問題應該在I/O上,中止top命令;而後執行iostat命令,看看有沒有I/O性能問題

[root@luoahong mysql-slow]# iostat -d -x 1
Linux 5.1.0-1.el7.elrepo.x86_64 (luoahong) 	05/30/2019 	_x86_64_	(2 CPU)

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda             16.27  10181.73     0.02   0.10   39.60   625.71   18.35    976.48     0.46   2.44    3.22    53.23    0.00      0.00     0
Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda             30.00   4436.00     0.00   0.00    7.23   147.87    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.20   3.50

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            129.00 110716.00     1.00   0.77   46.16   858.26    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    5.89  19.10

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            118.00 112244.00     1.00   0.84   50.22   951.22    1.00      4.00     0.00   0.00   34.00     4.00    0.00      0.00     0.00   0.00    0.00     0.00    5.90  18.70

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            116.00 118784.00     0.00   0.00   54.59  1024.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    6.27  18.50

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            119.00 121600.00     0.00   0.00   53.70  1021.85    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    6.34  19.20

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            126.00 118788.00     2.00   1.56   54.24   942.76    1.00      4.00     0.00   0.00   40.00     4.00    0.00      0.00     0.00   0.00    0.00     0.00    6.81  19.20

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            106.00 109056.00     0.00   0.00   62.00  1028.83    1.00      7.50     0.00   0.00   52.00     7.50    0.00      0.00     0.00   0.00    0.00     0.00    6.50  16.50

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            101.00 102656.00     0.00   0.00   63.90  1016.40    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    6.47  16.10

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            127.72 120146.53     1.98   1.53   53.74   940.68    1.98     11.88     0.00   0.00   42.50     6.00    0.00      0.00     0.00   0.00    0.00     0.00    6.89  19.50

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
sda            102.00  93000.00     0.00   0.00   48.75   911.76    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    4.92  14.50

一、磁盤 sda 每秒的讀數據爲 32 MB
二、而 I/O 使用率高達 97%
三、接近飽和,這說明,磁盤 sda 的讀取確實碰到了性能瓶頸

三、如何知道這些進程是那些進程致使的呢?

[root@luoahong mysql-slow]# pidstat -d 1
Linux 5.1.0-1.el7.elrepo.x86_64 (luoahong) 	05/30/2019 	_x86_64_	(2 CPU)

04:18:28 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

04:18:29 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
04:18:30 PM     0     10641      4.00      4.00      0.00       0  python
04:18:30 PM     0     10945      0.00      0.00      0.00       1  kworker/0:0-events

04:18:30 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

04:18:31 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
04:18:32 PM     0     10945      0.00      0.00      0.00       1  kworker/0:0-events_power_efficient

04:18:32 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
04:18:33 PM     0     10263    556.00      0.00      0.00       0  bash
04:18:33 PM   999     10560  15872.00      0.00      0.00       0  mysqld
04:18:33 PM     0     10641      0.00      4.00      0.00       0  python
04:18:33 PM     0     11084   5792.00      0.00      0.00      29  curl

四、分析進程的數據讀取 須要用到strace+ lsof 組合。

爲何mysqld會讀取大量的磁盤數據呢?按照前面猜想,咱們提到過、這有多是慢查詢問題
但是、回想一下、慢查詢的現象大可能是cpu使用率高,但這裏的看到的確實I/O問題,看來、這並非一個單純的
慢查詢問題,咱們有必要分析一下mysql讀取的數據

咱們知道,MySQL 是一個多線程的數據庫應用,爲了避免漏掉這些線程的數據讀取狀況,你要記得在執行stace 命令時,加上 -f 參數:

strace -f -p 10560
[pid 10919] read(37, "gOvH0QGqpShDOt3TFpB7mWFxIsGFpxEQ"..., 131072) = 131072
[pid 10919] read(37, "veWjWoElqB6E26n7ghhjHtFdRfUcQ4Vt"..., 20480) = 20480
[pid 10919] read(37, "tiyHTvaaW6XOT9Sq7dZMmNimVOPvFoWp"..., 131072) = 131072
[pid 10919] read(37, "78fMhVd5SH38edDFgwuLpDNdiNIp7mHo"..., 24576) = 24576
[pid 10919] read(37, "GpjARraEFkUJCzaO41iaoiVmWW730hS1"..., 131072) = 131072
[pid 10919] read(37, "T4K9rAkBz3cApPxKNJyPpSU6lK4CuUaq"..., 20480) = 20480
[pid 10919] read(37, "dUndUh2lEwhYK6ueXqfZ6jjj1Y9OSniP"..., 131072) = 131072
[pid 10919] read(37, "r7WsV96IojCmciSHlgk0Pp7oqkoq7hL4"..., 24576) = 24576
[pid 10919] read(37, "4kvN7g1EidOep0AFEN0bzOLNYjFt3FM0"..., 131072) = 131072

線程 10919 正在讀取大量數據、且讀取文件的描述符編號爲 37。

五、這兒的 37 又對應着哪一個文件呢?

[root@luoahong ~]# lsof -p 10919
[root@luoahong ~]# echo $?
1

爲何 lsof 命令執行失敗了呢?

遇到現象解釋不了,先去查查工具文檔。事實上,經過查詢 lsof 的文檔,你會發現,-p 參數須要指定進程號,而咱們剛纔傳入的是線程號,因此 lsof 失敗了

[root@luoahong ~]# pstree -a -p 10560
mysqld,10560 --log_bin=on --sync_binlog=1
  ├─{mysqld},10856
  ├─{mysqld},10857
  ├─{mysqld},10858
  ├─{mysqld},10859
  ├─{mysqld},10860
  ├─{mysqld},10861
  ├─{mysqld},10862
  ├─{mysqld},10863
  ├─{mysqld},10864
  ├─{mysqld},10865
  ├─{mysqld},10867
  ├─{mysqld},10868
  ├─{mysqld},10869
  ├─{mysqld},10870
  ├─{mysqld},10871
  ├─{mysqld},10872
  ├─{mysqld},10873
  ├─{mysqld},10874
  ├─{mysqld},10875
  ├─{mysqld},10876
  └─{mysqld},10919

你會發現,mysqld 其實還有不少正在運行的其餘線程:  

 六、找到了緣由,lsof 的問題就容易解決了。把線程號換成進程號、繼續執行 lsof 命令:

[root@luoahong ~]# lsof -p 10560
COMMAND   PID    USER   FD   TYPE DEVICE   SIZE/OFF     NODE NAME
mysqld  10560 polkitd  cwd    DIR    8,2        239   455186 /var/lib/mysql
mysqld  10560 polkitd  rtd    DIR   0,42         28  1315612 /
mysqld  10560 polkitd  txt    REG   0,42   15759280 39165788 /usr/sbin/mysqld
......
mysqld  10560 polkitd  DEL    REG   0,17               65017 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65016 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65015 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65014 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65013 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65012 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65011 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65010 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65009 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65008 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65007 /[aio]
mysqld  10560 polkitd  DEL    REG   0,17               65004 /[aio]
mysqld  10560 polkitd    0u   CHR  136,0        0t0        3 /dev/pts/0
mysqld  10560 polkitd    1u   CHR  136,0        0t0        3 /dev/pts/0
mysqld  10560 polkitd    2u   CHR  136,0        0t0        3 /dev/pts/0
mysqld  10560 polkitd    3u   REG    8,2         48 21165914 /var/lib/mysql/on.index
mysqld  10560 polkitd    4uW  REG    8,2   12582912 18611645 /var/lib/mysql/ibdata1
mysqld  10560 polkitd    5u   REG   0,42          0 74328016 /tmp/ibbSKXmR (deleted)
mysqld  10560 polkitd    6u   REG   0,42          0 74328017 /tmp/ibeUxi1R (deleted)
mysqld  10560 polkitd    7u   REG   0,42          0 74328018 /tmp/ibaQWDFS (deleted)
mysqld  10560 polkitd    8u   REG   0,42          0 74328019 /tmp/iboRiwZT (deleted)
mysqld  10560 polkitd    9uW  REG    8,2   50331648 18611646 /var/lib/mysql/ib_logfile0
mysqld  10560 polkitd   10uW  REG    8,2   50331648 18611647 /var/lib/mysql/ib_logfile1
mysqld  10560 polkitd   11w   REG    8,2        820 21165905 /var/lib/mysql/fef6fa81243e-slow.log
mysqld  10560 polkitd   12u   REG   0,42          0 74328020 /tmp/ibellVRU (deleted)
mysqld  10560 polkitd   13u  sock    0,9        0t0    65025 protocol: TCPv6
mysqld  10560 polkitd   14w   REG    8,2 1026029812 21165913 /var/lib/mysql/on.000004
mysqld  10560 polkitd   15u  sock    0,9        0t0    65026 protocol: UNIX
mysqld  10560 polkitd   16u   REG    8,2       2048 74317349 /var/lib/mysql/mysql/user.MYI
mysqld  10560 polkitd   17u   REG    8,2        452 74317350 /var/lib/mysql/mysql/user.MYD
mysqld  10560 polkitd   18u   REG    8,2       5120 74317346 /var/lib/mysql/mysql/db.MYI
mysqld  10560 polkitd   19u   REG    8,2        880 74317347 /var/lib/mysql/mysql/db.MYD
mysqld  10560 polkitd   20u   REG    8,2       5120 74317493 /var/lib/mysql/mysql/proxies_priv.MYI
mysqld  10560 polkitd   21u   REG    8,2       1386 74317494 /var/lib/mysql/mysql/proxies_priv.MYD
mysqld  10560 polkitd   22u   REG    8,2       4096 74317361 /var/lib/mysql/mysql/tables_priv.MYI
mysqld  10560 polkitd   23u   REG    8,2          0 74317362 /var/lib/mysql/mysql/tables_priv.MYD
mysqld  10560 polkitd   24u   REG    8,2       4096 74317364 /var/lib/mysql/mysql/columns_priv.MYI
mysqld  10560 polkitd   25u   REG    8,2          0 74317365 /var/lib/mysql/mysql/columns_priv.MYD
mysqld  10560 polkitd   26u   REG    8,2       4096 74317468 /var/lib/mysql/mysql/procs_priv.MYI
mysqld  10560 polkitd   27u   REG    8,2          0 74317469 /var/lib/mysql/mysql/procs_priv.MYD
mysqld  10560 polkitd   28u   REG    8,2       1024 74317358 /var/lib/mysql/mysql/servers.MYI
mysqld  10560 polkitd   29u   REG    8,2          0 74317359 /var/lib/mysql/mysql/servers.MYD
mysqld  10560 polkitd   30uW  REG    8,2      98304 74317489 /var/lib/mysql/mysql/slave_master_info.ibd
mysqld  10560 polkitd   31uW  REG    8,2      98304 74317491 /var/lib/mysql/mysql/slave_worker_info.ibd
mysqld  10560 polkitd   32uW  REG    8,2      98304 74317487 /var/lib/mysql/mysql/slave_relay_log_info.ibd
mysqld  10560 polkitd   33u   REG    8,2       2048 74317477 /var/lib/mysql/mysql/event.MYI
mysqld  10560 polkitd   34u   REG    8,2          0 74317478 /var/lib/mysql/mysql/event.MYD
mysqld  10560 polkitd   36u   REG    8,2     207872 74328024 /var/lib/mysql/test/products.MYI
mysqld  10560 polkitd   37u   REG    8,2 1024880000 74328025 /var/lib/mysql/test/products.MYD

mysqld 進程確實打開了大量文件

而根據文件描述符(FD)的編號,咱們知道,描述符爲 37 的是一個路徑爲/var/lib/mysql/test/products.MYD的文件,這裏注意37後面的U表示,mysqld讀寫的方式訪問文件
看到這個文件,熟悉 MySQL 的你可能笑了:

一、MYD 文件,是 MyISAM 引擎用來存儲表數據的文件;
二、文件名就是數據表的名字;
三、而這個文件的父目錄,也就是數據庫的名字。

換句話說,這個文件告訴咱們,mysqld 在讀取數據庫 test中的products表

七、查看 mysqld 在管理數據庫 test 時的存儲文件

[root@luoahong ~]# docker exec -it mysql ls /var/lib/mysql/test/
db.opt	products.MYD  products.MYI  products.frm

從這裏你能夠發現,/var/lib/mysql/test/ 目錄中有四個文件,每一個文件的做用分別是:

一、MYD 文件用來存儲表的數據;
二、MYI 文件用來存儲表的索引;
三、frm 文件用來存儲表的元信息(好比表結構);
四、opt 文件則用來存儲數據庫的元信息(好比字符集、字符校驗規等

八、這些文件究竟是不是 mysqld 正在使用的數據庫文件呢?

[root@luoahong mysql-slow]# docker exec -i -t mysql mysql -e 'show global variables like "%datadir%";'
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+

九、數據庫中正在執行什麼樣的 SQL 了

不過,爲了保證 SQL 語句不截斷、這裏咱們能夠執行 show full processlist命令。若是一切正常,你應該能夠看到以下輸出:

mysql> show full processlist;
+-----+------+-----------------+------+---------+------+--------------+-----------------------------------------------------+
| Id  | User | Host            | db   | Command | Time | State        | Info                                                |
+-----+------+-----------------+------+---------+------+--------------+-----------------------------------------------------+
| 183 | root | localhost       | NULL | Query   |    0 | init         | show full processlist                               |
| 188 | root | 127.0.0.1:60018 | test | Query   |    1 | Sending data | select * from products where productName='geektime' |
+-----+------+-----------------+------+---------+------+--------------+-----------------------------------------------------+
2 rows in set (0.00 sec)

十、explain 命令確認是否創建索引

根據這些信息,咱們能夠肯定,這條查詢語句壓根兒沒有使用索引,因此查詢時,會掃描全表,而且掃描行數高達 20000 行。響應速度那麼慢也就難怪了。

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> explain select * from products where productName='geektime';
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | products | ALL  | NULL          | NULL | NULL    | NULL | 20000 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.01 sec)

查詢 products 表的結構

mysql> show create table products;
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| products | CREATE TABLE `products` (
  `id` int(11) NOT NULL,
  `productCode` text NOT NULL COMMENT '產品代碼',
  `productName` text NOT NULL COMMENT '產品名稱',
  `productLine` text NOT NULL COMMENT '產品線',
  `productScale` text NOT NULL,
  `productVendor` text NOT NULL,
  `productDescription` text NOT NULL,
  `quantityInStock` smallint(6) NOT NULL COMMENT '庫存',
  `buyPrice` decimal(10,2) NOT NULL COMMENT '價格',
  `MSRP` decimal(10,2) NOT NULL COMMENT '建議零售價',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

你會看到,它只有一個 id 主鍵,並不包括 productName 的索引: 

十一、建立索引 

mysql> CREATE INDEX products_index ON products (productName);
ERROR 1170 (42000): BLOB/TEXT column 'productName' used in key specification without a key length

你會看到,它只有一個 id 主鍵,並不包括 productName 的索引:就必須爲 productName 指定一個前綴長度

mysql>  CREATE INDEX products_index ON products (productName(64));
Query OK, 20000 rows affected (38.83 sec)
Records: 20000  Duplicates: 0  Warnings: 0

如今能夠看到,索引已經建好了。能作的都作完了,最後就該檢查一下,性能問題是否已經解決了。

查看還在執行的 curl 命令的結果:

[root@luoahong ~]# while true; do curl http://192.168.118.115:10000/products/geektime; sleep 5; done
Got data: () in 8.62768268585205 sec 
Got data: () in 8.635614395141602 sec 
Got data: () in 8.58862042427063 sec 
Got data: () in 22.183180809020996 sec 
Got data: () in 0.19141674041748047 sec 
Got data: () in 0.010161638259887695 sec 
Got data: () in 0.006281137466430664 sec 
Got data: () in 0.006078481674194336 sec 

查看還在執行的 curl 命令的結果:

4、DataService 是一個嚴重影響 MySQL 性能的干擾應用

一、中止DataService容器

[root@luoahong ~]# 
[root@luoahong ~]# docker rm -f dataservice
dataservice

二、刪除索引

$ docker exec -i -t mysql mysql
mysql> mysql> 
mysql> DROP INDEX products_index ON products;
Query OK, 20000 rows affected (16.24 sec)
Records: 20000  Duplicates: 0  Warnings: 0

三、觀察性能

[root@luoahong ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0  35340 1429716      0 1131008    0    3 20224   421  409  517 10  5 70 16  0
 0  1  35340 1427952      0 1130840   16    0 110096     0  607  429  2 11 55 33  0
 0  1  35340 1429188      0 1130904    0    0 111368     0  583  361  1 11 50 38  0
 0  1  35852 1429212      0 1131276    0  388 93088   388  680  536  1 11 52 37  0
 2  0  36108 1427440      0 1131444    0  240 80744   240  624  390  3 13 50 35  0
 1  1  40716 1427952      0 1132732    0 4808 102312  4808  527  376  1  9 51 39  0
 0  0  40716 1430220      0 1132712    0    0 35228     0  331  335  1  5 78 16  0
 0  0  40716 1430220      0 1132712    0    0     0     0  123  210  0  0 100  0  0
 2  0  40716 1430220      0 1132712    0    0     0     0  124  202  1  1 99  0  0
 0  0  40716 1430220      0 1132712    0    0     0     0  142  226  0  1 99  0  0
 1  0  40716 1430220      0 1132712    0    0     0     0  194  246  1  2 97  0  0

四、觀察 curl 的結果:

Got data: () in 13.258588314056396 sec 
Got data: () in 9.701965808868408 sec 
Got data: () in 9.14393663406372 sec 
Got data: () in 9.088764190673828 sec 

Got data: () in 5.43427038192749 sec 
Got data: () in 5.0143187046051025 sec 
Got data: () in 6.960656404495239 sec 
Got data: () in 7.294579267501831 sec 
Got data: () in 4.582106590270996 sec 
Got data: () in 4.365068674087524 sec 
相關文章
相關標籤/搜索