塊設備塊緩存
① 深入理解EXT2文件系統實現原理
一 EXT2文件系統結構概覽
每一文件或目錄在磁碟上皆有inode管理自身屬性信息,數據塊存儲文件內容。inode與數據塊關聯如下圖所示:
小文件數據塊少於12個時,數據塊索引存放於inode中的'i_blocks',文件較大時,通過間接塊存儲超12個數據塊的索引。
二 塊緩存
塊緩存用於頁緩存與塊設備原始數據讀取。頁緩存中塊緩存與頁關聯,頁釋放時緩存釋放。獨立塊緩存由lru緩存管理,頁依附於塊緩存,緩存釋放頁隨之釋放。
三 EXT2文件系統掛載
注冊ext2文件系統類型,通過函數register_filesystem添加至全局鏈表。
獲取塊設備並分配super_block,讀取超級塊數據。
文件系統操作涉及讀寫邏輯,從文件位置偏移找到數據塊塊號,讀取映射塊數據。
塊映射由函數ext2_get_block實現,包含查找文件偏移位置、檢查數據塊映射、分配空閑塊等步驟。
塊分配由ext2_new_blocks函數完成,預分配邏輯中,初始化inode預分配窗口,查找空閑空間,設置數據塊點陣圖為1。
② 濡備綍鎻愰珮linux涓嬪潡璁懼嘔O鐨勬暣浣撴ц兘
鍓嶈█錛氭湰鏂囦富瑕佽茶ВLinux IO璋冨害灞傜殑涓夌嶆ā寮忥細cfp銆乨eadline鍜宯oop錛屽苟緇欏嚭鍚勮嚜鐨勪紭鍖栧拰閫傜敤鍦烘櫙寤鴻銆
IO璋冨害鍙戠敓鍦↙inux鍐呮牳鐨処O璋冨害灞傘傝繖涓灞傛℃槸閽堝筁inux鐨勬暣浣揑O灞傛′綋緋繪潵璇寸殑銆備粠read()鎴栬厀rite()緋葷粺璋冪敤鐨勮掑害鏉ヨ達紝Linux鏁翠綋IO浣撶郴鍙浠ュ垎涓轟竷灞傦紝瀹冧滑鍒嗗埆鏄錛
VFS灞傦細 鉶氭嫙鏂囦歡緋葷粺灞傘傜敱浜庡唴鏍歌佽窡澶氱嶆枃浠剁郴緇熸墦浜ら亾錛岃屾瘡涓縐嶆枃浠剁郴緇熸墍瀹炵幇鐨勬暟鎹緇撴瀯鍜岀浉鍏蟲柟娉曢兘鍙鑳戒笉灝界浉鍚岋紝鎵浠ワ紝鍐呮牳鎶借薄浜嗚繖涓灞傦紝涓撻棬鐢ㄦ潵閫傞厤鍚勭嶆枃浠剁郴緇燂紝騫跺瑰栨彁渚涚粺涓鎿嶄綔鎺ュ彛銆
鏂囦歡緋葷粺灞傦細 涓嶅悓鐨勬枃浠剁郴緇熷疄鐜拌嚜宸辯殑鎿嶄綔榪囩▼錛屾彁渚涜嚜宸辯壒鏈夌殑鐗瑰緛錛屽叿浣撲笉澶氳翠簡錛屽ぇ瀹舵効鎰忕殑璇濊嚜宸卞幓鐪嬩唬鐮佸嵆鍙銆
欏電紦瀛樺眰錛 璐熻矗鐪熷筽age鐨勭紦瀛樸
閫氱敤鍧楀眰錛 鐢變簬緇濆ぇ澶氭暟鎯呭喌鐨剗o鎿嶄綔鏄璺熷潡璁懼囨墦浜ら亾錛屾墍浠Linux鍦ㄦゆ彁渚涗簡涓涓綾諱技vfs灞傜殑鍧楄懼囨搷浣滄娊璞″眰銆備笅灞傚規帴鍚勭嶄笉鍚屽睘鎬х殑鍧楄懼囷紝瀵逛笂鎻愪緵緇熶竴鐨凚lock IO璇鋒眰鏍囧噯銆
IO璋冨害灞 錛氬洜涓虹粷澶у氭暟鐨勫潡璁懼囬兘鏄綾諱技紓佺洏榪欐牱鐨勮懼囷紝鎵浠ユ湁蹇呰佹牴鎹榪欑被璁懼囩殑鐗圭偣浠ュ強搴旂敤鐨勪笉鍚岀壒鐐規潵璁劇疆涓浜涗笉鍚岀殑璋冨害綆楁硶鍜岄槦鍒椼備互渚垮湪涓嶅悓鐨勫簲鐢ㄧ幆澧冧笅鏈夐拡瀵規х殑鎻愰珮紓佺洏鐨勮誨啓鏁堢巼錛岃繖閲屽氨鏄澶у悕榧庨紟鐨凩inux鐢墊鎵璧蜂綔鐢ㄧ殑鍦版柟銆傞拡瀵規満姊扮‖鐩樼殑鍚勭嶈皟搴︽柟娉曞氨鏄鍦ㄨ繖瀹炵幇鐨勩
鍧楄懼囬┍鍔ㄥ眰錛 椹卞姩灞傚瑰栨彁渚涚浉瀵規瘮杈冮珮綰х殑璁懼囨搷浣滄帴鍙o紝寰寰鏄疌璇璦鐨勶紝鑰屼笅灞傚規帴璁懼囨湰韜鐨勬搷浣滄柟娉曞拰瑙勮寖銆
鍧楄懼囧眰錛 榪欏眰灝辨槸鍏蜂綋鐨勭墿鐞嗚懼囦簡錛屽畾涔変簡鍚勭嶇湡瀵硅懼囨搷浣滄柟娉曞拰瑙勮寖銆
鏈変竴涓宸茬粡鏁寸悊濂界殑[Linux IO緇撴瀯鍥綸錛岄潪甯哥粡鍏革紝涓鍥捐儨鍗冭█錛
鎴戜滑浠婂ぉ瑕佺爺絀剁殑鍐呭逛富瑕佸湪IO璋冨害榪欎竴灞傘
瀹冭佽В鍐崇殑鏍稿績闂棰樻槸錛屽備綍鎻愰珮鍧楄懼嘔O鐨勬暣浣撴ц兘錛熻繖涓灞備篃涓昏佹槸閽堝規満姊扮‖鐩樼粨鏋勮岃捐$殑銆
浼楁墍鍛ㄧ煡錛屾満姊扮‖鐩樼殑瀛樺偍浠嬭川鏄紓佺洏錛岀佸ご鍦ㄧ洏鐗囦笂縐誨姩榪涜岀侀亾瀵誨潃錛岃屼負綾諱技鎾鏀句竴寮犲敱鐗囥
榪欑嶇粨鏋勭殑鐗圭偣鏄錛岄『搴忚塊棶鏃跺悶鍚愰噺杈冮珮錛屼絾鏄濡傛灉涓鏃﹀圭洏鐗囨湁闅忔満璁塊棶錛岄偅涔堝ぇ閲忕殑鏃墮棿閮戒細嫻璐瑰湪紓佸ご鐨勭Щ鍔ㄤ笂錛岃繖鏃跺欏氨浼氬艱嚧姣忔IO鐨勫搷搴旀椂闂村彉闀匡紝鏋佸ぇ鐨勯檷浣嶪O鐨勫搷搴旈熷害銆
紓佸ご鍦ㄧ洏鐗囦笂瀵婚亾鐨勬搷浣滐紝綾諱技鐢墊璋冨害錛屽疄闄呬笂鍦ㄦ渶寮濮嬬殑鏃舵湡錛孡inux鎶婅繖涓綆楁硶鍛藉悕涓篖inux鐢墊綆楁硶錛屽嵆錛
濡傛灉鍦ㄥ婚亾鐨勮繃紼嬩腑錛岃兘鎶婇『搴忚礬榪囩殑鐩稿叧紓侀亾鐨勬暟鎹璇鋒眰閮解滈『渚庫濆勭悊鎺夛紝閭d箞灝卞彲浠ュ湪姣旇緝灝忓獎鍝嶅搷搴旈熷害鐨勫墠鎻愪笅錛屾彁楂樻暣浣揑O鐨勫悶鍚愰噺銆
榪欏氨鏄鎴戜滑涓轟粈涔堣佽捐IO璋冨害綆楁硶鐨勫師鍥犮
鐩鍓嶅湪鍐呮牳涓榛樿ゅ紑鍚浜嗕笁縐嶇畻娉/妯″紡錛歯oop錛宑fq鍜宒eadline銆備弗鏍肩畻搴旇ユ槸涓ょ嶏細
鍥犱負絎涓縐嶅彨鍋歯oop錛屽氨鏄絀烘搷浣滆皟搴︾畻娉曪紝涔熷氨鏄娌℃湁浠諱綍璋冨害鎿嶄綔錛屽苟涓嶅筰o璇鋒眰榪涜屾帓搴忥紝浠呬粎鍋氶傚綋鐨剗o鍚堝苟鐨勪竴涓猣ifo闃熷垪銆
鐩鍓嶅唴鏍鎬腑榛樿ょ殑璋冨害綆楁硶搴旇ユ槸cfq錛屽彨鍋氬畬鍏ㄥ叕騫抽槦鍒楄皟搴︺傝繖涓璋冨害綆楁硶浜哄傚叾鍚嶏紝瀹冭瘯鍥劇粰鎵鏈夎繘紼嬫彁渚涗竴涓瀹屽叏鍏騫崇殑IO鎿嶄綔鐜澧冦
娉錛氳峰ぇ瀹朵竴瀹氳頒綇榪欎釜璇嶈錛宑fq錛屽畬鍏ㄥ叕騫抽槦鍒楄皟搴︼紝涓嶇劧涓嬫枃灝辨病娉曠湅浜嗐
cfq涓烘瘡涓榪涚▼鍒涘緩涓涓鍚屾IO璋冨害闃熷垪錛屽苟榛樿や互鏃墮棿鐗囧拰璇鋒眰鏁伴檺瀹氱殑鏂瑰紡鍒嗛厤IO璧勬簮錛屼互姝や繚璇佹瘡涓榪涚▼鐨処O璧勬簮鍗犵敤鏄鍏騫崇殑錛宑fq榪樺疄鐜頒簡閽堝硅繘紼嬬駭鍒鐨勪紭鍏堢駭璋冨害錛岃繖涓鎴戜滑鍚庨潰浼氳︾粏瑙i噴銆
鏌ョ湅鍜屼慨鏀笽O璋冨害綆楁硶鐨勬柟娉曟槸錛
cfq鏄閫氱敤鏈嶅姟鍣ㄦ瘮杈冨ソ鐨処O璋冨害綆楁硶閫夋嫨錛屽規岄潰鐢ㄦ埛涔熸槸姣旇緝濂界殑閫夋嫨銆
浣嗘槸瀵逛簬寰堝欼O鍘嬪姏杈冨ぇ鐨勫満鏅灝卞苟涓嶆槸寰堥傚簲錛屽挨鍏舵槸IO鍘嬪姏闆嗕腑鍦ㄦ煇浜涜繘紼嬩笂鐨勫満鏅銆
鍥犱負榪欑嶅満鏅鎴戜滑闇瑕佹洿澶氱殑婊¤凍鏌愪釜鎴栬呮煇鍑犱釜榪涚▼鐨処O鍝嶅簲閫熷害錛岃屼笉鏄璁╂墍鏈夌殑榪涚▼鍏騫崇殑浣跨敤IO錛屾瘮濡傛暟鎹搴撳簲鐢ㄣ
deadline璋冨害錛堟渶緇堟湡闄愯皟搴︼級灝辨槸鏇撮傚悎涓婅堪鍦烘櫙鐨勮В鍐蟲柟妗堛俤eadline瀹炵幇浜嗗洓涓闃熷垪錛
鍏朵腑涓や釜鍒嗗埆澶勭悊姝e父read鍜寃rite錛屾寜鎵囧尯鍙鋒帓搴忥紝榪涜屾e父io鐨勫悎騫跺勭悊浠ユ彁楂樺悶鍚愰噺銆傚洜涓篒O璇鋒眰鍙鑳戒細闆嗕腑鍦ㄦ煇浜涚佺洏浣嶇疆錛岃繖鏍蜂細瀵艱嚧鏂版潵鐨勮鋒眰涓鐩磋鍚堝苟錛屽彲鑳戒細鏈夊叾浠栫佺洏浣嶇疆鐨剗o璇鋒眰琚楗挎匯
鍙﹀栦袱涓澶勭悊瓚呮椂read鍜寃rite鐨勯槦鍒楋紝鎸夎鋒眰鍒涘緩鏃墮棿鎺掑簭錛屽傛灉鏈夎秴鏃剁殑璇鋒眰鍑虹幇錛屽氨鏀捐繘榪欎袱涓闃熷垪錛岃皟搴︾畻娉曚繚璇佽秴鏃訛紙杈懼埌鏈緇堟湡闄愭椂闂達級鐨勯槦鍒椾腑鐨勮鋒眰浼氫紭鍏堣澶勭悊錛岄槻姝㈣鋒眰琚楗挎匯
涓嶄箙鍓嶏紝鍐呮牳榪樻槸榛樿ゆ爣閰嶅洓縐嶇畻娉曪紝榪樻湁涓縐嶅彨鍋歛s鐨勭畻娉曪紙Anticipatory scheler錛夛紝棰勬祴璋冨害綆楁硶銆備竴涓楂樺ぇ涓婄殑鍚嶅瓧錛屾悶寰楁垜涓搴﹁や負Linux鍐呮牳閮戒細綆楀懡浜嗐
緇撴灉鍙戠幇錛屾棤闈炴槸鍦ㄥ熀浜巇eadline綆楁硶鍋歩o璋冨害鐨勪箣鍓嶇瓑涓灝忎細鏃墮棿錛屽傛灉榪欐墊椂闂村唴鏈夊彲浠ュ悎騫剁殑io璇鋒眰鍒版潵錛屽氨鍙浠ュ悎騫跺勭悊錛屾彁楂榙eadline璋冨害鐨勫湪欏哄簭璇誨啓鎯呭喌涓嬬殑鏁版嵁鍚炲悙閲忋
鍏跺疄榪欐牴鏈涓嶆槸鍟ラ勬祴錛屾垜瑙夊緱涓嶅傚彨鎾炲ぇ榪愯皟搴︾畻娉曪紝褰撶劧榪欑嶇瓥鐣ュ湪鏌愪簺鐗瑰畾鍦烘櫙宸鏁堟灉涓嶉敊銆
浣嗘槸鍦ㄥぇ澶氭暟鍦烘櫙涓嬶紝榪欎釜璋冨害涓嶄粎娌℃湁鎻愰珮鍚炲悙閲忥紝榪橀檷浣庝簡鍝嶅簲閫熷害錛屾墍浠ュ唴鏍稿共鑴嗘妸瀹冧粠榛樿ら厤緗閲屽垹闄や簡銆傛瘯絝烲inux鐨勫畻鏃ㄦ槸瀹炵敤錛岃屾垜浠涔熷氨涓嶅啀榪欎釜璋冨害綆楁硶涓婂氳垂鍙h垖浜嗐
1銆乧fq錛氬畬鍏ㄥ叕騫抽槦鍒楄皟搴
cfq鏄鍐呮牳榛樿ら夋嫨鐨処O璋冨害闃熷垪錛屽畠鍦ㄦ岄潰搴旂敤鍦烘櫙浠ュ強澶у氭暟甯歌佸簲鐢ㄥ満鏅涓嬮兘鏄寰堝ソ鐨勯夋嫨銆
濡備綍瀹炵幇涓涓鎵璋撶殑瀹屽叏鍏騫抽槦鍒楋紙Completely Fair Queueing錛夛紵
棣栧厛鎴戜滑瑕佺悊瑙f墍璋撶殑鍏騫蟲槸瀵硅皝鐨勫叕騫籌紵浠庢搷浣滅郴緇熺殑瑙掑害鏉ヨ達紝浜х敓鎿嶄綔琛屼負鐨勪富浣撻兘鏄榪涚▼錛屾墍浠ヨ繖閲岀殑鍏騫蟲槸閽堝規瘡涓榪涚▼鑰岃█鐨勶紝鎴戜滑瑕佽瘯鍥捐╄繘紼嬪彲浠ュ叕騫崇殑鍗犵敤IO璧勬簮銆
閭d箞濡備綍璁╄繘紼嬪叕騫崇殑鍗犵敤IO璧勬簮錛熸垜浠闇瑕佸厛鐞嗚В浠涔堟槸IO璧勬簮銆傚綋鎴戜滑琛¢噺涓涓狪O璧勬簮鐨勬椂鍊欙紝涓鑸鍠滄㈢敤鐨勬槸涓や釜鍗曚綅錛屼竴涓鏄鏁版嵁璇誨啓鐨勫甫瀹斤紝鍙︿竴涓鏄鏁版嵁璇誨啓鐨処OPS銆
甯﹀藉氨鏄浠ユ椂闂翠負鍗曚綅鐨勮誨啓鏁版嵁閲忥紝姣斿傦紝100Mbyte/s銆傝孖OPS鏄浠ユ椂闂翠負鍗曚綅鐨勮誨啓嬈℃暟銆傚湪涓嶅悓鐨勮誨啓鎯呭冧笅錛岃繖涓や釜鍗曚綅鐨勮〃鐜板彲鑳戒笉涓鏍鳳紝浣嗘槸鍙浠ョ『瀹氱殑鏄錛屼袱涓鍗曚綅鐨勪換浣曚竴涓杈懼埌浜嗘ц兘涓婇檺錛岄兘浼氭垚涓篒O鐨勭摱棰堛
浠庢満姊扮‖鐩樼殑緇撴瀯鑰冭檻錛屽傛灉璇誨啓鏄欏哄簭璇誨啓錛岄偅涔圛O鐨勮〃鐜版槸鍙浠ラ氳繃姣旇緝灝戠殑IOPS杈懼埌杈冨ぇ鐨勫甫瀹斤紝鍥犱負鍙浠ュ悎騫跺緢澶欼O錛屼篃鍙浠ラ氳繃棰勮葷瓑鏂瑰紡鍔犻熸暟鎹璇誨彇鏁堢巼銆
褰揑O鐨勮〃鐜版槸鍋忓悜浜庨殢鏈鴻誨啓鐨勬椂鍊欙紝閭d箞IOPS灝變細鍙樺緱鏇村ぇ錛孖O鐨勮鋒眰鐨勫悎騫跺彲鑳芥т笅闄嶏紝褰撴瘡嬈io璇鋒眰鏁版嵁瓚婂皯鐨勬椂鍊欙紝甯﹀借〃鐜板氨浼氳秺浣庛
浠庤繖閲屾垜浠鍙浠ョ悊瑙o紝閽堝硅繘紼嬬殑IO璧勬簮鐨勪富瑕佽〃鐜板艦寮忔湁涓や釜錛 榪涚▼鍦ㄥ崟浣嶆椂闂村唴鎻愪氦鐨処O璇鋒眰涓鏁板拰榪涚▼鍗犵敤IO鐨勫甫瀹姐
鍏跺疄鏃犺哄摢涓錛岄兘鏄璺熻繘紼嬪垎閰嶇殑IO澶勭悊鏃墮棿闀垮害緔у瘑鐩稿叧鐨勩
鏈夋椂涓氬姟鍙浠ュ湪杈冨皯IOPS鐨勬儏鍐典笅鍗犵敤杈冨ぇ甯﹀斤紝鍙﹀栦竴浜涘垯鍙鑳藉湪杈冨ぇIOPS鐨勬儏鍐典笅鍗犵敤杈冨皯甯﹀斤紝鎵浠ュ硅繘紼嬪崰鐢↖O鐨勬椂闂磋繘琛岃皟搴︽墠鏄鐩稿規渶鍏騫崇殑銆
鍗籌紝鎴戜笉綆′綘鏄疘OPS楂樿繕鏄甯﹀藉崰鐢ㄩ珮錛屽埌浜嗘椂闂村挶灝辨崲涓嬩竴涓榪涚▼澶勭悊錛屼綘鐖卞拫鏍峰拫鏍楓
鎵浠ワ紝cfq灝辨槸璇曞浘緇欐墍鏈夎繘紼嬪垎閰嶇瓑鍚岀殑鍧楄懼囦嬌鐢ㄧ殑鏃墮棿鐗囷紝榪涚▼鍦ㄦ椂闂寸墖鍐咃紝鍙浠ュ皢浜х敓鐨処O璇鋒眰鎻愪氦緇欏潡璁懼囪繘琛屽勭悊錛屾椂闂寸墖緇撴潫錛岃繘紼嬬殑璇鋒眰灝嗘帓榪涘畠鑷宸辯殑闃熷垪錛岀瓑寰呬笅嬈¤皟搴︾殑鏃跺欒繘琛屽勭悊銆傝繖灝辨槸cfq鐨勫熀鏈鍘熺悊銆
褰撶劧錛岀幇瀹炵敓媧諱腑涓嶅彲鑳芥湁鐪熸g殑鈥滃叕騫斥濓紝甯歌佺殑搴旂敤鍦烘櫙涓嬶紝鎴戜滑寰堣偗鑳介渶瑕佷漢涓虹殑瀵硅繘紼嬬殑IO鍗犵敤榪涜屼漢涓烘寚瀹氫紭鍏堢駭錛岃繖灝卞儚瀵硅繘紼嬬殑CPU鍗犵敤璁劇疆浼樺厛綰х殑姒傚康涓鏍楓
鎵浠ワ紝闄や簡閽堝規椂闂寸墖榪涜屽叕騫抽槦鍒楄皟搴﹀栵紝cfq榪樻彁渚涗簡浼樺厛綰ф敮鎸併傛瘡涓榪涚▼閮藉彲浠ヨ劇疆涓涓狪O浼樺厛綰э紝cfq浼氭牴鎹榪欎釜浼樺厛綰х殑璁劇疆鎯呭喌浣滀負璋冨害鏃剁殑閲嶈佸弬鑰冨洜緔犮
浼樺厛綰ч栧厛鍒嗘垚涓夊ぇ綾伙細RT銆丅E銆両DLE錛屽畠浠鍒嗗埆鏄瀹炴椂錛圧eal Time錛夈佹渶浣蟲晥鏋滐紙Best Try錛夊拰闂茬疆錛圛dle錛変笁涓綾誨埆錛屽規瘡涓綾誨埆鐨処O錛宑fq閮戒嬌鐢ㄤ笉鍚岀殑絳栫暐榪涜屽勭悊銆傚彟澶栵紝RT鍜孊E綾誨埆涓錛屽垎鍒鍙堝啀鍒掑垎浜8涓瀛愪紭鍏堢駭瀹炵幇鏇寸粏鑺傜殑QOS闇奼傦紝鑰孖DLE鍙鏈変竴涓瀛愪紭鍏堢駭銆
鍙﹀栵紝鎴戜滑閮界煡閬撳唴鏍擱粯璁ゅ瑰瓨鍌ㄧ殑璇誨啓閮芥槸緇忚繃緙撳瓨錛坆uffer/cache錛夌殑錛屽湪榪欑嶆儏鍐典笅錛宑fq鏄鏃犳硶鍖哄垎褰撳墠澶勭悊鐨勮鋒眰鏄鏉ヨ嚜鍝涓涓榪涚▼鐨勩
鍙鏈夊湪榪涚▼浣跨敤鍚屾ユ柟寮忥紙sync read鎴栬卻ync wirte錛夋垨鑰呯洿鎺IO錛圖irect IO錛夋柟寮忚繘琛岃誨啓鐨勬椂鍊欙紝cfq鎵嶈兘鍖哄垎鍑篒O璇鋒眰鏉ヨ嚜鍝涓榪涚▼銆
鎵浠ワ紝闄や簡閽堝規瘡涓榪涚▼瀹炵幇鐨処O闃熷垪浠ュ栵紝榪樺疄鐜頒簡涓涓鍏鍏辯殑闃熷垪鐢ㄦ潵澶勭悊寮傛ヨ鋒眰銆
褰撳墠鍐呮牳宸茬粡瀹炵幇浜嗛拡瀵笽O璧勬簮鐨刢group璧勬簮闅旂伙紝鎵浠ュ湪浠ヤ笂浣撶郴鐨勫熀紜涓婏紝cfq涔熷疄鐜頒簡閽堝筩group鐨勮皟搴︽敮鎸併
鎬葷殑鏉ヨ達紝cfq鐢ㄤ簡涓緋誨垪鐨勬暟鎹緇撴瀯瀹炵幇浜嗕互涓婃墍鏈夊嶆潅鍔熻兘鐨勬敮鎸侊紝澶у跺彲浠ラ氳繃婧愪唬鐮佺湅鍒板叾鐩稿叧瀹炵幇錛屾枃浠跺湪婧愪唬鐮佺洰褰曚笅鐨刡lock/cfq-iosched.c銆
1.1 cfq璁捐″師鐞
鍦ㄦわ紝鎴戜滑瀵規暣浣撴暟鎹緇撴瀯鍋氫竴涓綆瑕佹弿榪幫細棣栧厛錛宑fq閫氳繃涓涓鍙鍋歝fq_data鐨勬暟鎹緇撴瀯緇存姢浜嗘暣涓璋冨害鍣ㄦ祦紼嬨傚湪涓涓鏀鎸佷簡cgroup鍔熻兘鐨刢fq涓錛屽叏閮ㄨ繘紼嬭鍒嗘垚浜嗚嫢騫蹭釜contral group榪涜岀$悊銆
姣忎釜cgroup鍦╟fq涓閮芥湁涓涓猚fq_group鐨勭粨鏋勮繘琛屾弿榪幫紝鎵鏈夌殑cgroup閮借浣滀負涓涓璋冨害瀵硅薄鏀捐繘涓涓綰㈤粦鏍戜腑錛屽苟浠vdisktime涓簁ey榪涜屾帓搴忋
vdisktime榪欎釜鏃墮棿綰褰曠殑鏄褰撳墠cgroup鎵鍗犵敤鐨剗o鏃墮棿錛屾瘡嬈″筩group榪涜岃皟搴︽椂錛屾繪槸閫氳繃綰㈤粦鏍戦夋嫨褰撳墠vdisktime鏃墮棿鏈灝戠殑cgroup榪涜屽勭悊錛屼互淇濊瘉鎵鏈塩groups涔嬮棿鐨処O璧勬簮鍗犵敤鈥滃叕騫斥濄
褰撶劧鎴戜滑鐭ラ亾錛宑group鏄鍙浠ュ筨lkio榪涜岃祫婧愭瘮渚嬪垎閰嶇殑錛屽叾浣滅敤鍘熺悊灝辨槸錛屽垎閰嶆瘮渚嬪ぇ鐨刢group鍗犵敤vdisktime鏃墮棿澧為暱杈冩參錛屽垎閰嶆瘮渚嬪皬鐨剉disktime鏃墮棿澧為暱杈冨揩錛屽揩鎱涓庡垎閰嶆瘮渚嬫垚姝f瘮銆
榪欐牱灝卞仛鍒頒簡涓嶅悓鐨刢group鍒嗛厤鐨処O姣斾緥涓嶄竴鏍鳳紝騫朵笖鍦╟fq鐨勮掑害鐪嬫潵渚濈劧鏄鈥滃叕騫斥滅殑銆
閫夋嫨濂戒簡闇瑕佸勭悊鐨刢group錛坈fq_group錛変箣鍚庯紝璋冨害鍣ㄩ渶瑕佸喅絳栭夋嫨涓嬩竴姝ョ殑service_tree銆
service_tree榪欎釜鏁版嵁緇撴瀯瀵瑰簲鐨勯兘鏄涓緋誨垪鐨勭孩榛戞爲錛屼富瑕佺洰鐨勬槸鐢ㄦ潵瀹炵幇璇鋒眰浼樺厛綰у垎綾葷殑錛屽氨鏄疪T銆丅E銆両DLE鐨勫垎綾匯傛瘡涓涓猚fq_group閮界淮鎶や簡7涓猻ervice_trees錛屽叾瀹氫箟濡備笅錛
鍏朵腑service_tree_idle灝辨槸鐢ㄦ潵緇橧DLE綾誨瀷鐨勮鋒眰榪涜屾帓闃熺敤鐨勭孩榛戞爲銆
鑰屼笂闈浜岀淮鏁扮粍錛岄栧厛絎涓涓緇村害閽堝筊T鍜孊E鍒嗗埆鍚勫疄鐜頒簡涓涓鏁扮粍錛屾瘡涓涓鏁扮粍涓閮界淮鎶や簡涓変釜綰㈤粦鏍戱紝鍒嗗埆瀵瑰簲涓夌嶄笉鍚屽瓙綾誨瀷鐨勮鋒眰錛屽垎鍒鏄錛歋YNC銆丼YNC_NOIDLE浠ュ強ASYNC銆
鎴戜滑鍙浠ヨや負SYNC鐩稿綋浜嶴YNC_IDLE騫朵笌SYNC_NOIDLE瀵瑰簲銆俰dling鏄痗fq鍦ㄨ捐′笂涓轟簡灝介噺鍚堝苟榪炵畫鐨処O璇鋒眰浠ヨ揪鍒版彁楂樺悶鍚愰噺鐨勭洰鐨勮屽姞鍏ョ殑鏈哄埗錛屾垜浠鍙浠ョ悊瑙d負鏄涓縐嶁滅┖杞鈥濈瓑寰呮満鍒躲
絀鴻漿鏄鎸囷紝褰撲竴涓闃熷垪澶勭悊涓涓璇鋒眰緇撴潫鍚庯紝浼氬湪鍙戠敓璋冨害涔嬪墠絀虹瓑涓灝忎細鏃墮棿錛屽傛灉涓嬩竴涓璇鋒眰鍒版潵錛屽垯鍙浠ュ噺灝戠佸ご瀵誨潃錛岀戶緇澶勭悊欏哄簭鐨処O璇鋒眰銆
涓轟簡瀹炵幇榪欎釜鍔熻兘錛宑fq鍦╯ervice_tree榪欏眰鏁版嵁緇撴瀯榪欏疄鐜頒簡SYNC闃熷垪錛屽傛灉璇鋒眰鏄鍚屾ラ『搴忚鋒眰錛屽氨鍏ラ槦榪欎釜service tree錛屽傛灉璇鋒眰鏄鍚屾ラ殢鏈鴻鋒眰錛屽垯鍏ラ槦SYNC_NOIDLE闃熷垪錛屼互鍒ゆ柇涓嬩竴涓璇鋒眰鏄鍚︽槸欏哄簭璇鋒眰銆
鎵鏈夌殑寮傛ュ啓鎿嶄綔璇鋒眰灝嗗叆闃烝SYNC鐨剆ervice tree錛屽苟涓旈拡瀵硅繖涓闃熷垪娌℃湁絀鴻漿絳夊緟鏈哄埗銆
姝ゅ栵紝cfq榪樺筍SD榪欐牱鐨勭‖鐩樻湁鐗規畩璋冩暣錛屽綋cfq鍙戠幇瀛樺偍璁懼囨槸涓涓猻sd紜鐩樿繖鏍風殑闃熷垪娣卞害鏇村ぇ鐨勮懼囨椂錛屾墍鏈夐拡瀵瑰崟鐙闃熷垪鐨勭┖杞閮藉皢涓嶇敓鏁堬紝鎵鏈夌殑IO璇鋒眰閮藉皢鍏ラ槦SYNC_NOIDLE榪欎釜service tree銆
姣忎竴涓猻ervice tree閮藉瑰簲浜嗚嫢騫蹭釜cfq_queue闃熷垪錛屾瘡涓猚fq_queue闃熷垪瀵瑰簲涓涓榪涚▼錛岃繖涓鎴戜滑鍚庣畫鍐嶈︾粏璇存槑銆
cfq_group榪樼淮鎶や簡涓涓鍦╟group鍐呴儴鎵鏈夎繘紼嬪叕鐢ㄧ殑寮傛IO璇鋒眰闃熷垪錛屽叾緇撴瀯濡備笅錛
寮傛ヨ鋒眰涔熷垎鎴愪簡RT銆丅E銆両DLE榪欎笁綾昏繘琛屽勭悊錛屾瘡涓綾誨瑰簲涓涓猚fq_queue榪涜屾帓闃熴
BE鍜孯T涔熷疄鐜頒簡浼樺厛綰х殑鏀鎸侊紝姣忎竴涓綾誨瀷鏈塈OPRIO_BE_NR榪欎箞澶氫釜浼樺厛綰э紝榪欎釜鍊煎畾涔変負8錛屾暟緇勪笅鏍囦負0-7銆
鎴戜滑鐩鍓嶅垎鏋愮殑鍐呮牳浠g爜鐗堟湰涓篖inux 4.4錛屽彲浠ョ湅鍑猴紝浠巆fq鐨勮掑害鏉ヨ達紝宸茬粡鍙浠ュ疄鐜板紓姝IO鐨刢group鏀鎸佷簡錛屾垜浠闇瑕佸畾涔変竴涓嬭繖閲屾墍璋撳紓姝IO鐨勫惈涔夛紝瀹冧粎浠呰〃紺轟粠鍐呭瓨鐨刡uffer/cache涓鐨勬暟鎹鍚屾ュ埌紜鐩樼殑IO璇鋒眰錛岃屼笉鏄痑io(man 7 aio)鎴栬卨inux鐨刵ative寮傛io浠ュ強lio鏈哄埗錛屽疄闄呬笂榪欎簺鎵璋撶殑鈥滃紓姝モ滻O鏈哄埗錛屽湪鍐呮牳涓閮芥槸鍚屾ュ疄鐜扮殑錛堟湰璐ㄤ笂鍐璇轟紛鏇艱$畻鏈烘病鏈夌湡姝g殑鈥滃紓姝モ濇満鍒訛級銆
鎴戜滑鍦ㄤ笂闈㈠凡緇忚存槑榪囷紝鐢變簬榪涚▼姝e父鎯呭喌涓嬮兘鏄灝嗘暟鎹鍏堝啓鍏buffer/cache錛屾墍浠ヨ繖縐嶅紓姝IO閮芥槸緇熶竴鐢眂fq_group涓鐨刟sync璇鋒眰闃熷垪澶勭悊鐨勩
閭d箞涓轟粈涔堝湪涓婇潰鐨剆ervice_tree涓榪樿佸疄鐜板拰涓涓獮SYNC鐨勭被鍨嬪憿錛
榪欏綋鐒舵槸涓轟簡鏀鎸佸尯鍒嗚繘紼嬬殑寮傛IO騫朵嬌涔嬪彲浠モ滃畬鍏ㄥ叕騫斥濆仛鍑嗗囧柦銆
瀹為檯涓婂湪鏈鏂扮殑cgroup v2鐨刡lkio浣撶郴涓錛屽唴鏍稿凡緇忔敮鎸佷簡閽堝筨uffer IO鐨刢group闄愰熸敮鎸侊紝鑰屼互涓婅繖浜涘彲鑳藉規槗娣鋒穯鐨勪竴鍫嗙被鍨嬶紝閮芥槸鍦ㄦ柊鐨勪綋緋諱笅闇瑕佺敤鍒扮殑綾誨瀷鏍囪般
鏂頒綋緋葷殑澶嶆潅搴︽洿楂樹簡錛屽姛鑳戒篃鏇村姞寮哄ぇ錛屼絾鏄澶у跺厛涓嶈佺潃鎬ワ紝姝e紡鐨刢group v2浣撶郴錛屽湪Linux 4.5鍙戝竷鐨勬椂鍊欎細姝e紡璺熷ぇ瀹惰侀潰銆
鎴戜滑緇х畫閫夋嫨service_tree鐨勮繃紼嬶紝涓夌嶄紭鍏堢駭綾誨瀷鐨剆ervice_tree鐨勯夋嫨灝辨槸鏍規嵁綾誨瀷鐨勪紭鍏堢駭鏉ュ仛閫夋嫨鐨勶紝RT浼樺厛綰ф渶楂橈紝BE鍏舵★紝IDLE鏈浣庛傚氨鏄璇達紝RT閲屾湁錛屽氨浼氫竴鐩村勭悊RT錛孯T娌′簡鍐嶅勭悊BE銆
姣忎釜service_tree瀵瑰簲涓涓鍏冪礌涓篶fq_queue鎺掗槦鐨勭孩榛戞爲錛岃屾瘡涓猚fq_queue灝辨槸鍐呮牳涓鴻繘紼嬶紙綰跨▼錛夊壋寤虹殑璇鋒眰闃熷垪銆
姣忎竴涓猚fq_queue閮戒細緇存姢涓涓猺b_key鐨勫彉閲忥紝榪欎釜鍙橀噺瀹為檯涓婂氨鏄榪欎釜闃熷垪鐨処O鏈嶅姟鏃墮棿錛坰ervice time錛夈
榪欓噷榪樻槸閫氳繃綰㈤粦鏍戞壘鍒皊ervice time鏃墮棿鏈鐭鐨勯偅涓猚fq_queue榪涜屾湇鍔★紝浠ヤ繚璇佲滃畬鍏ㄥ叕騫斥濄
閫夋嫨濂戒簡cfq_queue涔嬪悗錛屽氨瑕佸紑濮嬪勭悊榪欎釜闃熷垪閲岀殑IO璇鋒眰浜嗐傝繖閲岀殑璋冨害鏂瑰紡鍩烘湰璺焏eadline綾諱技銆
cfq_queue浼氬硅繘鍏ラ槦鍒楃殑姣忎竴涓璇鋒眰榪涜屼袱嬈″叆闃燂紝涓涓鏀捐繘fifo涓錛屽彟涓涓鏀捐繘鎸夎塊棶鎵囧尯欏哄簭浣滀負key鐨勭孩榛戞爲涓銆
榛樿や粠綰㈤粦鏍戜腑鍙栬鋒眰榪涜屽勭悊錛屽綋璇鋒眰鐨勫歡鏃舵椂闂磋揪鍒癲eadline鏃訛紝灝變粠綰㈤粦鏍戜腑鍙栫瓑寰呮椂闂存渶闀跨殑榪涜屽勭悊錛屼互淇濊瘉璇鋒眰涓嶈楗挎匯
榪欏氨鏄鏁翠釜cfq鐨勮皟搴︽祦紼嬶紝褰撶劧鍏朵腑榪樻湁寰堝氱粏鏋濇湯鑺傛病鏈変氦浠o紝姣斿傚悎騫跺勭悊浠ュ強欏哄簭澶勭悊絳夌瓑銆
1.2 cfq鐨勫弬鏁拌皟鏁
鐞嗚В鏁翠釜璋冨害嫻佺▼鏈夊姪浜庢垜浠鍐崇瓥濡備綍璋冩暣cfq鐨勭浉鍏沖弬鏁般傛墍鏈塩fq鐨勫彲璋冨弬鏁伴兘鍙浠ュ湪/sys/class/block/sda/queue/iosched/鐩褰曚笅鎵懼埌錛屽綋鐒訛紝鍦ㄤ綘鐨勭郴緇熶笂錛岃峰皢sda鏇挎崲涓虹浉搴旂殑紓佺洏鍚嶇О銆傛垜浠鏉ョ湅涓涓嬮兘鏈変粈涔堬細
榪欎簺鍙傛暟閮ㄥ垎鏄璺熸満姊扮‖鐩樼佸ご瀵婚亾鏂瑰紡鏈夊叧鐨勶紝濡傛灉鍏惰存槑浣犵湅涓嶆噦錛岃峰厛琛ュ厖鐩稿叧鐭ヨ瘑錛
back_seek_max:紓佸ご鍙浠ュ悜鍚庡誨潃鐨勬渶澶ц寖鍥達紝榛樿ゅ間負16M銆
back_seek_penalty:鍚戝悗瀵誨潃鐨勬儵緗氱郴鏁般傝繖涓鍊兼槸璺熷悜鍓嶅誨潃榪涜屾瘮杈冪殑銆
浠ヤ笂涓や釜鏄涓轟簡闃叉㈢佸ご瀵婚亾鍙戠敓鎶栧姩鑰屽艱嚧瀵誨潃榪囨參鑰岃劇疆鐨勩傚熀鏈鎬濊礬鏄榪欐牱錛屼竴涓猧o璇鋒眰鍒版潵鐨勬椂鍊欙紝cfq浼氭牴鎹鍏跺誨潃浣嶇疆棰勪及涓涓嬪叾紓佸ご瀵婚亾鎴愭湰銆
璁劇疆涓涓鏈澶у糱ack_seek_max錛屽逛簬璇鋒眰鎵璁塊棶鐨勬墖鍖哄彿鍦ㄧ佸ご鍚庢柟鐨勮鋒眰錛屽彧瑕佸誨潃鑼冨洿娌℃湁瓚呰繃榪欎釜鍊礆紝cfq浼氬儚鍚戝墠瀵誨潃鐨勮鋒眰涓鏍峰勭悊瀹冦
鍐嶈劇疆涓涓璇勪及鎴愭湰鐨勭郴鏁癰ack_seek_penalty錛岀浉瀵逛簬紓佸ご鍚戝墠瀵誨潃錛屽悜鍚庡誨潃鐨勮窛紱諱負1/2(1/back_seek_penalty)鏃訛紝cfq璁や負榪欎袱涓璇鋒眰瀵誨潃鐨勪唬浠鋒槸鐩稿悓銆
榪欎袱涓鍙傛暟瀹為檯涓婃槸cfq鍒ゆ柇璇鋒眰鍚堝苟澶勭悊鐨勬潯浠墮檺鍒訛紝鍑′簨澶嶅悎榪欎釜鏉′歡鐨勮鋒眰錛岄兘浼氬敖閲忓湪鏈嬈¤鋒眰澶勭悊鐨勬椂鍊欎竴璧峰悎騫跺勭悊銆
fifo_expire_async:璁劇疆寮傛ヨ鋒眰鐨勮秴鏃舵椂闂淬
鍚屾ヨ鋒眰鍜屽紓姝ヨ鋒眰鏄鍖哄垎涓嶅悓闃熷垪澶勭悊鐨勶紝cfq鍦ㄨ皟搴︾殑鏃跺欎竴鑸鎯呭喌閮戒細浼樺厛澶勭悊鍚屾ヨ鋒眰錛屼箣鍚庡啀澶勭悊寮傛ヨ鋒眰錛岄櫎闈炲紓姝ヨ鋒眰絎﹀悎涓婅堪鍚堝苟澶勭悊鐨勬潯浠墮檺鍒惰寖鍥村唴銆
褰撴湰榪涚▼鐨勯槦鍒楄璋冨害鏃訛紝cfq浼氫紭鍏堟鏌ユ槸鍚︽湁寮傛ヨ鋒眰瓚呮椂錛屽氨鏄瓚呰繃fifo_expire_async鍙傛暟鐨勯檺鍒躲傚傛灉鏈夛紝鍒欎紭鍏堝彂閫佷竴涓瓚呮椂鐨勮鋒眰錛屽叾浣欒鋒眰浠嶇劧鎸夌収浼樺厛綰т互鍙婃墖鍖虹紪鍙峰ぇ灝忔潵澶勭悊銆
fifo_expire_sync:榪欎釜鍙傛暟璺熶笂闈㈢殑綾諱技錛屽尯鍒鏄鐢ㄦ潵璁劇疆鍚屾ヨ鋒眰鐨勮秴鏃舵椂闂淬
slice_idle:鍙傛暟璁劇疆浜嗕竴涓絳夊緟鏃墮棿銆傝繖璁ヽfq鍦ㄥ垏鎹cfq_queue鎴杝ervice tree鐨勬椂鍊欑瓑寰呬竴孌墊椂闂達紝鐩鐨勬槸鎻愰珮鏈烘扮‖鐩樼殑鍚炲悙閲忋
涓鑸鎯呭喌涓嬶紝鏉ヨ嚜鍚屼竴涓猚fq_queue鎴栬卻ervice tree鐨処O璇鋒眰鐨勫誨潃灞閮ㄦф洿濂斤紝鎵浠ヨ繖鏍峰彲浠ュ噺灝戠佺洏鐨勫誨潃嬈℃暟銆傝繖涓鍊煎湪鏈烘扮‖鐩樹笂榛樿や負闈為浂銆
褰撶劧鍦ㄥ滻鎬佺‖鐩樻垨鑰呯‖RAID璁懼囦笂璁劇疆榪欎釜鍊間負闈為浂浼氶檷浣庡瓨鍌ㄧ殑鏁堢巼錛屽洜涓哄滻鎬佺‖鐩樻病鏈夌佸ご瀵誨潃榪欎釜姒傚康錛屾墍浠ュ湪榪欐牱鐨勮懼囦笂搴旇ヨ劇疆涓0錛屽叧闂姝ゅ姛鑳姐
group_idle:榪欎釜鍙傛暟涔熻窡涓婁竴涓鍙傛暟綾諱技錛屽尯鍒鏄褰揷fq瑕佸垏鎹cfq_group鐨勬椂鍊欎細絳夊緟涓孌墊椂闂淬
鍦╟group鐨勫満鏅涓嬶紝濡傛灉鎴戜滑娌跨敤slice_idle鐨勬柟寮忥紝閭d箞絀鴻漿絳夊緟鍙鑳戒細鍦╟group緇勫唴姣忎釜榪涚▼鐨刢fq_queue鍒囨崲鏃跺彂鐢熴
榪欐牱浼氬傛灉榪欎釜榪涚▼涓鐩存湁璇鋒眰瑕佸勭悊鐨勮瘽錛岄偅涔堢洿鍒拌繖涓猚group鐨勯厤棰濊鑰楀敖錛屽悓緇勪腑鐨勫叾瀹冭繘紼嬩篃鍙鑳芥棤娉曡璋冨害鍒般傝繖鏍蜂細瀵艱嚧鍚岀粍涓鐨勫叾瀹冭繘紼嬮タ姝昏屼駭鐢烮O鎬ц兘鐡墮堛
鍦ㄨ繖縐嶆儏鍐典笅錛屾垜浠鍙浠ュ皢slice_idle 錛 0鑰実roup_idle 錛 8銆傝繖鏍風┖杞絳夊緟灝辨槸浠cgroup涓哄崟浣嶈繘琛岀殑錛岃屼笉鏄浠cfq_queue鐨勮繘紼嬩負鍗曚綅榪涜岋紝浠ラ槻姝涓婅堪闂棰樹駭鐢熴
low_latency:榪欎釜鏄鐢ㄦ潵寮鍚鎴栧叧闂璫fq鐨勪綆寤舵椂錛坙ow latency錛夋ā寮忕殑寮鍏熾
褰撹繖涓寮鍏蟲墦寮鏃訛紝cfq灝嗕細鏍規嵁target_latency鐨勫弬鏁拌劇疆鏉ュ規瘡涓涓榪涚▼鐨勫垎鐗囨椂闂達紙slice time錛夎繘琛岄噸鏂拌$畻銆
榪欏皢鏈夊埄浜庡瑰悶鍚愰噺鐨勫叕騫籌紙榛樿ゆ槸瀵規椂闂寸墖鍒嗛厤鐨勫叕騫籌級銆
鍏抽棴榪欎釜鍙傛暟錛堣劇疆涓0錛夊皢蹇界暐target_latency鐨勫箋傝繖灝嗕嬌緋葷粺涓鐨勮繘紼嬪畬鍏ㄦ寜鐓ф椂闂寸墖鏂瑰紡榪涜孖O璧勬簮鍒嗛厤銆傝繖涓寮鍏抽粯璁ゆ槸鎵撳紑鐨勩
鎴戜滑宸茬粡鐭ラ亾cfq璁捐′笂鏈夆滅┖杞鈥濓紙idling錛夎繖涓姒傚康錛岀洰鐨勬槸涓轟簡鍙浠ヨ╄繛緇鐨勮誨啓鎿嶄綔灝藉彲鑳藉氱殑鍚堝苟澶勭悊錛屽噺灝戠佸ご鐨勫誨潃鎿嶄綔浠ヤ究澧炲ぇ鍚炲悙閲忋
濡傛灉鏈夎繘紼嬫繪槸寰堝揩鐨勮繘琛岄『搴忚誨啓錛岄偅涔堝畠灝嗗洜涓篶fq鐨勭┖杞絳夊緟鍛戒腑鐜囧緢楂樿屽艱嚧鍏跺畠闇瑕佸勭悊IO鐨勮繘紼嬪搷搴旈熷害涓嬮檷錛屽傛灉鍙︿竴涓闇瑕佽皟搴︾殑榪涚▼涓嶄細鍙戝嚭澶ч噺欏哄簭IO琛屼負鐨勮瘽錛岀郴緇熶腑涓嶅悓榪涚▼IO鍚炲悙閲忕殑琛ㄧ幇灝變細寰堜笉鍧囪銆
灝辨瘮濡傦紝緋葷粺鍐呭瓨鐨刢ache涓鏈夊緢澶氳剰欏佃佸啓鍥炴椂錛屾岄潰鍙堣佹墦寮涓涓嫻忚堝櫒榪涜屾搷浣滐紝榪欐椂鑴忛〉鍐欏洖鐨勫悗鍙拌屼負灝卞緢鍙鑳戒細澶ч噺鍛戒腑絀鴻漿鏃墮棿錛岃屽艱嚧嫻忚堝櫒鐨勫皬閲廔O涓鐩寸瓑寰咃紝璁╃敤鎴鋒劅瑙夋祻瑙堝櫒榪愯屽搷搴旈熷害鍙樻參銆
榪欎釜low_latency涓昏佹槸瀵硅繖縐嶆儏鍐佃繘琛屼紭鍖栫殑閫夐」錛屽綋鍏舵墦寮鏃訛紝緋葷粺浼氭牴鎹畉arget_latency鐨勯厤緗瀵瑰洜涓哄懡涓絀鴻漿鑰屽ぇ閲忓崰鐢↖O鍚炲悙閲忕殑榪涚▼榪涜岄檺鍒訛紝浠ヨ揪鍒頒笉鍚岃繘紼婭O鍗犵敤鐨勫悶鍚愰噺鐨勭浉瀵瑰潎琛°傝繖涓寮鍏蟲瘮杈冨悎閫傚湪綾諱技妗岄潰搴旂敤鐨勫満鏅涓嬫墦寮銆
target_latency:褰搇ow_latency鐨勫間負寮鍚鐘舵佹椂錛宑fq灝嗘牴鎹榪欎釜鍊奸噸鏂拌$畻姣忎釜榪涚▼鍒嗛厤鐨処O鏃墮棿鐗囬暱搴︺
quantum:榪欎釜鍙傛暟鐢ㄦ潵璁劇疆姣忔′粠cfq_queue涓澶勭悊澶氬皯涓狪O璇鋒眰銆傚湪涓涓闃熷垪澶勭悊浜嬩歡鍛ㄦ湡涓錛岃秴榪囪繖涓鏁板瓧鐨処O璇鋒眰灝嗕笉浼氳澶勭悊銆傝繖涓鍙傛暟鍙瀵瑰悓姝ョ殑璇鋒眰鏈夋晥銆
slice_sync:褰撲竴涓猚fq_queue闃熷垪琚璋冨害澶勭悊鏃訛紝瀹冨彲浠ヨ鍒嗛厤鐨勫勭悊鎬繪椂闂存槸閫氳繃榪欎釜鍊兼潵浣滀負涓涓璁$畻鍙傛暟鎸囧畾鐨勩傚叕寮忎負錛歵ime_slice = slice_sync + (slice_sync/5 * (4 - prio))銆傝繖涓鍙傛暟瀵瑰悓姝ヨ鋒眰鏈夋晥銆
slice_async:榪欎釜鍊艱窡涓婁竴涓綾諱技錛屽尯鍒鏄瀵瑰紓姝ヨ鋒眰鏈夋晥銆
slice_async_rq:榪欎釜鍙傛暟鐢ㄦ潵闄愬埗鍦ㄤ竴涓猻lice鐨勬椂闂磋寖鍥村唴錛屼竴涓闃熷垪鏈澶氬彲浠ュ勭悊鐨勫紓姝ヨ鋒眰涓鏁般傝鋒眰琚澶勭悊鐨勬渶澶т釜鏁拌繕璺熺浉鍏寵繘紼嬭璁劇疆鐨剗o浼樺厛綰ф湁鍏熾
1.3 cfq鐨処OPS妯″紡
鎴戜滑宸茬粡鐭ラ亾錛岄粯璁ゆ儏鍐典笅cfq鏄浠ユ椂闂寸墖鏂瑰紡鏀鎸佺殑甯︿紭鍏堢駭鐨勮皟搴︽潵淇濊瘉IO璧勬簮鍗犵敤鐨勫叕騫熾
楂樹紭鍏堢駭鐨勮繘紼嬪皢寰楀埌鏇村氱殑鏃墮棿鐗囬暱搴︼紝鑰屼綆浼樺厛綰х殑榪涚▼鏃墮棿鐗囩浉瀵硅緝灝忋
褰撴垜浠鐨勫瓨鍌ㄦ槸涓涓楂橀熷苟涓旀敮鎸丯CQ錛堝師鐢熸寚浠ら槦鍒楋級鐨勮懼囩殑鏃跺欙紝鎴戜滑鏈濂藉彲浠ヨ╁叾鍙浠ヤ粠澶氫釜cfq闃熷垪涓澶勭悊澶氳礬鐨勮鋒眰錛屼互渚挎彁鍗嘚CQ鐨勫埄鐢ㄧ巼銆
姝ゆ椂浣跨敤鏃墮棿鐗囩殑鍒嗛厤鏂瑰紡鍒嗛厤璧勬簮灝辨樉寰椾笉鍚堟椂瀹滀簡錛屽洜涓哄熀浜庢椂闂寸墖鐨勫垎閰嶏紝鍚屼竴鏃跺埢鏈澶氳兘澶勭悊鐨勮鋒眰闃熷垪鍙鏈変竴涓銆
榪欐椂錛屾垜浠闇瑕佸垏鎹cfq鐨勬ā寮忎負IOPS妯″紡銆傚垏鎹㈡柟寮忓緢綆鍗曪紝灝辨槸灝唖lice_idle=0鍗沖彲銆傚唴鏍鎬細鑷鍔ㄦ嫻嬩綘鐨勫瓨鍌ㄨ懼囨槸鍚︽敮鎸丯CQ錛屽傛灉鏀鎸佺殑璇漜fq浼氳嚜鍔ㄥ垏鎹涓篒OPS妯″紡銆
鍙﹀栵紝鍦ㄩ粯璁ょ殑鍩轟簬浼樺厛綰х殑鏃墮棿鐗囨柟寮忎笅錛屾垜浠鍙浠ヤ嬌鐢╥onice鍛戒護鏉ヨ皟鏁磋繘紼嬬殑IO浼樺厛綰с傝繘紼嬮粯璁ゅ垎閰嶇殑IO浼樺厛綰ф槸鏍規嵁榪涚▼鐨刵ice鍊艱$畻鑰屾潵鐨勶紝璁$畻鏂規硶鍙浠ュ湪man ionice涓鐪嬪埌錛岃繖閲屼笉鍐嶅簾璇濄
2銆乨eadline錛氭渶緇堟湡闄愯皟搴
deadline璋冨害綆楁硶鐩稿筩fq瑕佺畝鍗曞緢澶氥傚叾璁捐$洰鏍囨槸錛
鍦ㄤ繚璇佽鋒眰鎸夌収璁懼囨墖鍖虹殑欏哄簭榪涜岃塊棶鐨勫悓鏃訛紝鍏奸【鍏跺畠璇鋒眰涓嶈楗挎伙紝瑕佸湪涓涓鏈緇堟湡闄愬墠琚璋冨害鍒般
鎴戜滑鐭ラ亾紓佸ご瀵圭佺洏鐨勫婚亾鏄鍙浠ヨ繘琛岄『搴忚塊棶鍜岄殢鏈鴻塊棶鐨勶紝鍥犱負瀵婚亾寤舵椂鏃墮棿鐨勫叧緋伙紝欏哄簭璁塊棶鏃禝O鐨勫悶鍚愰噺鏇村ぇ錛岄殢鏈鴻塊棶鐨勫悶鍚愰噺灝忋
濡傛灉鎴戜滑鎯充負涓涓鏈烘扮‖鐩樿繘琛屽悶鍚愰噺浼樺寲鐨勮瘽錛岄偅涔堝氨鍙浠ヨ╄皟搴﹀櫒鎸夌収灝介噺澶嶅悎欏哄簭璁塊棶鐨処O璇鋒眰榪涜屾帓搴忥紝涔嬪悗璇鋒眰浠ヨ繖鏍風殑欏哄簭鍙戦佺粰紜鐩橈紝灝卞彲浠ヤ嬌IO鐨勫悶鍚愰噺鏇村ぇ銆
浣嗘槸榪欐牱鍋氫篃鏈夊彟涓涓闂棰橈紝灝辨槸濡傛灉姝ゆ椂鍑虹幇浜嗕竴涓璇鋒眰錛屽畠瑕佽塊棶鐨勭侀亾紱葷洰鍓嶇佸ご鎵鍦ㄧ侀亾寰堣繙錛屽簲鐢ㄧ殑璇鋒眰鍙堝ぇ閲忛泦涓鍦ㄧ洰鍓嶇侀亾闄勮繎銆
瀵艱嚧澶ч噺璇鋒眰涓鐩翠細琚鍚堝苟鍜屾彃闃熷勭悊錛岃岄偅涓瑕佽塊棶姣旇緝榪滅侀亾鐨勮鋒眰灝嗗洜涓轟竴鐩翠笉鑳借璋冨害鑰岄タ姝匯
deadline灝辨槸榪欐牱涓縐嶈皟搴﹀櫒錛岃兘鍦ㄤ繚璇両O鏈澶у悶鍚愰噺鐨勬儏鍐典笅錛屽敖閲忎嬌榪滅璇鋒眰鍦ㄤ竴涓鏈熼檺鍐呰璋冨害鑰屼笉琚楗挎葷殑璋冨害鍣ㄣ
③ linuxpagebuffercache深入理解
Page cache和buffer cache一直以來是兩個比較容易混淆的概念,在我工作的這一段時間,page cache和buffer cache的概念曾經困擾過我,如果能夠了解到這兩個cache的本質,那麼我們在分析io問題的時候可能會更加得心應手Page cache和buffer cache一直以來是兩個比較容易混淆的概念,在網上也有很多人在爭辯和猜想這兩個cache到底有什麼區別,討論到最後也一直沒有一個統一和正確的結論,在我工作的這一段時間,page cache和buffer cache的概念曾經困擾過我,但是仔細分析一下,這兩個概念實際上非常的清晰。如果能夠了解到這兩個cache的本質,那麼我們在分析io問題的時候可能會更加得心應手。
Page cache實際上是針對文件系統的,是文件的緩存,在文件層面上的數據會緩存到page cache。文件的邏輯層需要映射到實際的物理磁碟,這種映射關系由文件系統來完成。當page cache的數據需要刷新時,page cache中的數據交給buffer cache,但是這種處理在2.6版本的內核之後就變的很簡單了,沒有真正意義上的cache操作。
Buffer cache是針對磁碟塊的緩存,也就是在沒有文件系統的情況下,直接對磁碟進行操作的數據會緩存到buffer cache中,例如,文件系統的元數據都會緩存到buffer cache中。
簡單說來,page cache用來緩存文件數據,buffer cache用來緩存磁碟數據。在有文件系統的情況下,對文件操作,那麼數據會緩存到page cache,如果直接採用dd等工具對磁碟進行讀寫,那麼數據會緩存到buffer cache。
補充一點,在文件系統層每個設備都會分配一個def_blk_ops的文件操作方法,這是設備的操作方法,在每個設備的inode下面會存在一個radix tree,這個radix tree下面將會放置緩存數據的page頁。這個page的數量將會在top程序的buffer一欄中顯示。如果設備做了文件系統,那麼會生成一個inode,這個inode會分配ext3_ops之類的操作方法,這些方法是文件系統的方法,在這個inode下面同樣存在一個radix tree,這里會緩存文件的page頁,緩存頁的數量在top程序的cache一欄進行統計。從上面的分析可以看出,2.6內核中的buffer cache和page cache在處理上是保持一致的,但是存在概念上的差別,page cache針對文件的cache,buffer是針對磁碟塊數據的cache,僅此而已。
buffer 與cache 的區別
A buffer is something that has yet to be 「written」 to disk. A cache is something that has been 「read」 from the disk and stored for later use.
更詳細的解釋參考:Difference Between Buffer and Cache
對於共享內存(Shared memory),主要用於在UNIX 環境下不同進程之間共享數據,是進程間通信的一種方法,一般的應用程序不會申請使用共享內存,筆者也沒有去驗證共享內存對上面等式的影響。如果你有興趣,請參考:What is Shared Memory?
cache 和 buffer的區別:
Cache:高速緩存,是位於CPU與主內存間的一種容量較小但速度很高的存儲器。由於CPU的速度遠高於主內存,CPU直接從內存中存取數據要等待一定時間周期,Cache中保存著CPU剛用過或循環使用的一部分數據,當CPU再次使用該部分數據時可從Cache中直接調用,這樣就減少了CPU的等待時間,提高了系統的效率。Cache又分為一級Cache(L1 Cache)和二級Cache(L2 Cache),L1 Cache集成在CPU內部,L2 Cache早期一般是焊在主板上,現在也都集成在CPU內部,常見的容量有256KB或512KB L2 Cache.
Buffer:緩沖區,一個用於存儲速度不同步的設備或優先順序不同的設備之間傳輸數據的區域。通過緩沖區,可以使進程之間的相互等待變少,從而使從速度慢的設備讀入數據時,速度快的設備的操作進程不發生間斷。
Free中的buffer和cache:(它們都是佔用內存):
buffer :作為buffer cache的內存,是塊設備的讀寫緩沖區
cache:作為page cache的內存, 文件系統的cache
如果 cache 的值很大,說明cache住的文件數很多。如果頻繁訪問到的文件都能被cache住,那麼磁碟的讀IO 必會非常小。
④ 深入理解Linux 的Page Cache
深入理解Linux的Page Cache
Linux內核管理的內存區域,即Page Cache,其本質是文件I/O系統的組成部分。Page Cache通過mmap和buffered I/O將文件讀取到內存空間,實際上讀取的是Page Cache。可以通過讀取/proc/meminfo文件實時獲取系統內存情況。Page Cache的大小由多個page構成,通常為4KB大小(32bits/64bits),而Page Cache的大小則為4KB的整數倍。Linux系統內存分為用戶可訪問的內存和非用戶可訪問的內存。Page Cache並不等同於Active(file) + Inactive(file) + Shmem,內核演算法計算Page Cache為:Cached = files - SwapCached - Buffers。Page Cache包含File-backed pages和Anonymous pages。File-backed pages的內存回收代價較低,而Anonymous pages的回收代價較高。Swap機制用於物理內存不夠用時回收內存空間,當進程發現需要訪問的數據不在內存時,操作系統通過系統調用將page再次讀到內存中。操作系統選擇合適的物理內存頁驅逐回磁碟,這個過程被稱為頁面替換。Swappiness參數控制Swap機制的優先順序。buffers和cached表示當前的塊緩存和頁緩存佔用量。Page Cache用於緩存文件的頁數據,buffer cache用於緩存塊設備的塊數據。操作系統積極地將所有空閑內存都用作Page Cache和buffer cache。現代Linux的Page Cache提供預讀機制,一次系統調用讀取的數據量大於請求量。Linux提供多種機制保證數據一致性,但吞吐量與數據一致性是一對矛盾。Page Cache的主要優勢包括加快數據訪問和減少I/O次數,提高系統磁碟I/O吞吐量。Page Cache的劣勢包括需要佔用額外物理內存空間,可能導致頻繁的swap操作和磁碟I/O負載上升,以及對於應用層的管理透明,應用層難以優化Page Cache的使用策略。在某些應用場景下,Page Cache可能比Direct I/O多一次磁碟讀I/O以及磁碟寫I/O。