1.度量性能php
持續地對性能進行度量在兩個方面有幫助。首先,度量能夠幫助瞭解性能趨勢,包括好壞兩方面的趨勢。做爲一個簡單的方法,查看一下 Web 服務器上的中央處理單元(CPU)使用率,就能夠了解 CPU 是否負載太重。一樣,查看過去使用的總帶寬並推斷將來的變化,能夠幫助判斷何時須要進行網絡升級。這些度量最好與其餘度量和觀測結合考慮。例如,當用戶抱怨應用程序太慢時,能夠檢查磁盤操做是否達到了最大容量。html
性能度量的第二個用途是,判斷調優是對系統性能有幫助,仍是使它更糟糕了。方法是比較修改以前和以後的度量結果。可是,爲了進行有效的比較,每次應該只修改一個設置,而後對適當的指標進行比較以判斷修改的效果。每次只修改一個設置的緣由應該是很明顯的:同時作出的兩個修改極可能會相互影響。選擇用來進行比較的指標比較微妙。mysql
選擇的指標必須可以反映應用程序用戶感受到的響應。若是一項修改的目標是減小數據庫的內存佔用量,那麼取消各類緩衝區確定會有幫助,可是這會犧牲查詢速度和應用程序性能。因此,應該選擇應用程序響應時間這樣的指標,這會使調優向着正確的方向發展,而不只僅是針對數據庫內存使用量。linux
(1).能夠以許多方式度量應用程序響應時間。最簡單的方法多是使用 curl 命令.web
1.使用curl度量 fix.weirenmai.dragon-stone.cn的響應時間redis
[root@web ~]# curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer}:%{time_total} http://www.baidu.com算法 0.004:0.882:1.393sql |
對 www.baidu.com執行curl命令,輸出一般是html代碼,經過 -o參數將html代碼發送到/dev/null。-s去除掉全部的狀態信息,-w參數是讓curl列出計時器的狀態信息:shell
curl使用的計時器:數據庫
time_connect |
創建到服務器的 TCP 鏈接所用的時間 (0.004) |
time_starttransfer |
在發出請求以後,Web 服務器返回數據的第一個字節所用的時間 (0.882) |
time_total |
完成請求所用的時間 (1.393) |
服務器創建tcp鏈接所用時間: 0.004s.
web服務器處理請求並開始返回數據所用的時間 : 0.882 - 0.004 = 0.878s.
客戶端從服務器下載數據所用的時間是: 1.393 - 0.882 = 0.511s.
經過觀察curl數據及其隨時間變化的趨勢,能夠很好的瞭解網站對用戶響應性.
(2).能夠經過uptime瞭解系統負載狀況
[root@web ~]# uptime 11:11:39 up 67 days, 1:30, 9 users, load average: 4.41, 4.40, 3.22 |
load average後的3個數字,分別表明系統最近一分鐘,五分鐘,十五分鐘的系統負載.
(3).使用sar監控系統(sar 主要負責收集,彙報與存儲系統運行信息)
1)經過sar -u輸出cpu使用狀況:
[root@web ~]# sar -u 1 3
Linux 2.6.32-220.el6.x86_64 (web.youlu.com.cn) 2013年02月18日 _x86_64_ (4 CPU)
11時38分59秒 CPU %user %nice %system %iowait %steal %idle
11時39分00秒 all 88.31 0.00 8.71 0.00 0.00 2.99
11時39分01秒 all 90.75 0.00 7.50 1.25 0.00 0.50
11時39分02秒 all 80.75 0.00 19.25 0.00 0.00 0.00
平均時間: all 86.61 0.00 11.81 0.42 0.00 1.16
1. 若 %iowait 的值太高,表示硬盤存在I/O瓶頸
2. 若 %idle 的值高但系統響應慢時,有多是 CPU 等待分配內存,此時應加大內存容量
3. 若 %idle 的值持續低於1,則系統的 CPU 處理能力相對較低,代表系統中最須要解決的資源是 CPU 。
2)經過sar -d 查看硬盤活動:
sar -d 10 3
Linux 2.6.32-220.el6.x86_64 (web.youlu.com.cn) 2013年02月18日 _x86_64_ (4 CPU)
11時55分16秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
11時55分26秒 dev8-0 3.30 0.00 69.67 21.09 0.02 7.09 6.55 2.16
11時55分26秒 dev8-16 3.20 0.00 69.67 21.75 0.02 6.69 6.16 1.97
11時55分26秒 dev8-32 16.32 108.91 146.55 15.66 0.09 5.48 3.50 5.72
11時55分26秒 dev8-48 15.42 8.81 146.55 10.08 0.07 4.86 3.03 4.66
1. avgqu-sz 的值較低時,設備的利用率較高。
2.當%util的值接近 1% 時,表示設備帶寬已經佔滿
3) 要判斷系統瓶頸問題,有時需幾個 sar 命令選項結合起來
1.懷疑CPU存在瓶頸,可用 sar -u 和 sar -q 等來查看
2.懷疑內存存在瓶頸,可用 sar -B、sar -r 和 sar -W 等來查看
3.懷疑I/O存在瓶頸,可用 sar -b、sar -u 和 sar -d 等來查看
(4) 使用top查看cpu,內存使用狀況:
Tasks: 219 total, 2 running, 217 sleeping, 0 stopped, 0 zombie
Cpu(s): 8.4%us, 0.8%sy, 0.0%ni, 90.3%id, 0.2%wa, 0.0%hi, 0.2%si, 0.0%st
Mem: 3853728k total, 3415984k used, 437744k free, 197692k buffers
Swap: 8388600k total, 350820k used, 8037780k free, 799716k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7605 root 20 0 212m 9352 3772 S 4.3 0.2 0:00.13 svn
12004 root 20 0 305m 9756 3216 S 1.3 0.3 27:26.98 php
9720 xufengqi 20 0 299m 13m 6440 S 1.0 0.4 1:16.80 php
12667 root 20 0 806m 9452 888 S 0.7 0.2 62:12.83 opportunity_rec
22854 root 20 0 147m 67m 664 S 0.7 1.8 194:47.15 redis-server
24161 mysql 20 0 2188m 45m 4172 S 0.7 1.2 295:30.25 mysqld
8744 zhusheng 20 0 340m 6392 2540 S 0.3 0.2 57:03.99 recommend_compa
1.輸入P查看系統cpu使用狀況.
2.輸入M查看系統內存使用狀況.
2. linux系統調優
大多數 Linux 發佈版都定義了適當的緩衝區和其餘 Transmission Control Protocol(TCP)參數。能夠修改這些參數來分配更多的內存,從而改進網絡性能。設置內核參數的方法是經過 proc 接口,也就是經過讀寫 /proc 中的值。幸運的是,sysctl 能夠讀取/etc/sysctl.conf 中的值並根據須要填充 /proc,這樣就可以更輕鬆地管理這些參數.
1).添加/etc/sysctl.conf中的參數
# Use TCP syncookies when needed
net.ipv4.tcp_syncookies = 1
# Enable TCP window scaling
net.ipv4.tcp_window_scaling: = 1
# Increase TCP max buffer size
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# Increase Linux autotuning TCP buffer limits
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Increase number of ports available
net.ipv4.ip_local_port_range = 1024 65000
將這些設置添加到 /etc/sysctl.conf 的現有內容中。
第一個設置啓用 TCP SYN cookie。當從客戶機發來新的 TCP 鏈接時,數據包設置了 SYN 位,服務器就爲這個半開的鏈接建立一個條目,並用一個 SYN-ACK 數據包進行響應。在正常操做中,遠程客戶機用一個 ACK 數據包進行響應,這會使半開的鏈接轉換爲全開的。有一種稱爲 SYN 氾濫的網絡攻擊,它使 ACK 數據包沒法返回,致使服務器用光內存空間,沒法處理到來的鏈接。SYN cookie 特性能夠識別出這種狀況,並使用一種優雅的方法保留隊列中的空間。大多數系統都默認啓用這個特性,可是確保配置這個特性更可靠。
第二個設置是啓用tcp窗口伸縮使客戶機可以以更高的速度下載數據。tcp容許在未從遠程端收到確認的狀況下發送多個數據包,默認設置最多使64k,在與延遲比較大的遠程機進行通信時這個設置是不夠。窗口伸縮會在頭中啓用更多的位,從而增長窗口大小
後面4個配置項是增長tcp發送和接收緩存區。這使得運用程序能夠更快丟掉它的數據,從而爲另外一個請求服務.還能夠強化遠程客戶機在服務器繁忙時發送數據的能力。
最後一個配置是增長可用的本地端口數量,這樣就增長了能夠同時服務的最大鏈接數量. 運行 sysctl -p /etc/sysctl.conf ,這樣設置就會生效
2)磁盤調優
磁盤在 LAMP 架構中扮演着重要的角色。靜態文件、模板和代碼都來自磁盤,組成數據庫的數據表和索引也來自磁盤。對磁盤的許多調優(尤爲是對於數據庫)集中於避免磁盤訪問,由於磁盤訪問的延遲至關高.
首先要在文件系統上禁用atime日誌記錄特性. atime是最近訪問文件的時間,每當訪問文件時,底層文件系統必須記錄這個時間戳。由於咱們不多使用atime,禁用它能夠減小磁盤的訪問時間. 禁用該特性的方法是,在/etc/fstab的第四列中添加noatime。
如何啓用 noatime 的 fstab 示例
/dev/mapper/VolGroup-lv_root / ext4 defaults,noatime 1 1
UUID=ba007d22-b42b-4b1e-9301-eec5535dffe1 /boot ext4 defaults,noatime 1 2
/dev/mapper/VolGroup-LogVol02 /opt ext4 defaults,noatime 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
上述修改了 ext4 文件系統,由於 noatime 只對駐留在磁盤上的文件系統有幫助。爲讓這一修改生效,不須要從新引導;只需從新掛裝每一個文件系統, 運行 mount / -o remount。
可使用 hdparm 命令查明和設置用來訪問 IDE 磁盤的方法。hdparm -t /path/to/device 執行速度測試,能夠將這個測試結果做爲性能基準。爲了使結果儘量準確,在運行這個命令時系統應該是空閒的.
在/dev/sda 上執行的速度測試
# hdparm -t /dev/sda
/dev/sda:
Timing buffered disk reads: 290 MB in 3.18 seconds = 91.27 MB/sec
這一測試說明,在這個磁盤上讀取數據的速度是大約每秒 91.27 MB。
3) I/O調優
在/etc/grub.conf中加入相應的I/O調度算法.
I/O調度算法總共有4種.
1.deadline算法 (適合小文件讀寫,跳躍式讀寫,零散讀寫,適合吞吐量很是大的運用)(數據庫)
2. anticipatory算法 (適合大文件讀寫,整塊式,重複讀寫) (web server)
3. cfg算法 (徹底公平算法)
4. noop算法 (沒有算法)
將I/o調度算法改成deadline算法.
echo deadline > /sys/block/sda/queue/scheduler
4)將訪問數超過150的ip加上防火牆
#!/bin/sh
status=`netstat -na|awk '5 ~ /[0-9]+:[0-9]+/ {print5}' |awk -F ":" -- '{print #1}' |sort -n|uniq -c |sort -n|tail -n 1`
NUM=`echo status|awk '{print1}'`
IP=`echo status|awk '{print2}'`
result=`echo "#NUM > 150" | bc`
if [ #result = 1 ]
then
echo IP:IPisoverIPisoverNUM, BAN IT!
/sbin/iptables -I INPUT -s #IP -j DROP
fi
將該shell腳本加入crontab中,5秒運行一次.
5)查看apache的併發請求數及其tcp鏈接狀態:
[root@weirenmai-dev ~]#netstat -nat|awk '{print $NF}'|sort|uniq -c|sort -n
1 established
1 State
3 LAST_ACK
4 FIN_WAIT2
11 SYN_SENT
14 LISTEN
19 CLOSE_WAIT
43 FIN_WAIT1
244 SYN_RECV
696 TIME_WAIT
1126 ESTABLISHED
上述參數的描述:
SYN_RECV : 表示正在等待處理的請求數.
ESTABLISHED : 表示正常數據傳輸狀態
TIME_WAIT : 表示處理完畢,等待超時結束的請求數。
3. apache調優
1)MPM(多處理模塊)配置(主要負責管理網絡鏈接,調度請求)
Apache有3個MPM,分別是: event , prefork和worker。
event這個MPM是在Apache2.4後纔有穩定版,比較適用於大量連續的狀況。event爲不一樣的任務使用單獨的線程池. KeepAlive的好處是,能夠同一個tcp鏈接中響應多個請求,這種方式,可使一個包含大量圖片和html文檔的請求加速50%,在Apache配置文件httpd.conf中設置KeepAlive設置爲On
prefork是一個非線程的MPM。它的特色:不快但很穩定.它可以隔離每一個請求,因此若是某個請求出現故障,不會影響其餘請求.使用prefork最重要的一個參數是MaxClients。這個MaxClients足夠大,這樣能夠在訪問高峯時發揮很好的性能,可是同時又不能太大,導致Apache所需內存超過物理內存
worker這個MPM,速度比prefork快不少,因爲使用多線程進行訪問處理,因此可以處理相對海量的請求,而系統資源的佔用要小於基於進程的服務器.work有2個比較重要的參數:ThreadPerChild和MaxClients.
ThreadPerChild是用來控制每一個子進程容許創建的線程數,
MaxClients用來控制容許創建的總線程數。
prefork MPM
<IfModule mpm_prefork_module]]>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 250
MaxConnectionsPerChild 0
</IfModule]]>
worker MPM
<IfModule mpm_worker_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
event MPM
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
經過/opt/apache/bin/httpd -l,咱們能夠看到咱們的使用是event MPM
<IfModule mpm_event_module>
ServerLimit 10000
StartServers 8
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 4000
MaxConnectionsPerChild 2000
</IfModule>
2)Apache其餘參數優化
1. ExtendedStatus Off 關閉對每一個請求鏈接的擴展狀態信息跟蹤.
2. KeepAlive On //使用keepalive能夠在單一鏈接時進行多個請求.
MaxKeepAliveRequests 0 //最大保持鏈接數, 0爲不限制.
KeepAliveTimeout 5 //每一個鏈接保持時間
3. HostnameLookups Off
//儘可能較少DNS查詢的次數。若是你使用了任何」Allow fromdomain」或」Denyfrom domain」指令(也就是domain使用的是主機名而不是IP地址),則代價是要進行兩次DNS查詢(一次正向和一次反向,以確認沒有做假)。因此,爲了獲得最高的性能,應該避免使用這些指令.
4.使用mod_deflat模塊,這個模塊能夠在用戶訪問網站時實時將內容進行壓縮,而後再傳給客戶端.因此mod_deflat能極大地加速網站,節約帶寬,固然壓縮須要花費cpu時間.
LoadModule deflate_module modules/mod_deflate.so
<ifmodule mod_deflate>
DeflateCompressionLevel 9
SetOutputFilter DEFLATE
#DeflateFilterNote Input instream
#DeflateFilterNote Output outstream
#DeflateFilterNote Ratio ratio
#LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
#CustomLog logs/deflate_log.log deflate
</ifmodule>
5.減小Timeout值 Timeout 30
6. UseCanonicalName on
打開UseCanonicalName是Web服務器的標準作法。這是由於客戶發送的大部分請求都是對本服務器的引用,打開該項設置就能使用 ServerName和Port選項的設置內容構建完整的URL。若是將這個參數設置爲Off,那麼Apache將使用從客戶請求中得到服務器名字和端口值,從新構建URL。
7. 取消符號鏈接 Options FollowSymLinks
FollowSymLinks容許使用符號鏈接,這將使用瀏覽器有可能訪問文檔根目錄(DocumentRoot)以外的內容,而且只有符號鏈接的目的與符號鏈接自己爲同一用戶所擁有時(SymLinksOwnerMatch),才容許訪問,這個設置將增長一些安全性,但將耗費Apache大量的資源。
4. php調優
1) 使用APC模塊(緩存opcodes)
安裝APC模塊
tar -zxvf APC-3.0.19.tar.gz
cd APC-3.0.19
/opt/php/bin/phpize
./configure
make
make install
APC模塊配置參數:
apc.enabled=1
apc.shm_segmemnts = 1
apc.shm_size = 64
APC把數據緩存到內存裏面,咱們就有必要對內存資源進行限定,經過這二個配置能夠限定APC可使用的內存空間大小。
apc.shm_segments指定了使用共享內存塊數,而apc.shm_size則指定了一塊共享內存空間大小,單位是M。因此,容許APC使用的內存大小應該是 apc.shm_segments * apc.shm_size = 64M。
apc.num_files_hint = 1000
apc.user_entries_hint = 4096
這二配置指定apc能夠有多少個緩存條目。apc.num_files_hint說明你估計可能會有多少個文件相應的opcodes須要被緩成,即大約能夠有多少個apc_compiler_cache條目。另外apc.user_entries_hint則說明你估計可能會有多少個apc_userdata_cache條目須要被緩存。若是項目中不使用apc_store()緩存用戶數據的話,該值能夠設定得更小。也就是說apc.num_files_hint與apc.user_entries_hint之和決定了APC容許最大緩存對象條目的數量。準確地設置這二個值能夠獲得最佳查詢性能.
apc.stat =1
apc.stat_ctime
這二個參數,只跟apc_compiler_cache緩存相關,並不影響apc_user_cache。apc_complier_cache,它緩存的對象是php源文件一一對應的opcodes(目標文件)。PHP源文件存放在磁盤設備上,與之相對應的Opcodes目標文件位置內存空間(共享內存),那麼當php源文件被修改之後,怎麼通知更新內存空間的opcodes呢?每次接收到請求後,APC都會去檢查打開的php源文件的最後修改時間,若是文件的最後修改時間與相應的內存空間緩存對象記錄的最後修改時間不一致的話,APC則會認爲存放在內存空間的Opcode目標文件(緩存對象)已通過期了,apc會將緩存對象清除而且保存新解析獲得的Opcode。咱們關心的是,即使沒有更新任何php源文件,每次接受到http請求後,APC都會請求系統內核調用stat()來獲取php源文件最後修改時。咱們能夠經過將apc.stat設置爲0,要求APC不去檢查Opcodes相對應的php源文件是否更新了。這樣能夠得到最佳的性能,咱們也推薦這麼作。不過,這樣作有一點很差的就是,一旦有PHP源文件更新了以後,須要重啓httpd守護進程或者調用apc_cache_clear()函數清空APC緩存來保證php源文件與緩存在內存空間的Opcodes相一致。
apc.ttl =0
apc.user_ttl =0
apc.ttl做用於apc_compiler_cache。當apc.ttl大於0時,每次請求都會對比此次的請求時間與上一次請求時間之差是否是大於apc.ttl,若是大於apc.ttl,則會被認緩存條目過時了,會被清理。
推薦若是項目較爲穩定,而且apc.stat設置爲0。同時apc.shm_size、apc.num_files_hint設置合理的話,apc.ttl建議設置爲0。即apc_compiler_cache永不回收,直到重啓httpd守護進程或者調用函數apc_cache_clear()清緩存。至於apc.user_ttl,建議設置爲0,由開發人員調用apc_store()函數的時候,設置#ttl來指定該緩存對象的生命週期。
apc.max_file_size = 1M
apc.filters = NULL
apc.cache_by_default=1
這三個配置放在一塊兒,是由於他們都用於限制緩存。其中apc.max_file_size表示若是php源文件超過了1M,則與之對應的opcodes不被緩存。而apc.filters指定一個文件過濾列表,以逗號(,)隔開。當apc.cache_by_default等於1時,與apc.filters列表中指定的文件名相匹配的文件不會被緩存。相反,apc.cache_by_default等於0時,僅緩存與acp.filters列表中指定的文件相匹配的文件。
2)使用xhprof模塊(性能分析工具)
xhprof安裝:
wget http://pecl.php.net/get/xhprof-0.9.2.tgz
tar zxf xhprof-0.9.2.tgz
cd xhprof-0.9.2
cp -r xhprof_html xhprof_lib /www/www.hx.com/xhprof/
cd extension/
/opt/php/bin/phpize
./configure –with-php-config=/opt/php/bin/php-config
make
make install
在php.ini中添加:
extension=xhprof.so
xhprof.output_dir=/opt/xhprof
xhprof的調用,在index.php中添加以下代碼:
if (#config->php->xhprof && mt_rand(1, 10000) == 1) {
xhprof_enable();
#xhprof_on = true;
}
if(config->php->xhprof &&xhprof_on){
#xhprof_data = xhprof_disable();
#xhprof_root = '/opt/xhprof'
include_once #xhprof_root."xhprof_lib/utils/xhprof_lib.php";
include_once #xhprof_root."xhprof_lib/utils/xhprof_runs.php";
#xhprof_runs = new XHProfRuns_Default();
runid=runid=xhprof_runs->save_run(#xhprof_data, "hx");
echo '<a href="http://www.test.com/xhprof_html/index.php?run='.#run_id.'&source=hx" target="_blank">統計信息</a>';
}
運行程序,底部出現統計信息字樣,點過去就能夠看到性能分析了。按運行時間排序,很容易找出花時間最長的函數。
Calls% |
IWall% |
EWall% |
||||
165 |
0.6% |
93,442 |
47.1% |
93,442 |
47.1% |
|
32 |
0.1% |
10,417 |
5.2% |
10,417 |
5.2% |
|
165 |
0.6% |
117,153 |
59.0% |
8,816 |
4.4% |
|
10 |
0.0% |
6,275 |
3.2% |
6,275 |
3.2% |
|
631 |
2.2% |
2,692 |
1.4% |
2,692 |
1.4% |
表格中一些參數的解釋:
5. mysql調優
加快mysql服務器的運行速度的方法,按照效率從低到高的依次爲:
1. 替換有問題的硬件
2. 對mysql進程的設置進行調優
3. 對查詢進行優化
1) 記錄慢查詢
在一個 SQL 服務器中,數據表都是保存在磁盤上的。索引爲服務器提供了一種在表中查找特定數據行的方法,而不用搜索整個表。當必需要搜索整個表時,就稱爲表掃描。一般來講,您可能只但願得到表中數據的一個子集,所以全表掃描會浪費大量的磁盤 I/O,所以也就會浪費大量時間。當必須對數據進行鏈接時,這個問題就更加複雜了,由於必需要對鏈接兩端的多行數據進行比較。
配置mysqld將這些慢查詢記錄到指定的慢查詢日誌中,經過查看慢查詢日誌能夠定位到可能有問題的sql語句.啓用慢查詢日誌需在my.cnf文件中添加以下設置.
[mysqld] ; enable the slow query log, default 10 seconds log-slow-queries=/opt/mysql/logs/mysql-slow.log ; log queries taking longer than 2 seconds long_query_time = 2 ; log queries that don't use indexes even if they take less than long_query_time ; MySQL 4.1 and newer only log-queries-not-using-indexes |
這3個設置一塊兒使用,能夠記錄執行時間超過2秒和沒有使用索引的查詢. 慢查詢日誌會存放在 /opt/mysql/logs/mysql-slow.log
閱讀慢查詢日誌使用mysqldumpslow的命令進行。指定日誌文件的路徑,就能夠看到一個慢查詢排序後的列表,而且顯示它們在日誌中出現的次數.一個很是有用的特性是mysqldumpslow在比較結果以前,會刪除任何用戶指定的數據,所以對同一個查詢的不一樣調用被記爲一次,這樣能夠找出工做量最多的查詢.
/opt/mysql/bin/mysqldumpslow -s c -t 20 mysql-slow.log //慢查詢中訪問次數最多的20條sql /opt/mysql/bin/mysqldumpslow -s r -t 20 mysql-slow.log //返回記錄結果集最多的20條sql |
-s. 是order的排序,分別按照query的次數,時間,lock時間和返回的記錄數來排序.
-t , 是top n 的意思,就是返回 前面多少條數據。
顯示結果以下:
Count: 1147605 Time=0.01s (7931s) Lock=0.00s (107s) Rows=0.0 (984), wcontact[wcontact]@[172.16.236.115]
select Fuid, Fcompany_id from relation_company where Ftime >= N and Ftime <= N order by Fuid limit N,N
Count: 108878 Time=0.03s (2792s) Lock=0.00s (5s) Rows=1.0 (108878), wcontact[wcontact]@2hosts
SELECT COUNT(*) FROM msg_index WHERE Fobj_uid=N AND Funread=N AND Fdel=N
Count: 23142 Time=0.04s (1012s) Lock=0.00s (1s) Rows=15.7 (363685), wcontact[wcontact]@[172.16.236.115]
select Fcompany_id, count(*) num from relation_company where Ftime > N and Ftime <= N group by Fcompany_id limit N,N
............ |
對相應的sql語句進行優化:
例如
SELECT COUNT(*) FROM msg_index WHERE Fobj_uid=N AND Funread=N AND Fdel=N |
表結構:
CREATE TABLE `msg_index` ( `Fid` int(11) NOT NULL AUTO_INCREMENT COMMENT '短消息編號', `Fmsg_id` int(11) NOT NULL DEFAULT '0' COMMENT '消息ID', `Fuid` bigint(20) NOT NULL DEFAULT '0' COMMENT '發送者UID', `Fobj_uid` bigint(20) NOT NULL DEFAULT '0' COMMENT '接收者UID', `Ftype` tinyint(3) NOT NULL DEFAULT '0' COMMENT '0發送 1接收', `Funread` tinyint(3) NOT NULL DEFAULT '0' COMMENT '新短消息', `Ftime` bigint(20) NOT NULL DEFAULT '0' COMMENT '發送時間', `Fdel` tinyint(3) NOT NULL DEFAULT '0' COMMENT '刪除狀態', PRIMARY KEY (`Fid`), KEY `ft` (`Fuid`,`Fobj_uid`), KEY `taf` (`Ftime`,`Ftype`) ) ENGINE=MyISAM AUTO_INCREMENT=163376 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC |
經過explain查看索引使用狀況
mysql> explain SELECT COUNT(*) FROM msg_index WHERE Fobj_uid=12 AND Funread=1 AND Fdel=0; +----+-------------+-----------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | msg_index | ALL | NULL | NULL | NULL | NULL | 3775 | Using where | +----+-------------+-----------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) |
能夠看到該sql語句未用到索引,致使了全表掃描. 故因將聯合索引 `ft`,拆分紅2個索引.
alter table msg_index drop index `ft`; alter table msg_index add index `Fuid`(`Fuid`); alter table msg_index add index `Fobj_uid`(`Fobj_uid`); |
2).對mysqld進程參數進行調優
1.對查詢進行緩存
在/opt/mysql/my.cnf添加以下的參數:
###query_cache### query_cache_size = 64M //啓用64M查詢緩存 query_cache_type = 1 query_cache_limit = 2M query_cache_min_res_unit = 4K |
啓用查詢緩存以後,看它是否有效使用:
mysql> show status like 'qcache%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Qcache_free_blocks | 7321 | | Qcache_free_memory | 33249712 | | Qcache_hits | 17036563 | | Qcache_inserts | 15195159 | | Qcache_lowmem_prunes | 3166865 | | Qcache_not_cached | 370185 | | Qcache_queries_in_cache | 28664 | | Qcache_total_blocks | 64727 | +-------------------------+----------+ 8 rows in set (0.00 sec) |
上表中一些變量的解釋:
Qcache_free_blocks |
緩存中相鄰內存塊的個數。數目大說明可能有碎片。FLUSH QUERY CACHE 會對緩存中的碎片進行整理,從而獲得一個空閒塊。 |
Qcache_free_memory |
緩存中的空閒內存。 |
Qcache_hits |
每次查詢在緩存中命中時就增大。 |
Qcache_inserts |
每次插入一個查詢時就增大。命中次數除以插入次數就是不中比率;用 1 減去這個值就是命中率。在上面這個例子中,大約有 87% 的查詢都在緩存中命中。 |
Qcache_lowmem_prunes |
緩存出現內存不足而且必需要進行清理以便爲更多查詢提供空間的次數。這個數字最好長時間來看;若是這個數字在不斷增加,就表示可能碎片很是嚴重,或者內存不多。(上面的free_blocks 和 free_memory 能夠告訴您屬於哪一種狀況)。 |
Qcache_not_cached |
不適合進行緩存的查詢的數量,一般是因爲這些查詢不是 SELECT 語句。 |
Qcache_queries_in_cache |
當前緩存的查詢(和響應)的數量。 |
Qcache_total_blocks |
緩存中塊的數量。 |
間隔幾秒顯示這些變量就能夠看出區別,這能夠幫助肯定緩存是否正在有效地使用。
2.強制限制
能夠在mysqld中強制來確保系統負載不會致使系統資源耗盡
max_connections = 800 wait_timeout = 15 max_connect_errors = 200 |
max_connections 是設置鏈接最大數,確保只創建服務器容許數目的鏈接.
肯定目前創建的最大鏈接數,能夠執行show status like 'max_used_connections'.
mysql> show status like 'max_used_connections'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | Max_used_connections | 26 | +----------------------+-------+ 1 row in set (0.00 sec) |
第 2 行告訴 mysqld 終止全部空閒時間超過 15 秒的鏈接。在 LAMP 應用程序中,鏈接數據庫的時間一般就是 Web 服務器處理請求所花費的時間。有時候,若是負載太重,鏈接會掛起,而且會佔用鏈接表空間。若是有多個交互用戶或使用了到數據庫的持久鏈接,那麼將這個值設低一點並不可取!
最後一行是一個安全的方法。若是一個主機在鏈接到服務器時有問題,並重試不少次後放棄,那麼這個主機就會被鎖定,直到 FLUSH HOSTS 以後才能運行。默認狀況下,10 次失敗就足以致使鎖定了。將這個值修改成 100 會給服務器足夠的時間來從問題中恢復。若是重試 100 次都沒法創建鏈接,那麼使用再高的值也不會有太多幫助,可能它根本就沒法鏈接。
3.表緩存.
數據庫中每一個表均可以表示爲磁盤上的一個文件,必須先打開,後讀取。爲了加快從文件中讀取數據,mysqld會對這些打開的文件進行緩存。其最大數目的是由/opt/mysql/my.cnf中的table_cache指定.
###表緩存 table_cache= 1024 |
顯示打開表的活動狀況:
mysql> show status like 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 287 |
| Opened_tables | 12 |
+---------------+-------+
2 rows in set (0.00 sec)
上述說明: 目前有287表是打開的,有12個表是須要打開的,由於緩存中已經沒有可用的文件描述符了。 若是Opened_tables隨着運行show status命令而快速增長時,說明緩存的命中率不夠.若是Opened_tables比table_cache設置小不少,就說明該值太大.
4. 線程的緩存
所說線程緩存,就是mysqld早接收鏈接時會根據須要生成線程.在一個鏈接變化很快的繁忙服務器上,對線程進行緩存有助於能夠加快最初的鏈接.
顯示線程使用的統計信息:
mysql> show status like 'threads%';
+-------------------+---------+
| Variable_name | Value |
+-------------------+---------+
| Threads_cached | 0 |
| Threads_connected | 68 |
| Threads_created | 1359226 |
| Threads_running | 1 |
+-------------------+---------+
上述中最重要的是 Threads_created值,每次mysqld須要建立一個新線程時,這個值都會增長。若是這個值隨着show status命令而快速增長,就應該嘗試增大線程緩存.
###線程緩存
Thread_cache 16
5.關鍵字緩存區(myisam)
關鍵字緩存區是保存myisam表的索引塊.在聯想狀況下,對於這些塊的請求應該來自於內存,而非磁盤.如何肯定有多少塊是從磁盤讀取,有多少塊是從內存讀取的.
mysql> show status like 'key_read%';
+-------------------+------------+
| Variable_name | Value |
+-------------------+------------+
| Key_read_requests | 2367514011 |
| Key_reads | 652489 |
+-------------------+------------+
2 rows in set (0.00 sec)
Key_reads表明命中磁盤的請求次數,key_read_requests是總數.命中磁盤的次數佔總數的 652489 /2367514011 = 0.0002756. 大約在1000個請求中有0.3次不會命中內存.若是該值(0.3)超過1時,就應該考慮增大關鍵字緩存區.key_buffer = 2G會將緩存區設置爲2G.
###MyISAM引擎參數###
key_buffer_size=2G
key_cache_block_size=1024
read_buffer_size=32M
read_rnd_buffer_size=32M
myisam_sort_buffer_size=2M
6.臨時表的使用
臨時表能夠在高級查詢中使用, 其中數據在進一步進行處理(group by )以前, 都必須先保存在臨時表中.理想狀況下,在內存中建立臨時表,若是臨時表變的太大,就須要寫入磁盤中.
mysql> show status like 'created_tmp%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_files | 746 |
| Created_tmp_tables | 0 |
+-------------------------+-------+
3 rows in set (0.00 sec)
每次使用臨時表都會增大 Created_tmp_tables;基於磁盤的表也會增大 Created_tmp_disk_tables。對於這個比率,並無什麼嚴格的規則,由於這依賴於所涉及的查詢。長時間觀察 Created_tmp_disk_tables 會顯示所建立的磁盤表的比率,您能夠肯定設置的效率。 tmp_table_size 和 max_heap_table_size 均可以控制臨時表的最大大小,所以請確保在 my.cnf 中對這兩個值都進行了設置。
優化查詢語句時候,要避免使用臨時表,若是避免不了的話,必定要保證臨時表存在內存中。若是你有不少group by語句,而且有不少內存的話,那就增大tmp_table_size和max_heap_table_size的值.
通常遵循的的公式:
Created_tmp_disk_tables/Created_tmp_tables<5%。
7.排序緩存區
當mysql進行排序時,就會在磁盤上讀取數據時分配一個緩存區來存放這些數據行.若是要排序的數據太大,那麼數據就要存放在磁盤上的臨時文件中,並再次進行排序。若是sort_merge_passes狀態量很大,這就指示磁盤的活動狀況.
mysql> SHOW STATUS LIKE "sort%";
+-------------------+---------+
| Variable_name | Value |
+-------------------+---------+
| Sort_merge_passes | 1 |
| Sort_range | 79192 |
| Sort_rows | 2066532 |
| Sort_scan | 44006 |
+-------------------+---------+
4 rows in set (0.00 sec)
若是sort_merge_passes很大.就表示要注意sort_buffer_size。 sort_buffer_size=16M將排序緩存區設置爲16M.
###排序緩存區
sort_buffer_size=16M
8.innodb參數
1) innodb_buffer_pool_size
對於innodb表來講,innodb_buffer_pool_size的做用就至關於key_buffer_size相對於myisam同樣.innodb使用該參數指定大小的內存來緩衝數據和索引.對於單獨的mysql數據庫服務器,最大能夠把該值設置成物理內存的80%。
2)innodb_additional_mem_pool_size
該參數指定Innodb用來存儲數據字典和其餘內部數據結構的內存池大小。缺省值爲1M。對於 2G內存的服務器推薦值爲 20M.
3)innodb_log_buffer_size
推薦值爲8M。
4)innodb_log_file_size
推薦值是 innodb_buffer_pool_size的25%.
5) innodb_flush_log_at_trx_commit
該值指定innodb記錄日誌的方式.若是設置爲1,則每一個事務提交的時候,mysql都會將事務日誌寫入磁盤.若是設置爲0或2,則每秒將日誌寫入磁盤一次.
6) innodb_file_per_table
將該值設置爲1時,則innodb表將使用獨立的表空間.
###Innodb引擎參數###
innodb_buffer_pool_size = 4G
innodb_additional_mem_pool_size = 20M
innodb_log_file_size = 256M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 100
innodb_open_files=800
innodb_file_per_table = 1
innodb_commit_concurrency = 4
3)使用mysqlreport調優性能
下載 :http://hackmysql.com/scripts/mysqlreport-3.5.tgz
解壓 tar zxf mysqlreport-3.5.tgz
./mysqlreport -user test -password test -port 3306
Can't locate DBI.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at ./mysqlreport line 24.
BEGIN failed--compilation aborted at ./mysqlreport line 24.
解決該錯誤 : sudo yum install perl-DBI perl-DBD-MySQL -y
使用mysqlreport
[root@WRM_DB01 mysqlreport-3.5]# perl mysqlreport --host=127.0.0.1 --user=test --password=test
__ Key _________________________________________________________________
Buffer used 295.49M of 24.00G %Used: 1.20
Current 4.78G %Usage: 19.91
Write hit 65.12%
Read hit 99.97%
__ Questions ___________________________________________________________
Total 45.03M 19.2/s
DMS 22.87M 9.7/s %Total: 50.79
QC Hits 17.39M 7.4/s 38.63
Com_ 3.53M 1.5/s 7.85
COM_QUIT 1.41M 0.6/s 3.13
-Unknown 178.89k 0.1/s 0.40
Slow 2 s 2.93M 1.3/s 6.52 %DMS: 12.83 Log: ON
DMS 22.87M 9.7/s 50.79
SELECT 15.89M 6.8/s 35.28 69.48
INSERT 3.80M 1.6/s 8.44 16.63
UPDATE 1.41M 0.6/s 3.14 6.18
REPLACE 938.06k 0.4/s 2.08 4.10
DELETE 827.92k 0.4/s 1.84 3.62
Com_ 3.53M 1.5/s 7.85
set_option 2.03M 0.9/s 4.50
change_db 1.01M 0.4/s 2.25
show_status 366.23k 0.2/s 0.81
__ SELECT and Sort _____________________________________________________
Scan 2.51M 1.1/s %SELECT: 15.81
Range 3.98M 1.7/s 25.05
Full join 14.74k 0.0/s 0.09
Range check 0 0/s 0.00
Full rng join 0 0/s 0.00
Sort scan 1.68M 0.7/s
Sort range 251.33k 0.1/s
Sort mrg pass 371 0.0/s
__ Query Cache _________________________________________________________
Memory usage 35.67M of 64.00M %Used: 55.73
Block Fragmnt 9.92%
Hits 17.39M 7.4/s
Inserts 15.49M 6.6/s
Insrt:Prune 4.81:1 5.2/s
Hit:Insert 1.12:1
__ Table Locks _________________________________________________________
Waited 3.36k 0.0/s %Total: 0.01
Immediate 24.70M 10.5/s
__ Tables ______________________________________________________________
Open 287 of 1024 %Cache: 28.03
Opened 893 0.0/s
__ Connections _________________________________________________________
Max used 26 of 800 %Max: 3.25
Total 1.41M 0.6/s
__ Created Temp ________________________________________________________
Disk table 3.57k 0.0/s
Table 927.74k 0.4/s Size: 16.0M
File 748 0.0/s
__ Threads _____________________________________________________________
Running 3 of 7
Cached 13 of 16 %Hit: 100
Created 32 0.0/s
Slow 0 0/s
__ Aborted _____________________________________________________________
Clients 34 0.0/s
Connects 333 0.0/s
__ Bytes _______________________________________________________________
Sent 18.91G 8.1k/s
Received 9.19G 3.9k/s
__ InnoDB Buffer Pool __________________________________________________
Usage 1.00M of 4.00G %Used: 0.02
Read hit 92.17%
Pages
Free 262.08k %Total: 99.98
Data 64 0.02 %Drty: 0.00
Misc 0 0.00
Latched 0.00
Reads 166 0.0/s
From file 13 0.0/s 7.83
Ahead Rnd 1 0.0/s
Ahead Sql 0 0/s
Writes 0 0/s
Flushes 0 0/s
Wait Free 0 0/s
__ InnoDB Lock _________________________________________________________
Waits 0 0/s
Current 0
Time acquiring
Total 0 ms
Average 0 ms
Max 0 ms
__ InnoDB Data, Pages, Rows ____________________________________________
Data
Reads 26 0.0/s
Writes 3 0.0/s
fsync 3 0.0/s
Pending
Reads 0
Writes 0
fsync 0
Pages
Created 0 0/s
Read 64 0.0/s
Written 0 0/s
Rows
Deleted 0 0/s
Inserted 0 0/s
Read 0 0/s
Updated 0 0/s
6. apache ab 壓力測試
/opt/apache/bin/ab -c 1000 -n 1000 http://www.baidu.com /
This is ApacheBench, Version 2.3 <Revision:655654Revision:655654>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking http://www.baidu.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: Apache/2.4.3
Server Hostname: http://www.baidu.com
Server Port: 80
Document Path: /
Document Length: 0 bytes
Concurrency Level: 1000 //併發數
Time taken for tests: 19.280 seconds //整個測試持續的時間
Complete requests: 1000 //完成的請求數
Failed requests: 0 //失敗的數量
Write errors: 0
Non-2xx responses: 1000
Total transferred: 669559 bytes // 整個傳輸量
HTML transferred: 0 bytes
//至關於 LR 中的每秒事務數,後面括號中的 mean 表示這是一個平均值
Requests per second: 51.87 [#/sec] (mean)
// 至關於 LR 中的平均事務響應時間,後面括號中的 mean 表示這是一個平均值
Time per request: 19279.633 [ms] (mean)
Time per request: 19.280 [ms] (mean, across all concurrent requests)
//平均每秒網絡上的流量,能夠幫助排除是否存在網絡流量過大致使響應時間延長的問題
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1699 3354.9 0 13403
Processing: 60 2356 2019.0 1918 15280
Waiting: 60 2354 2019.4 1918 15280
Total: 61 4055 4334.0 2584 19277
Percentage of the requests served within a certain time (ms)
50% 2584
66% 4267
75% 5154
80% 5807
90% 9886
95% 16438
98% 18259
99% 18298
100% 19277 (longest request)
整個場景中全部的用戶請求的響應情況,每一個請求都有一個響應時間,其中50%的用戶響應的時間小於2584ms,66%的用戶響應時間小於4267,最大的響應時間爲19277ms
優化後測試的結果:
[root@web ~]# /opt/apache/bin/ab -c 1000 -n 1000 http://www.baidu.com This is ApacheBench, Version 2.3 <Revision:655654Revision:655654> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking http://www.baidu.com (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests
Server Software: Apache/2.4.3 Server Hostname: http://www.baidu.com Server Port: 80
Document Path: / Document Length: 0 bytes
Concurrency Level: 1000 Time taken for tests: 11.070 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Non-2xx responses: 1000 Total transferred: 637429 bytes HTML transferred: 0 bytes Requests per second: 90.33 [#/sec] (mean) Time per request: 11070.237 [ms] (mean) Time per request: 11.070 [ms] (mean, across all concurrent requests) Transfer rate: 56.23 [Kbytes/sec] received
Connection Times (ms) min mean[+/-sd] median max Connect: 0 745 1929.5 0 9012 Processing: 529 2289 1451.9 1818 9833 Waiting: 529 2287 1451.8 1818 9833 Total: 544 3033 2312.3 2333 10987
Percentage of the requests served within a certain time (ms) 50% 2333 66% 3002 75% 3811 80% 4183 90% 6512 95% 8925 98% 10694 99% 10809 100% 10987 (longest request) |
根據測試結果進行對比 :
對於1000的併發數,總耗時從19.280s降低到11.070s
優化前:
Requests per second: 51.87 [#/sec] (mean)
Time per request: 19279.633 [ms] (mean)
Time per request: 19.280 [ms] (mean, across all concurrent requests)
Transfer rate: 33.91 [Kbytes/sec] received
優化後:
Requests per second: 90.33 [#/sec] (mean) Time per request: 11070.237 [ms] (mean) Time per request: 11.070 [ms] (mean, across all concurrent requests) Transfer rate: 56.23 [Kbytes/sec] received |
最能反應服務器性能的是 Request per second,即每秒完成的請求數從51.87提高到90.33。
每一個請求花費的時間從19.280ms降低到11.070ms.
每秒的網絡流流量從33.91Kbytes提高到56.23Kbytes.
參考文章:http://www.cnblogs.com/kristain/articles/4127381.html