Linux刪文件力度過(guò)大導(dǎo)致IO占用太高的解決方案
前兩天剛找到刪文件性能比較OK的方式后,測(cè)試沒(méi)啥問(wèn)題就在生產(chǎn)環(huán)境開(kāi)始操練了, 雖然文件是在持續(xù)刪除著,但是跑了一段時(shí)間以后,執(zhí)勤同事找我說(shuō)IO滿了,問(wèn)我是不是做了啥,我上去一看還真是,然后讓我先停了:

但是文件也不能不刪,腳本還是要跑,基于這個(gè)問(wèn)題,看看怎么樣控制IO又能夠持續(xù)做文件清理。
現(xiàn)象描述
先詳細(xì)描述一下問(wèn)題的現(xiàn)象,我在上午9點(diǎn)左右把腳本起來(lái)以后,觀察了一會(huì)任務(wù)執(zhí)行,發(fā)現(xiàn)沒(méi)啥問(wèn)題就做別的事情了,讓腳本一直在服務(wù)器運(yùn)行,大概中午的時(shí)候,找到我說(shuō)IO太高了,讓我看下,然后看IO升高和我的腳本基本是同一時(shí)間開(kāi)始的,監(jiān)控圖如下,我11:30左右把腳本完全停了以后,IO就沒(méi)有再這么高了:

問(wèn)題分析
我在之前的一篇文章中說(shuō)到相比較而言,文件清理最快的方式是find + delete的方式,這也是我選擇的文件清理方式,但是問(wèn)題就在于,使用find . -mtime +3 -type f -delete這種命令我沒(méi)法在腳本這一層對(duì)他的刪除做限制,比如刪除1000個(gè)文件休眠5秒。
這個(gè)時(shí)候想到用nice這些命令對(duì)進(jìn)程優(yōu)先級(jí)做限制,嘗試限制IO的占用;或者在perl腳本中做限制,兩種方法應(yīng)該都是可行的,主要是在實(shí)際使用上是不是會(huì)有差異;
處理過(guò)程
nice命令限制優(yōu)先級(jí)
可以使用man nice查看nice命令的使用方式,還是比較簡(jiǎn)單的:

nice命令只有一個(gè)參數(shù)-n,用來(lái)指定要設(shè)置的優(yōu)先級(jí),可選范圍在-20到19,數(shù)字越大優(yōu)先級(jí)越低(看到一個(gè)比較有意思的理解:nice代表這個(gè)人是個(gè)好人,越nice人約好,他就越謙讓,所以優(yōu)先級(jí)越低:D)
在啟動(dòng)清理命令之前加上nice -n 19就能直接指定優(yōu)先級(jí)運(yùn)行了,如下:
nice -n 19 find . -mtime +3 -type f -delete

根據(jù)監(jiān)控來(lái)看,似乎并沒(méi)有什么用,使用top命令看了下,優(yōu)先級(jí)是生效了的,看來(lái)這個(gè)方法不奏效。

ionice命令限制
另一個(gè)查到的方法是ionice,這個(gè)命令貌似可以直接對(duì)IO的調(diào)度策略和優(yōu)先級(jí)做限制,使用man ionice可以看到命令的詳細(xì)用法:

簡(jiǎn)單介紹下:
| 參數(shù) | 作用 | 取值 | 描述 |
|---|---|---|---|
| -c, --class | 調(diào)度類(lèi),調(diào)度方式 | 0,1,2,3 | 0對(duì)應(yīng)none,1對(duì)應(yīng)realtime,2對(duì)應(yīng)best-effort,3對(duì)應(yīng)idle |
| -n | 對(duì)應(yīng)調(diào)度類(lèi)下的級(jí)別 | 0-7 | 只對(duì)realtime和best-effort有效 |
| -p | 指定PID | pid號(hào) | 指定要做調(diào)整的進(jìn)程pid,如果是執(zhí)行命令,那就直接帶上命令就可以 |
關(guān)于調(diào)度策略的解釋:
idle:當(dāng)沒(méi)有其他進(jìn)程請(qǐng)求磁盤(pán)I/O時(shí),才會(huì)進(jìn)行磁盤(pán)IO,也就是說(shuō)最后考慮;realtime:對(duì)磁盤(pán)進(jìn)行優(yōu)先訪問(wèn),也就是說(shuō)進(jìn)程的IO請(qǐng)求會(huì)被優(yōu)先處理;best-effort:該調(diào)度策略取值為0-7,數(shù)值越低,優(yōu)先級(jí)越高,內(nèi)核2.6.26之前,使用none等同于使用best-effort
具體的可以搜下IO的CFQ調(diào)度算法了解下,這里不展開(kāi)討論了;
隨后測(cè)試了一下ionice的控制:
ionice -c 2 -n 7 find . -mtime +3 -type f -delete

感覺(jué)還是沒(méi)太大作用,IO還是會(huì)打到100%,也可能是技藝不精,沒(méi)找對(duì)方法;看樣子只有自己在腳本里做控制了;
改造perl腳本
實(shí)在沒(méi)有辦法了,只有在我的清理腳本里做控制,把find方式換成了perl腳本,然后做了一層控制:
#!/usr/bin/perl
use File::Find;
use File::Spec;
my $path="xxx";
opendir DH, $path or die "cannot chdir to $path : $!";
for my $p (readdir DH) {
my $idle=0; # 已刪除的文件數(shù),初始化為0
my $sleep_time=5; # 休眠時(shí)間5秒
next if $file eq "." or $file eq "..";
my $sonpath=File::Spec->catdir($path,$p);
opendir SH, $sonpath or die "cannot chdir to $sonpath : $!";
for my $file (readdir SH) {
next if $file eq "." or $file eq "..";
next if $file =~ /^\./;
my $abspath=File::Spec->catdir($sonpath,$file);
my @s=stat("$abspath");
if ((time()-$s[8]) > (60*60*24*2)){
print "delete file $abspath\n";
unlink $abspath;
$idle=$idle+1; # 完成文件的清理后
if ($idle>=500){
print "finish delete $idle files, will sleep $sleep_time.\n";
$idle=0; # 當(dāng)刪除文件數(shù)達(dá)到500個(gè)的時(shí)候,手動(dòng)休眠
sleep($sleep_time);
}
}
}
closedir SH;
}
closedir DH;
接下來(lái)運(yùn)行腳本進(jìn)行清理:

再看監(jiān)控圖,終于是穩(wěn)定維持在一個(gè)水平了:

總結(jié)
雖然通過(guò)腳本的方式控制了文件清理對(duì)IO的占用,但是這算是沒(méi)辦法的辦法,若是能夠?qū)inux的IO調(diào)度策略再熟悉些,也許我能找到更好的辦法吧~
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Linux服務(wù)使用寶塔面板搭建網(wǎng)站并發(fā)布公網(wǎng)訪問(wèn)
寶塔面板作為簡(jiǎn)單好用的服務(wù)器運(yùn)維管理面板,它支持Linux/Windows系統(tǒng),本文我們將演示使用寶塔面板快速簡(jiǎn)單搭建本地web網(wǎng)站,并做內(nèi)網(wǎng)穿透,實(shí)現(xiàn)不在同個(gè)局域網(wǎng)下的用戶也可以訪問(wèn)到本地web站點(diǎn),無(wú)需公網(wǎng)IP,也不用設(shè)置路由器,需要的朋友可以參考下2023-08-08
LINUX中關(guān)于mkdir命令語(yǔ)法和實(shí)例解讀
Linux系統(tǒng)中,mkdir命令用于創(chuàng)建新的目錄,支持多種選項(xiàng)如權(quán)限設(shè)置、遞歸創(chuàng)建等,對(duì)于新手和管理員都非常有用,命令的靈活性可以通過(guò)各種選項(xiàng)來(lái)實(shí)現(xiàn)不同的功能,包括設(shè)置權(quán)限、創(chuàng)建多級(jí)嵌套目錄和處理隱藏目錄等,掌握mkdir命令對(duì)于提高Linux操作效率和管理文件系統(tǒng)至關(guān)重要2024-10-10
arm linux利用alsa驅(qū)動(dòng)并使用usb音頻設(shè)備
這篇文章主要介紹了arm linux利用alsa驅(qū)動(dòng)并使用usb音頻設(shè)備的相關(guān)資料,需要的朋友可以參考下2017-10-10

