系統(tǒng)調(diào)優(yōu)

reference1: 鄒sir的rh442系統(tǒng)調(diào)優(yōu)課程

系統(tǒng)調(diào)優(yōu)

[TOC]

reference1: 鄒sir的調(diào)優(yōu)課程

推薦書目: <Linux服務(wù)器性能調(diào)整>

基本概念

<font color=#ff0000>調(diào)優(yōu)是一門黑色藝術(shù)</font>

調(diào)優(yōu)方法(由好到差):

<font color=#ff0000>架構(gòu) -> 硬件 -> 軟件配置(SQL調(diào)優(yōu))</font>

關(guān)閉不需要的服務(wù)

換算單位:

KB的單位: KiBi的單位 :
1000 1024
sosreport # 會在/tmp下生成報告文件

系統(tǒng)內(nèi)核幫助手冊:

# 軟件包: kernel-doc, 安裝好之后可在以下目錄查詢:
/usr/share/doc/kernel-doc-*/Documentation/
# 只有redhat7光盤無此包
grep -irn ip_forwrad 目錄 # 可利用此命令查你需要的參數(shù)在哪個文件中

如何監(jiān)控系統(tǒng)

1. iostat

yum whatprovides "*/sar"
yum -y install sysstat
iostat # 展示系統(tǒng)從開機到現(xiàn)在的統(tǒng)計信息(靜態(tài), 平均值且非實時), 包括CPU, 磁盤
  %user # 應(yīng)用程序所占的百分比
  %nice # 調(diào)整應(yīng)用程序的優(yōu)先級從而使CPU不停切換進程,消耗系統(tǒng)資源所占的百分比
  %system # 內(nèi)核所占的百分比
  %iowait # IO相關(guān)百分比
  %steal # 虛擬化所占百分比
  %idle # 空閑率
iostat.png
iostat_tps.png
tps kB_read/s kB_wrtn/s kB_read kB_wrtn
22 444 451 5963560 6060483
每秒傳輸?shù)膇o請求數(shù) 開機到現(xiàn)在的讀

從上面的表格中提供的數(shù)據(jù)可以計算出系統(tǒng)每個IO大小的平均值: ( 444 + 451 ) / 22 = 40, 根據(jù)此處計算出的結(jié)果可以獲得系統(tǒng)內(nèi)的IO是小IO (小于64K)還是大IO (大于64K), 從而進行對應(yīng)的調(diào)優(yōu)

# 實例1: 只顯示設(shè)備的統(tǒng)計信息
iostat -d 2 6

# 實例2: 顯示指定的磁盤sda和sdb
iostat -x sda sdb 2 6

# 實例3: 顯示制定設(shè)備的分區(qū)的統(tǒng)計信息
iostat -p sda 2 6

# 實例4:
iostat -k|-m # 單位

2. iotop

當(dāng)系統(tǒng)的%iowait值非常高時, 說明系統(tǒng)IO等待時間非常高, 此時可用iotop查看哪個程序?qū)е耰o負(fù)載高:

iotop # simple top-like I/O monitor
iotop.png
dd if=/dev/zero of=/tmp/test.txt bs=1M count=2048 oflag=direct
  # 此命令的if和of本身寫于內(nèi)存
  # oflag=direct 直接寫入磁盤
iotop(oflag=direct).png

3. 衡量硬盤的性能指標(biāo)

  • IOPS: 每秒處理的IO次數(shù)
    • 隨機的小IO一般用此參數(shù)衡量
    • 用途: 數(shù)據(jù)庫(OLTP, 聯(lián)機事務(wù)處理): 例如銀行的每次交易
  • 帶寬: 每秒處理的數(shù)據(jù)大小
    • 順序的大IO
    • 用途: 1. 備份數(shù)據(jù); 2. 視頻監(jiān)控

下為實例:

硬盤類型 IOPS/延遲 帶寬
SSD > 2000/1ms 100MB/s
15K HHD 200/10ms 30MB/s

4. sar

Collect, report, or save system activity information

可查看之前某個時刻和當(dāng)前時刻的系統(tǒng)信息, 此命令比較全面, 可以實時查看系統(tǒng)的cpu, 內(nèi)存, 磁盤, swap信息

alias sar='LANG=C sar' # 設(shè)置顯示的時間格式為24小時制
sar -u # 查看實時的cpu信息, 與iostat的不同之處在于iostat查看到的是開機到現(xiàn)在的 
sar_u.png
iostat -q # 查看隊列長度和1分鐘, 5分鐘, 15分鐘的平均負(fù)載
sar_q.png
sar -r # 查看內(nèi)存, 類似free -m
sar_r(free).png
sar -b 1 5 # 查看硬盤設(shè)備的實時io數(shù), 注意和iostat之間的區(qū)別, 首先單位就不一樣
sar_b.png
sar -S # 查看swap的信息
sar -d 1 5 # 顯示主次設(shè)備編號(利用ll /dev/sd* 可查看對應(yīng)關(guān)系)
sar -d -p 1 5 # 顯示對應(yīng)設(shè)備名的設(shè)備
sar -r -f /var/log/sa/sa08 # /etc/cron.d/sysstat文件里設(shè)置系統(tǒng)每隔10分鐘, 會將系統(tǒng)狀態(tài)記錄到/var/log/sa/sa${DATE}文件中, 但這些文件需要通過-f選項指定file才能查看, 以及在每天的23:53會執(zhí)行命令記錄系統(tǒng)狀態(tài)并記錄到/var/log/sa/sar${DATE}文件中, 這些文件通過less可以直接查看
sar -d -p -s 19:00:00 -e 19:40:00 -f /var/log/sa/sa14
  -s [hh:mm:ss] # start time
  -e            # end time
  -A            # 指定顯示系統(tǒng)的所有信息
sar -n DEV 1 5  # 查看network信息, DEV選項表是查看network devices信息
sar -u 1 5 -o /tmp/sar.data # 將cpu信息收集并存入/tmp/sar.data文件中, 查看時需用-f指定文件
time cp -r /etc/ /tmp # 計時
watch -n 1 free -m # 每秒監(jiān)視一次
vmstat # 查看進程, 內(nèi)存, swap, io, system, cpu的統(tǒng)計信息
bigmem 500 # 申請使用500M內(nèi)存

# top命令解釋:
cp -a /etc/ /tmp/ # 輸入命令后使用ctrl + z 暫停
top # 然后用top命令查看時會發(fā)現(xiàn)后臺的Tasks中會有一個stopped顯示, 就是剛才暫停的任務(wù)

5. pmstat

yum -y install pcp pcp-gui
# 安裝這兩個包時可能報錯: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2
# 解決方法: https://blog.51cto.com/dihuo/1568438
# 在/usr/share/yum-cli/yummain.py和/usr/lib64/python2.7/encodings/utf_8.py中加入三行
import sys
reload(sys)
sys.setdefaultencoding('gbk')

ssh root@ip -X # 讓ssh支持圖形化界面展示

6. gunplot

Queue Theory

<font color=#ff0000>根據(jù)下面的公式可以判斷系統(tǒng)的瓶頸在哪里!</font>

調(diào)優(yōu)思想的起源, 利特爾定律: L = A * W

  • L: 隊列長度, 系統(tǒng)有多少請求在等待

    • 隊列位于內(nèi)存的buffer中
      • 長: 消耗內(nèi)存, 但可重新整合IO, 然后寫入磁盤, 減少磁盤的尋道次數(shù)
      • 短: 優(yōu)化內(nèi)存, 但數(shù)據(jù)寫入磁盤時尋道次數(shù)多
  • A: 到達率, 每秒來的請求數(shù)

  • W: 等待時間, 每個請求需要多長時間處理

cat /proc/meminfo | grep Dirty # 查看內(nèi)存中的臟數(shù)據(jù)
sysctl -a | grep dirty # 其中有個內(nèi)核參數(shù): vm.dirty_expire_centisecs = 3000
                       # 用來設(shè)定臟數(shù)據(jù)的過期時長: 3000 (百分之一秒)
                       # 30s后內(nèi)存中的臟數(shù)據(jù)寫回磁盤, 可臨時將此值調(diào)大:
sysctl -w vm.dirty_expire_centisecs=6000
# 當(dāng)數(shù)據(jù)都是隨機的小IO時, 讓其充分整合以提升性能

# 如果要永久生效:
vi /etc/sysctl.conf
vm.dirty_expire_centisecs=6000 # 添加此項
sysctl -p # 重載配置文件: sysctl.conf和sysctl.d/*.conf

w = Q + S

  • Q: 隊列等待時間
  • S: 服務(wù)時間

類比與去銀行處理業(yè)務(wù): 整個等待時間W = 銀行排隊時間Q + 銀行業(yè)務(wù)人員處理的時間S

W = Q + ( T_sys + T_user )

  • T_sys: 內(nèi)核占用的時間 (打印機, 電腦特別慢)
  • T_user: 應(yīng)用程序占用的時間 (業(yè)務(wù)員對業(yè)務(wù)不熟練)
# 實例:
time cp -r /etc/ /data/
real 0m14.379s
user 0m0.003s
sys 0m0.541s
# T_sys + T_user = 0.544s, 那多的13.835s去哪里了呢? 多的時間其實是Q的時間

內(nèi)核模塊調(diào)優(yōu)

主要對以下目錄進行調(diào)優(yōu):

  • /proc: 主要是對內(nèi)核, 文件系統(tǒng), 進程, 網(wǎng)絡(luò)調(diào)優(yōu)
  • /sys: 主要是對設(shè)備, 驅(qū)動, 模塊的調(diào)優(yōu)

<font color=#ff0000>首先強調(diào)一點: 所有內(nèi)核模塊都必須匹配內(nèi)核版本! 內(nèi)核模塊對內(nèi)核版本非常敏感, 差一個小版本都不行!</font>

lsmod          # 查看系統(tǒng)當(dāng)前加載的模塊
modprobe 模塊名 # 加載模塊
modprobe -r 模塊名 # 卸載模塊
modprobe ext4
# 隨便在任意目錄下使用modprobe 模塊名加載模塊, 為什么能夠加載成功?
/lib/modules/$(uname -r)/modules.dep # 加載模塊時讀會取此文件中記載的模塊路徑
/boot/initrd-2.6.18-208.el5.img # ram disk, gzip格式壓縮的文件, 內(nèi)含驅(qū)動, 安裝系統(tǒng)時被讀到內(nèi)存
zcat initrd-...img | cpio -id # 可將此文件中的內(nèi)容解壓至當(dāng)前目錄
cpio # 將文件復(fù)制到存檔包, 也可以從存檔包中復(fù)制出文件
  -i # 解壓
  -d # 目錄
# 解壓后的lib/*.ko為各種驅(qū)動

<font color=#ff0000>8k: 如何將特定驅(qū)動添加到initrd中?</font>

# 1. 官網(wǎng)下載驅(qū)動
# 2. 編譯驅(qū)動: /lib/modules/$(uname -r)/kernel/下新建目錄, 然后build
# 3. 備份原有的/boot/initrd-2.6.18-208.el5.img文件
# 4. mkinitrd --with=lsi2008 --force /boot/initrd-2.6.18-208.el5.img 2.6.18-208.el5
                   # 模塊名                                         # 此處不可接絕對路徑, 
                                                                   # 且內(nèi)核版本要與上面編
                                                                   # 譯的驅(qū)動放置的內(nèi)核目
                                                                   # 錄是同一個才行

模塊參數(shù)調(diào)優(yōu) (parm)

# 系統(tǒng)真實放置模塊的位置:
/lib/modules/$(uname -r)/kernel/drivers/
lsmod ext4
# 模塊名               模塊大小  模塊使用次數(shù)  模塊描述
Module                  Size  Used by
ext4                  579979  0 
mbcache                14958  1 ext4
jbd2                  107478  1 ext4

modinfo ext4 # 查看模塊的詳細(xì)信息
# 部分模塊有一個參數(shù): parm, 可用于調(diào)優(yōu)
# redhat5有/etc/modprobe.conf, 可直接在此文件內(nèi)添加內(nèi)容:
options snd-card-0 index=0 # 調(diào)整模塊參數(shù)
# 但redhat6開始需要在/etc/modprobe.d/下新建*.conf文件, 用于調(diào)優(yōu)模塊參數(shù):
vi /etc/modprobe.d/st.conf
options st buffer_kbs=128 # 特別注意, 模塊名和參數(shù)不可以寫錯!
# 修改模塊參數(shù)后如何驗證參數(shù)生效?
# 方法一: 
# 修改后重載st模塊, 然后去/sys/目錄下查看參數(shù)是否生效
# 方法二:
modprobe --showconfig 模塊名

<font color=#ff0000>8k: 重建ram disk文件, 解決P2V問題</font>

  • P2V問題: 物理機遷移到虛擬機時系統(tǒng)無法啟動
# redhat5, 6
mkinitrd /boot/initrd-2.6.18-208.el5xen.img $(uname -r)

# redhat7
dracut --add-drivers "module1 module2 ..." /boot/initramfs-3.10.0-123.el7.x86_64.img $(uname -r)
  --add-drivers # 可添加模塊
# 如何查看redhat7的ram disk文件中的內(nèi)容:
/usr/lib/dracut/skipcpio /tmp/initramfs-...img | zcat | cpio -id

小白式系統(tǒng)調(diào)優(yōu) (redhat7)

tune: n,v 曲調(diào); 調(diào)整

/usr/lib/tuned/下有可調(diào)參數(shù)

yum -y install tuned
systemctl enable tuned && systemctl start tuned
tuned-adm list # 列出所有可以調(diào)優(yōu)的參數(shù)
tuned-adm profile throughput-performance # 系統(tǒng)調(diào)優(yōu), 選用throughput-performance
tuned-adm list # 馬上生效且重啟有效

自定義某些配置:

cd /usr/lib/tuned/
cp -r throughput-performance/ my442 # 新建自定義目錄
vi my442/tuned.conf # 修改配置你需要的參數(shù)
tuned-adm profile mu442 # 讓你配置的參數(shù)生效

系統(tǒng)資源限制調(diào)優(yōu)

# 編輯完limit.conf文件, 立即生效
rss - max resident set size (KB) # 常駐內(nèi)存(物理), 無法限制
as - address space limit (KB) # 虛擬內(nèi)存, 可做限制
# 用戶可自己調(diào)整限制至最大值: ulimit -n 20

Cgroup <==> Controller group

mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)

軟件包: libcgroup (redhat6默認(rèn)不裝, redhat7安裝)

redhat6中如何利用cgroup對系統(tǒng)資源做限制:
yum -y install libcgroup
/etc/init.d/cgconfig start # 服務(wù)啟動后系統(tǒng)就有/cgroup/這個目錄
  • 臨時生效:
# /cgroup/內(nèi)控制資源, 可在其內(nèi)新建目錄, 將需要控制的進程對應(yīng)的PID寫入新建目錄內(nèi)的tasks文件中
mkdir /cgroup/memory/{bigdata,rh442} # 想對bigdata, rh442的內(nèi)存做限制, 
                                     # 就在/cgroup/memory/目錄下新建目錄
echo 102400000 > /cgroup/memroy/rh442/memory.limit_in_bytes # 可通過此方式臨時對rh442組的
                                                            # 內(nèi)存做限制, 只能用100M內(nèi)存
echo $(pidof vsftpd) > /cgroup/memory/rh442/tasks # 將需對內(nèi)存做限制的進程的PID寫入rh442組
                                                  # 的tasks中, 這樣就對對應(yīng)進程做了限制
pmap PID # 查看進程使用內(nèi)存情況, 可以看到一個進程運行時一共需要的內(nèi)存
# 如何刪除內(nèi)存中的文件夾:
rmdir rh442
  • 永久生效: <font color=#ff0000>可對云, 虛擬機, docker等容器使用的資源做限制</font>
vi /etc/cgconfig.conf # 添加如下內(nèi)容:
group bigdata {       # bigdata為需要限制的組的組名, 名字可自定義, 可以創(chuàng)建多個group
    blkio {           # blkio為需要限制的內(nèi)容
        參數(shù) = "值";   # 可以限制的參數(shù)能在/cgroup/blkcio/目錄下找到
    }
    memory {
        參數(shù) = "值";
        memory.limit_in_bytes = "100M";
    }
}

/etc/init.d/cgconfig restart
# 注: 如果這樣配置后在/cgroup/memory/內(nèi)執(zhí)行重啟命令, 會報錯: Device or resource busy
# 故需要到其他無關(guān)目錄內(nèi)重啟, 才會成功
# 這樣配置以后重啟cgconfig服務(wù), 會在/cgroup/memory/目錄下創(chuàng)建文件夾bigdata和memroy, 
# 但還沒針對服務(wù)做限制, 因此還需進行下面步驟
vi /etc/cgrules.conf # 策略文件, 添加上述參數(shù)對應(yīng)的配置:
#用戶:命令 需要限制的內(nèi)容    組名
*:cp      blkio,memory   bigdata/redhat/ # group內(nèi)有子組時, 可在bigdata后面添加redhat
# 上面這行的含義為對所有用戶執(zhí)行cp命令時, 會使用bigdata內(nèi)關(guān)于memory和blkio做限制的參數(shù)
# 在/etc/cgconfig.conf對內(nèi)存做了100M的限制, 因此超出100M時不會執(zhí)行cp命令
*:bigmem              memory  bigdata/ # 命令最好是絕對路徑
*:/etc/init.d/vsftpd  memory  bigdata/ # 針對服務(wù)做限制

/etc/init.d/cgred restart
# 也可用以下命令重啟服務(wù):
service cgconfig restart
service cgred restart
redhat7中如何利用cgroup對系統(tǒng)資源做限制:

書本P98, P99

  • redhat7內(nèi)可針對服務(wù)或用戶做限制

軟件包: memload (類似于bigmem), 可用作測試內(nèi)存

memload 256: 單位M, 申請使用256M內(nèi)存

man system.resource-control # 查看可以用來限制的參數(shù)
/etc/systemd/system/ # 此目錄下針對服務(wù)做限制
/etc/systemd/user/    # 此目錄下針對用戶做限制
# 實例: 需限制nginx.service的內(nèi)存使用量為512M
cd /etc/systemd/system/
mkdir nginx.service.d # 新建需要限制的服務(wù)對應(yīng)的目錄
vi 00-limit.conf # 新建00-limit.conf文件, 添加以下內(nèi)容:
[service]
MemoryLimit=512M

systemctl daemon-reload # 然后重載以及重啟服務(wù), 限制即可生效
systemctl restart nginx

硬件監(jiān)控

CPU

基本概念:

  • 一個核就是一個cpu
  • 核與線程:
    • 單線程: 人腦處理任務(wù)
    • 多線程: 電腦處理2個任務(wù)
  • 隊列: 10個任務(wù)同時來

衡量cpu性能:

  • lscpu | grep BogoMIPS:

    • BogoMIPS: 5616.00

    • 每秒處理百萬指令集的數(shù)目, 5616 * 1000,000

  • lscpu | grep "L3 cache"

    • L3 cache: 6144K

cpu <-- FSB --> mem: cpu和內(nèi)存之間通過 FSB (前端總線) 交換數(shù)據(jù)

  • UMA: 一致性內(nèi)存訪問

  • NUMA: 非一致性內(nèi)存訪問, cpu和mem在同一個NUMA node中

    • 優(yōu): 減少前端總線的壓力
    • 缺: 開啟NUMA無法內(nèi)存復(fù)用
lscpu.jpg
  • L1: 一級緩存, 一般CPU的L1i和L1d具備相同的容量
    • L1d: 數(shù)據(jù)緩存 (Data Cache, D-Cache)
    • L1i: 指令緩存 (Instruction Cache, I-Cache)
  • L2: 二級緩存
  • L3: 三級緩存

為什么CPU緩存會分為一級緩存L1、L2前塔、L3懒熙?有什么意義?

  • Virtualization type: full (支持全虛擬化)
# 更加詳細(xì)的關(guān)于cpu的信息, 可以查看:
cat /proc/cpuinfo

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec arat spec_ctrl intel_stibp flush_l1d arch_capabilities
# flags: 支持的指令集, 如lm (long mode, 64bits), vmx (全虛擬化)

address sizes   : 43 bits physical, 42 bits virtual
# 支持 2^42 = 4TB 的物理內(nèi)存以及 2^42 = 4TB 的虛擬內(nèi)存

內(nèi)存

dmidecode # 查看內(nèi)存信息, 如條數(shù), 大小, 插槽, 頻寬, 電壓, 是否支持NUMA等
numactl # 設(shè)置cpu和內(nèi)存在哪個NUMA node中

存儲

SATA SAS SSD
容量 > >
性能 < <

常用RAID Level:

1 5 10
裝系統(tǒng) 分布式
  • RAID5:

    • 帶奇偶校驗的條帶化, 有寫懲罰
      
      • 大寫: > 一半, 讀整個分條, 寫回 P
      • 小寫: < 一半
    • 適用場景: 順序的大IO ( 如視頻監(jiān)控, 備份, OLAP )
  • RAID10:

    • 使用場景: 隨機的小IO ( 如數(shù)據(jù)庫OLTP, 事務(wù)型, 交易系統(tǒng) )
  • FC - SAN: 一般用于公司內(nèi)部業(yè)務(wù), 距離有限

  • IP - SAN: 熱備

網(wǎng)絡(luò)

  1. 網(wǎng)卡選型
  2. 組網(wǎng) ( GE/10GE/IB ) 40Gb/56Gb/100Gb
  3. 雙網(wǎng)卡綁定模式 ( mode = 0-6 ) 0: 輪循 1: 主備 4: LACP 6: 最佳, 計算最小負(fù)載, 然后分發(fā)數(shù)據(jù)包至最小負(fù)載那里
  4. VLAN
  5. 網(wǎng)卡是否支持虛擬化: 指令集: VT-d(直通模式, 運算在網(wǎng)卡中進行), VT-x, SR-IOV(單根IO虛擬化, 硬直通, 直通虛擬機網(wǎng)卡)
cat /var/log/dmesg # 記錄啟動時的硬件信息

dmesg | grep eth # 可用于判斷內(nèi)核是否識別網(wǎng)卡
[    2.698411] e1000 0000:02:01.0 eth0: (PCI:66MHz:32-bit) 00:0c:29:8d:4d:36 # mac地址
[    2.698423] e1000 0000:02:01.0 eth0: Intel(R) PRO/1000 Network Connection # 別名
     # 耗費時間
dmesg | grep sd # 查看硬盤信息
[    3.126098] sd 2:0:0:0: [sda] 419430400 512-byte logical blocks: (214 GB/200 GiB)
[    3.126170] sd 2:0:0:0: [sda] Write Protect is off

<font color=#ff0000>系統(tǒng)啟動時, 紅字之后的是服務(wù)和文件系統(tǒng)的信息 !!!</font>

生產(chǎn)環(huán)境中可能遇到的問題以及一些補充說明

書本P115:

系統(tǒng)啟動時顯示: [<fffff...f 8014ebaf>]kobject_add+0x170/0x196

<font color=#ff0000>一般是物理機的內(nèi)存不兼容或者硬件問題造成的.</font>

lscpu, lspci, lsusb

# getconf此命令一般用于將系統(tǒng)配置變量值寫入標(biāo)準(zhǔn)輸出, 本身是個ELF可執(zhí)行文件汹桦,也可以用于獲取系統(tǒng)信息
getconf -a | grep -i page # 查看系統(tǒng)內(nèi)存分頁大小
                          # 內(nèi)存頁: 內(nèi)存最小單元 (類比與block塊的大小), 本例為4K
PAGESIZE                           4096
PAGE_SIZE                          4096
  -a # 獲取全部系統(tǒng)信息
dmidecode --from-dump 文件名 > dmi.txt # 分析二進制文件
                                      # 可分析出L1, L2的大小, 注意內(nèi)核個數(shù)!

影響磁盤IO性能的因素

  • 機械硬盤:
    • 轉(zhuǎn)數(shù)
    • 尋道時間

存儲密度

<font color=#ff0000>分區(qū)號越低, 越靠近外環(huán)</font>

讀性能提升

讀預(yù)取 (順序讀):

  • 固定預(yù)取
  • 倍數(shù)預(yù)取
  • 智能預(yù)取
    • /sys/block/sda/queue/read_ahead_kb --> 4096 KB, 可調(diào)整此參數(shù)提升讀預(yù)取的大小
  • 不預(yù)取

寫性能提升

硬盤調(diào)優(yōu)的角度(可針對某塊硬盤):

  • 方法一: /sys/block/sda/queue/nr_requests 隊列長度
  • 方法二: /sys/block/sda/queue/scheduler 調(diào)度算法
    • noop [deadline] cfq, 中括號中為當(dāng)前使用的調(diào)度算法
    • 調(diào)整: echo noop > /sys/block/sda/queue/scheduler

調(diào)度算法:

  • deadline 最終期限

    • <font color=#ff0000>適合小IO和ext4文件系統(tǒng)</font>
  • noop 沒有任何調(diào)優(yōu)

    • <font color=#ff0000>存儲映射時無需調(diào)優(yōu)</font>
  • as 猜想時間

    • <font color=#ff0000>適合大IO和xfs文件系統(tǒng)</font>
  • cfg 給每個應(yīng)用不同大小

    iostat # 對一個程序設(shè)置或獲取I/O調(diào)度級別和優(yōu)先級
    ionice -p 1 # 查看PID為1的進程的I/O調(diào)度級別以及優(yōu)先級
    ionice -p 1 -c 1 -n 2 # 設(shè)置PID為1的進程為class1, nice值為2
    
  • -c參數(shù):

class 1 2 3
優(yōu)先級 > >
實時: 先進先出 輪循: n越小, 分到的時間片越多, 但每個進程都會輪到 空閑
  • -n參數(shù):
    • 0 - 7, 越小越重要, 優(yōu)先級越高

mailload.py 壓力測試工具

<font color=#ff0000>當(dāng)然也可以通過tuned.conf修改參數(shù)進行調(diào)優(yōu)</font>

進程管理和調(diào)度

ps axo %cpu,%mem,nice,psr
  nice # 查看進程的優(yōu)先級
  psr # 顯示程序與運行在哪個cpu上

優(yōu)先級:

  • 靜態(tài): 1 - 99, 數(shù)字越大, 優(yōu)先級越高
  • 動態(tài): 0 <=> 100 - 129 ( -20 - 19 )
chrt -p 1 # 實時查看PID為1的進程優(yōu)先級
pid 1's current scheduling policy: SCHED_OTHER
pid 1's current scheduling priority: 0

<font color=#ff0000>FIFO和RR謹(jǐn)慎使用, 因為一旦使用會將整個CPU占用 !!!</font>

  • SCHED_FIFO

    • 先進先出, first input first output, 優(yōu)先級 1 - 99
    • 優(yōu)先級高的會搶占cpu
    • chrt -f 10 dd if=/dev/zero of=/dev/null:實時設(shè)置FIFO且優(yōu)先級為10
  • SCHED_RR

    • 類似FIFO但有時間片的概念
    • chrt -r 20 dd if=/dev/zero of=/dev/null
    • 只有RR級別才會輪循, 優(yōu)先級越高, 分到的時間片越多
  • SHCED_OTHER

    • nice

    • renice

    • other如何獲得更長的時間片?

      • 方法一: 類似cgroup中的內(nèi)存管理去設(shè)置 CPUShares=128 (份額 = 2的倍數(shù)), 永久生效

      • 方法二: systemctl set-property httpd.service CPUShares=512, 臨時生效

# 如何對已運行的程序調(diào)整優(yōu)先級:
chrt -p 2420
chrt -p -f 10 2420 # 對PID為2420的進程調(diào)整優(yōu)先級為FIFO, 10

跟蹤系統(tǒng)和庫調(diào)用

系統(tǒng)調(diào)用

<font color=#ff0000>排錯時會用到 !</font>

strace -c ls -l # 計數(shù)每步的操作時間
    -c # count
strace -e read cp -r /etc/ /data/ # 查看read的具體操作
strace -p PID # 實時查看某程序的系統(tǒng)和庫的調(diào)用情況

庫調(diào)用

ltrace cp # 查看某個命令會調(diào)用哪些庫

減少磁盤訪問次數(shù)

  • VFS: 虛擬文件系統(tǒng), 對應(yīng)用而言, 只要調(diào)用驅(qū)動, 寫入數(shù)據(jù)就好了, 所以任何的文件系統(tǒng)對應(yīng)用來講都是VFS
tune2fs -l /dev/vda1 # 查看原數(shù)據(jù), 簡略
dumpe2fs /dev/vda1   #           詳細(xì)
# 可以看到元數(shù)據(jù)中由block group, 即分組的概念, 以此保證數(shù)據(jù)連續(xù)

<font color=#ff0000>8K: 超級塊損壞時如何修復(fù)? 一定要記得先卸載分區(qū)再修復(fù) !!!</font>

dd if=/dev/zero of=/dev/vda1 bs=1k count=20 # 模擬生產(chǎn)環(huán)境中超級塊損壞的情況, 此處為破壞超級塊

# 修復(fù)ext類型文件系統(tǒng):
# 方法一:
umount /dev/vda1
fsck -v /dev/vda1 # 一直yes
# 方法二:
umount /dev/vda1
e2fsck -b 98304 /dev/vda1 # 使用98304的超級塊來恢復(fù), 
                          # 特別注意, 不同的文件系統(tǒng), 超級塊的位置固定的

# 修復(fù)xfs類型文件系統(tǒng):
xfs_repair /dev/vda1

日志型文件系統(tǒng)

ext3/ext4/xfs/NTFS

  • 優(yōu): 減少開機掃描

  • 缺: 寫數(shù)增加( 兩次寫: 1. journal 2.inode )

外部日志區(qū)如何配置

條件:

  • (1) journal size =2^N < 400M
  • (2) 整個分區(qū)只能用于journal device, 不能用作其他
    • <font color=#ff0000>多個文件系統(tǒng)可以共用一個外部日志區(qū), 不過block size必須相同</font>
  • (3) journal block size 必須與源文件系統(tǒng)一致

現(xiàn)在有兩塊硬盤, sda1和sdb1, 需要將sdb1用作sda1的外部日志區(qū), 從而減少硬盤訪問次數(shù), 下面為配置方法:

# 1. 卸載文件系統(tǒng)
umount /dev/sda1
umount /dev/sdb1

# 2. 查看文件系統(tǒng)的block大小及日志位置
dumpe2fs /dev/sda1 | egrep -i (journal|size)

# 3. 在已存在的文件系統(tǒng)中刪除內(nèi)部日志
tune2fs -O ^has_journal /dev/sdb1

# 4. 創(chuàng)建一個擴展的日志設(shè)備
mke2fs -O journal_dev -b block_size /dev/sdb1

# 5. 更新文件系統(tǒng)的超級塊, 從而使用擴展的日志
tune2fs -j -J device=/dev/sdb1 /dev/sda1

cpu的IRQ均衡 (IRQ balance)

<font color=#ff0000>用來均衡cpu的訪問次數(shù), 但cpu的緩存效果會減弱</font>

  • 每個硬件都會對應(yīng)一個中斷號, 一般IRQ只會指向某一個cpu, 所以某個設(shè)備只會在使用對應(yīng)的cpu跑任務(wù), 即只在某個cpu上消耗資源
cat /proc/interrupts
interrupts.png
中斷號 CPU0 CPU1 CPU2 CPU3
19: 8417 0 0 0 IO-APIC-fasteoi eno16777736
cpu編號說明: 2^0=1 2^1=2 2^2=4 2^3=8
cat /proc/irq/19/smp_affinity # smp_affinity: 多處理器親緣
08                            # 說明只用了CPU3
cat /proc/irp/27/smp_affinity
20                            # 2^2 + 2^4 = 20, 使用了CPU2和CPU4

修改多處理器親緣:

echo 2 > /proc/irq/19/smp_affinity # 將多處理器親緣改為CPU1
echo 3 > /proc/irq/3/smp_affinity  # 改為使用CPU0和CPU1, f: 15

Tuning process affinity with taskset (不均衡)

  • 一般應(yīng)用程序運行的時候會在不同的cpu上來回切換: ps axo %cpu,%mem,psr
  • 優(yōu): 設(shè)置應(yīng)用程序運行在指定的某個cpu或某些cpu上, 提高緩存命中率, 從而提升性能
  • 缺: 不均衡的運行隊列會導(dǎo)致較長的等待時間, 一般用于NUMA架構(gòu)
taskset -p PID # 查看PID的進程運行在哪個cpu上
taskset -p 3 PID # 此處的3為16進制, 例如1, 2, 4, 8, f

cpu隔離

如何做cpu隔離, 實現(xiàn)某個cpu只運行特定程序?

# 1. 啟動時編輯/etc/grub.conf, 隔離cpu
isolcpus=cpu_number,cpu_number,... # 設(shè)定只使用某幾個cpu, 其他不用

# 2. 設(shè)定某個程序運行在特定cpu上
taskset -p cpu_number PID

# 3. 考慮調(diào)整IRQ親緣

cpu支持熱插拔

  • CPU0以外的cpu支持如拔插, 0號不支持的原因是因為它是啟動cpu
  • 支持熱拔插的前提: 硬件支持 (BIOS支持物理熱拔插)
  • 對NUMA系統(tǒng)非常有用
  • 熱拔插的操作后內(nèi)核會動態(tài)更新/proc/cpuinfo及其他文件內(nèi)的信息
  • see kernel-doc-*/Documentation/cpu-hotplug.txt
# 1. 查看cpu號
grep processor /proc/cpuinfo
cat /proc/interrupts

# 2.動態(tài)關(guān)閉某個cpu, 如cpu1
echo 0 > /sys/devices/system/cpu/cpu1/online # online: 相當(dāng)于一個開關(guān)
cat /proc/interrupts # 關(guān)閉后無法看到cpu1的信息

# 3. 重開cpu1
echo 1 > sys/devices/system/cpu/cpu1/online
cat /proc/interrupts # 再次可以看到cpu1的信息

注: cpu1在被關(guān)閉時已有程序在上面運行, 關(guān)閉時其上的程序會被遷移到其他cpu, 不會影響原來程序的運行, 就算指定某程序在cpu1上運行, 當(dāng)cpu1被關(guān)閉時, 該程序依舊不會受到影響, 同樣會被遷移到其他cpu上, 但cpu1再次被開啟時, 原來指定的程序不會再次回到cpu1上運行

調(diào)度域 (scheduler domains)

  • cpuset: 進程組, 支持多核和NUMA架構(gòu)

  • /sys/fs/cgroup/cpuset/

cat /proc/filesystem | grep cpuset # 可以看到有種特殊的vfs: cpuset
nodev cpuset

mkdir /cpuset
mount -t cpuset nodev /cpuset/
cd /cpuset/; ls
cat cpuset.cpus
0-3       # 包含的cpu號
cat cpuset.mems
0         # 包含的內(nèi)存zone
cat tasks # 包含的所有任務(wù)

此架構(gòu)用于NUMA特別方便:

mkdir {rh442,cl210}
echo 0-1 > rh442/cpuset.cpus # 每個cpuset至少包含一個cpu和一個內(nèi)存zone
echo 0 > rh442/cpuset.mems
echo 2-3 > cl210/cpuset.cpus # cpuset支持嵌套, 故可將 2-3 改為 0-1
echo 0 > cl210/cpuset.mems

# 關(guān)閉cpu嵌套, 注意需要先關(guān)閉根cpuset的嵌套才有效
echo 1 > /cpuset/cpuset.cpu_exclusive

可將指定程序運行在NUMA node中:

systemctl start vsftpd
echo $(pidof vsftpd) > /cpuset/rh442/tasks

查看某程序運行在哪個cpuset中, 以vsftpd為例:

cd /proc/$(pidof vsftpd)
cat cpuset # 查看到結(jié)果為/rh442
cd /proc/1
cat cpuset # 查看到結(jié)果為/, 根cpuset包含所有系統(tǒng)資源

內(nèi)存管理(地址和分配)

  • 虛擬內(nèi)存
    • 應(yīng)用程序申請的內(nèi)存 (按需分配)
    • 應(yīng)用程序申請?zhí)摂M內(nèi)存時時, 總認(rèn)為<font color=#ff0000>每一個程序都有一段線性的, 連續(xù)的地址空間, 但實際映射到的物理內(nèi)存上是不連續(xù)的</font>
    • 地址范圍從0到最大值
    • 32bits架構(gòu)的系統(tǒng), 內(nèi)存最大支持 2^32 = 4GB
    • 64bits架構(gòu)的系統(tǒng), 內(nèi)存最大支持 2^48 = 256TB, 但由于內(nèi)核與硬件的限制, 實際只支持到 2^42 = 4TB
    • 用內(nèi)存頁來表示
  • 物理內(nèi)存
    • 物理內(nèi)存 = 內(nèi)存 + swap, 即 96G = 64G + 32G
      • swap上的數(shù)據(jù)只做暫存, 不作處理
    • cpu的內(nèi)存管理單元 MMU: 負(fù)責(zé)管理虛擬內(nèi)存與物理內(nèi)存之間的映射關(guān)系
ps aux | less # 可以查看到虛擬內(nèi)存VSZ和物理內(nèi)存RSS的使用情況
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0 193580  6584 ?        Ss    2018  17:55 /usr/lib/systemd/systemd --system --deserialize 20
root          2  0.0  0.0      0     0 ?        S     2018   0:09 [kthreadd]
root          3  0.0  0.0      0     0 ?        S     2018   0:25 [ksoftirqd/0]
root      73900  0.0  0.0 918368 32492 ?        Ssl  May24   0:30 PM2 v3.0.0: God Daemon (/root/.pm2)
root      86904  0.0  0.0 157860  2424 ?        S    Apr23   0:00 top
bigmem -v 500 # 申請使用500MB虛擬內(nèi)存
watch -n 1 'cat /proc/meminfo | grep AS' # AS:地址空間
  • PTE: 頁表條目 (page table entries)
    • 記錄虛擬內(nèi)存到物理內(nèi)存的映射關(guān)系
  • TLB: 記錄PTE內(nèi)映射關(guān)系的緩存
    • Hugepage (大頁): 用于存放TLB的緩存數(shù)據(jù)
      • cat /proc/meminfo | grep -i huge
      • bigmem -H NUM: -H, 指定使用Hugepage, 此命令可用作測試大頁
      • 一旦分配了大頁, 其他應(yīng)用程序無法申請到大頁使用的內(nèi)存

內(nèi)存架構(gòu)

x86, 即32bits的系統(tǒng)上:

1024M, 具體分配如下 物理內(nèi)存的第一個GB分配給內(nèi)核使用 (直接映射內(nèi)存)
128M 高位內(nèi)存, 用于存放PTE
896M, 包括下面的1M和16M和879M
1M 給BIOS和IO設(shè)備使用
16M 給DMA (直接內(nèi)存訪問) 使用
879M 低位內(nèi)存

x86_64, 及64bits的系統(tǒng)上:

128T 系統(tǒng)使用
128T 應(yīng)用使用

頁中斷 (page fault)

ps axo pid,comm,minflt,majflt
PID   COMMAND         MINFLT MAJFLT
53399 sshd              6937      0
53401 sftp-server       1444      0
66588 snmpmagt           637      0
66872 PatrolAgent     1739153756  0
66987 pukremotexec.xp    273      0
73900 PM2 v3.0.0: God 107465      0
  • 次頁中斷
    • 由物理內(nèi)存分配
  • 主頁中斷
    • 由swap分配
    • 主頁中斷越多, 系統(tǒng)性能越差

頁:

(1) dirty page: 內(nèi)存中已被修改, 還未寫入磁盤的數(shù)據(jù), 可用sync命令將drity page的數(shù)據(jù)寫入磁盤

(2) clean page: free -m中的caches, 以寫入磁盤, 但是作為緩存, 提升讀性能的數(shù)據(jù)

生產(chǎn)環(huán)境中一個特別有用的參數(shù): <font color=#ff0000>vm.swappiness</font>

vm.swappiness默認(rèn)值的范圍在: 0 - 100

  • 此值越高, 越多的使用swap
  • 此值越低, 越多的使用內(nèi)存
sysctl -a | grep swappiness
vm.swappiness = 30

生產(chǎn)環(huán)境中, 若swap使用過多, 如何更多的使用內(nèi)存, 減少swap的使用量:

# 方法一: 臨時生效
sysctl -w vm.swappiness=20
# 方法二: 永久生效
vi /etc/sysctl.conf
vm.swappiness = 20

sysctl -p

如果需要清空swap中的緩存, 該怎么做?

# 先看看當(dāng)前swap和內(nèi)存的使用情況: 如果swap使用量已經(jīng)超過內(nèi)存的空閑量, 則無法被清空!
swapon -s
Filename                                Type            Size    Used    Priority
/dev/sda1                               partition       8257532 8257532 -1

swapoff /dev/sda1 # 一定要注意, 生產(chǎn)環(huán)境中千萬不要隨便去卸載swap!!!
watch -n 1 'free -m'

擴展swap

一些概念:

  • 冷數(shù)據(jù), anon (匿名頁, 可用命令pmap查看) 都會大量放于swap中.

  • 一般內(nèi)存越大, swap也分配的越大, 因為內(nèi)存中的冷數(shù)據(jù)也越多.

如何提升swap的性能:

  • 將swap分到不同的硬盤上
  • 分配分區(qū)號小的分區(qū), (分區(qū)號越小, 越靠近外圈, 磁頭每轉(zhuǎn)過一圈讀取到的數(shù)據(jù)越多)

方法一: 使用硬盤分區(qū)

<font color=#ff0000>注: swap分區(qū)Priority的值越大, 優(yōu)先級越高, 越先被使用!</font>

# (1) 先在不同的兩塊硬盤上都分出1個分區(qū), 都用作swap
fdisk /dev/sdb # 分出/dev/sdb1
fdisk /dev/sdc # 分出/dev/sdc1

# (2) 然后格式化
mkswap /dev/sdb1
mkswap /dev/sdc1

# (3) 編輯/etc/fstab, 注意調(diào)整各自的優(yōu)先級, 做到均衡使用兩個分區(qū)的swap (即輪循)
vi /etc/fstab # UUID可用命令blkid查看
UUID="..." swap swap defaults,pri=-2 0 0
UUID="..." swap swap defaults,pri=-2 0 0

方法二: 使用文件

RHCE課程中已學(xué)過, 此處不再贅述.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子臊泰,更是在濱河造成了極大的恐慌,老刑警劉巖蚜枢,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缸逃,死亡現(xiàn)場離奇詭異,居然都是意外死亡厂抽,警方通過查閱死者的電腦和手機需频,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筷凤,“玉大人昭殉,你說我怎么就攤上這事∶晔兀” “怎么了挪丢?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卢厂。 經(jīng)常有香客問我乾蓬,道長,這世上最難降的妖魔是什么慎恒? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任任内,我火速辦了婚禮,結(jié)果婚禮上巧号,老公的妹妹穿的比我還像新娘族奢。我一直安慰自己,他們只是感情好丹鸿,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布越走。 她就那樣靜靜地躺著镰惦,像睡著了一般稠诲。 火紅的嫁衣襯著肌膚如雪放妈。 梳的紋絲不亂的頭發(fā)上因妙,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天,我揣著相機與錄音骡澈,去河邊找鬼锅纺。 笑死,一個胖子當(dāng)著我的面吹牛肋殴,可吹牛的內(nèi)容都是我干的囤锉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼护锤,長吁一口氣:“原來是場噩夢啊……” “哼官地!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烙懦,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤驱入,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后氯析,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亏较,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年掩缓,在試婚紗的時候發(fā)現(xiàn)自己被綠了雪情。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡拾因,死狀恐怖旺罢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绢记,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布正卧,位于F島的核電站蠢熄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏炉旷。R本人自食惡果不足惜签孔,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窘行。 院中可真熱鬧饥追,春花似錦、人聲如沸罐盔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捏顺,卻和暖如春六孵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背幅骄。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工劫窒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拆座。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓主巍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挪凑。 傳聞我的和親對象是個殘疾皇子煤禽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容