偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

從調(diào)度到緩存:解析 Linux 磁盤(pán) I/O 性能優(yōu)化的核心設(shè)計(jì)

系統(tǒng) Linux
Linux磁盤(pán)的I/O調(diào)度是系統(tǒng)性能調(diào)優(yōu)的一個(gè)重要組成部分,其核心目標(biāo)在于根據(jù)存儲(chǔ)設(shè)備的物理特性,合理的去規(guī)劃I/O請(qǐng)求的順序,減少無(wú)效操作導(dǎo)致性能問(wèn)題。

0.引言

在前一篇文章中我們講解了文件I/O與流的概念,幫助大家理解了上層的抽象設(shè)計(jì)。本文將深入更為底層的實(shí)現(xiàn)機(jī)制,探討Linux如何高效訪問(wèn)磁盤(pán)的兩大關(guān)鍵技術(shù):磁盤(pán)調(diào)度算法和Page Cache。我們將分別從兩個(gè)維度進(jìn)行分析:一是I/O調(diào)度策略的優(yōu)化,二是Page Cache的如何減少I(mǎi)/O操作。

1.磁盤(pán)I/O調(diào)度:減少尋道時(shí)間和延遲

Linux磁盤(pán)的I/O調(diào)度是系統(tǒng)性能調(diào)優(yōu)的一個(gè)重要組成部分,其核心目標(biāo)在于根據(jù)存儲(chǔ)設(shè)備的物理特性,合理的去規(guī)劃I/O請(qǐng)求的順序,減少無(wú)效操作導(dǎo)致性能問(wèn)題。因?yàn)檎{(diào)度的選擇涉及設(shè)備的物理特性,所以我們來(lái)看常見(jiàn)的兩種物理存儲(chǔ)設(shè)備,然后再來(lái)去介紹不同調(diào)度算法:

1)機(jī)械硬盤(pán)(HDD):機(jī)械硬盤(pán)是傳統(tǒng)的硬盤(pán),其依賴(lài)于磁頭移動(dòng)和盤(pán)片旋轉(zhuǎn)來(lái)實(shí)現(xiàn)讀寫(xiě),其尋道時(shí)間(磁頭移動(dòng))和旋轉(zhuǎn)延遲(盤(pán)片旋轉(zhuǎn))是其主要耗時(shí),所以隨機(jī)I/O性能遠(yuǎn)低于順序I/O,這就要求調(diào)度算法要通過(guò)合并、排序等方式來(lái)減少磁頭的移動(dòng)。

2)固態(tài)硬盤(pán)(SSD):固態(tài)硬盤(pán)是由控制單元和存儲(chǔ)單元組成,沒(méi)有機(jī)械部件,所以尋道時(shí)間幾乎可以忽略不計(jì),也就是說(shuō)它有著很好的隨機(jī)I/O性能,但其存在擦寫(xiě)次數(shù)限制,和寫(xiě)入放大。所以SSD的調(diào)度需要考慮合并小寫(xiě)入,減少CPU計(jì)算調(diào)度。

1.1 調(diào)度算法介紹(基于Linux 5.10)

調(diào)度算法可以分為單隊(duì)列(全局單一隊(duì)列)和多隊(duì)列(多CPU/硬件隊(duì)列獨(dú)立),因?yàn)楝F(xiàn)代主要使用多隊(duì)列模式,所以我們主要介紹多隊(duì)列的調(diào)度算法,先來(lái)看整體的調(diào)度結(jié)構(gòu):

圖片

整體多隊(duì)列調(diào)度的初始化函數(shù)如下,后面到具體算法因其實(shí)現(xiàn)涉及代碼比較多,我們會(huì)主要描述思路。

void elevator_init_mq(struct request_queue *q)
{
    struct elevator_type *e;  // 指向選中的I/O調(diào)度器類(lèi)型結(jié)構(gòu)體
    int err;                  // 函數(shù)返回值,用于檢查初始化是否成功
    // 檢查當(dāng)前隊(duì)列是否支持I/O調(diào)度器(如部分設(shè)備可能強(qiáng)制使用noop調(diào)度器)
    // 若不支持,則直接返回,不進(jìn)行調(diào)度器初始化
    if (!elv_support_iosched(q))
        return;
    // 警告:若隊(duì)列已注冊(cè)(已完成初始化),則觸發(fā)BUG_ON警告(僅調(diào)試用)
    // 確保調(diào)度器初始化僅在隊(duì)列未注冊(cè)時(shí)執(zhí)行
    WARN_ON_ONCE(blk_queue_registered(q));
    // 若隊(duì)列已關(guān)聯(lián)調(diào)度器(非空),則無(wú)需重復(fù)初始化,直接返回
    if (unlikely(q->elevator))
        return;
    // 根據(jù)隊(duì)列需求選擇合適的I/O調(diào)度器
    if (!q->required_elevator_features) {
        // 若隊(duì)列無(wú)特殊功能需求,選擇默認(rèn)調(diào)度器(由內(nèi)核配置或設(shè)備類(lèi)型決定)
        e = elevator_get_default(q);
    } else {
        // 若隊(duì)列有特殊功能需求(如支持層級(jí)調(diào)度、延遲控制等),
        // 則根據(jù)需求匹配具備對(duì)應(yīng)功能的調(diào)度器
        e = elevator_get_by_features(q);
    }
    // 若未找到合適的調(diào)度器(e為NULL),則退出初始化
    if (!e)
        return;
    // 凍結(jié)隊(duì)列:阻止新的I/O請(qǐng)求進(jìn)入隊(duì)列,確保初始化期間隊(duì)列狀態(tài)穩(wěn)定
    blk_mq_freeze_queue(q);
    // 暫停隊(duì)列:等待隊(duì)列中已有請(qǐng)求處理完成,避免初始化干擾正在進(jìn)行的I/O
    blk_mq_quiesce_queue(q);
    // 初始化調(diào)度器:將選中的調(diào)度器(e)與隊(duì)列(q)綁定,創(chuàng)建調(diào)度器上下文
    // 該函數(shù)會(huì)為多隊(duì)列的每個(gè)軟件隊(duì)列初始化調(diào)度器實(shí)例(如MQ-Deadline的每個(gè)隊(duì)列私有數(shù)據(jù))
    err = blk_mq_init_sched(q, e);
    // 恢復(fù)隊(duì)列運(yùn)行:允許隊(duì)列重新接收并處理I/O請(qǐng)求
    blk_mq_unquiesce_queue(q);
    // 解凍隊(duì)列:完全恢復(fù)隊(duì)列的正常操作
    blk_mq_unfreeze_queue(q);
    // 檢查調(diào)度器初始化是否失敗
    if (err) {
        // 打印警告信息,提示當(dāng)前調(diào)度器初始化失敗,將回退到"none"調(diào)度器(noop)
        pr_warn("\"%s\" elevator initialization failed, "
                "falling back to \"none\"\n", e->elevator_name);
        // 釋放之前獲取的調(diào)度器引用,避免資源泄漏
        elevator_put(e);
    }
}
1.1.1 BFQ調(diào)度

BFQ(Budget Fair Queueing)其含義為公平對(duì)待每個(gè)進(jìn)程,其主要邏輯可以見(jiàn)下圖,其中實(shí)線代表IO請(qǐng)求的方向,通過(guò)add方法添加到IO隊(duì)列,然后使用調(diào)度器調(diào)度,由dispatch方法進(jìn)行下發(fā)處理。

虛線箭頭budget表示每個(gè)進(jìn)程被分配的訪問(wèn)的最大扇區(qū)數(shù)目,其每訪問(wèn)一個(gè)扇區(qū)就會(huì)進(jìn)行減少,一旦消耗完就會(huì)選擇其他進(jìn)程執(zhí)行IO,當(dāng)前用完的進(jìn)程會(huì)被重新估算下一次的budget數(shù)量。

然后再來(lái)看Next active application selection,這是所有IO調(diào)度器的核心功能,本質(zhì)就是選擇出一個(gè)下一個(gè)有訪問(wèn)磁盤(pán)權(quán)力的隊(duì)列,BFQ是從符合條件的隊(duì)列中進(jìn)行選擇(如budget沒(méi)用完的,等待時(shí)間較長(zhǎng)的)。

圖片圖片

1.1.2 mq-deadLine調(diào)度

其整體邏輯如下:通過(guò)兩個(gè)結(jié)構(gòu)進(jìn)行管理,一個(gè)用來(lái)記錄磁盤(pán)位置排序(為了方便連續(xù)讀取),一個(gè)按照時(shí)間排序(為了deadline優(yōu)先),其為每個(gè)CPU配置一個(gè)隊(duì)列,減少鎖競(jìng)爭(zhēng),同時(shí)采用上述的雙重排序策略來(lái)提高性能。

圖片圖片

1.1.3 kyber調(diào)度

其整體邏輯如下:在初始化階段時(shí)創(chuàng)建四類(lèi)請(qǐng)求隊(duì)列(讀、寫(xiě)、discard、other),初始化 Token 池(控制每種請(qǐng)求的最大并發(fā)數(shù)),并設(shè)置延遲目標(biāo)(讀請(qǐng)求優(yōu)先低延遲,寫(xiě)請(qǐng)求平衡吞吐);應(yīng)用請(qǐng)求先進(jìn)入暫存隊(duì)列,完成請(qǐng)求合并(減少 I/O 次數(shù))和類(lèi)型分類(lèi),再分別進(jìn)入對(duì)應(yīng)類(lèi)型的分發(fā)隊(duì)列;核心調(diào)度邏輯:

1)調(diào)度器按固定順序輪詢(xún)四類(lèi)隊(duì)列,避免某類(lèi)請(qǐng)求長(zhǎng)期被忽略;

2)通過(guò) Token 機(jī)制 控制并發(fā):每種請(qǐng)求需消耗 Token 才能被處理,Token 耗盡則隊(duì)列掛起,直到請(qǐng)求完成釋放 Token;

3)優(yōu)先保障有 Token 的隊(duì)列,避免無(wú)限制并發(fā)導(dǎo)致設(shè)備擁堵;

4)通過(guò)定期統(tǒng)計(jì)實(shí)際延遲來(lái)動(dòng)態(tài)適應(yīng)設(shè)備負(fù)載。

圖片圖片

1.1.4 總結(jié)比較

我們從調(diào)度器的優(yōu)劣以及適用場(chǎng)景進(jìn)行比較,同時(shí)會(huì)描述我們修改調(diào)度器的方式。

調(diào)度器

優(yōu)勢(shì)

劣勢(shì)

適合場(chǎng)景

Kyber

讀寫(xiě)分離,動(dòng)態(tài)調(diào)整

機(jī)械硬盤(pán)適應(yīng)較差,隨機(jī)碎片請(qǐng)求多

現(xiàn)代存儲(chǔ)SSD和單一場(chǎng)景

BFQ

高交互性,公平性好

吞吐量略低

多任務(wù)環(huán)境、桌面系統(tǒng)

mq-deadline

并行性好,適度排序,適配多種存儲(chǔ)

公平性較弱

多對(duì)列SSD設(shè)備以及高負(fù)載場(chǎng)景  

切換調(diào)度器方式如下,中間路徑需要根據(jù)實(shí)際存儲(chǔ)類(lèi)型變化:

sudo echo kyber > /sys/block/hda/queue/scheduler

2.Page Cache

Page Cache是Linux用于緩存數(shù)據(jù)的核心機(jī)制,通過(guò)將磁盤(pán)數(shù)據(jù)暫存到內(nèi)存中,減少磁盤(pán)IO次數(shù),我們將從Page Cache的查看、緩存管理、讀寫(xiě)交互以及頁(yè)面回收四個(gè)部分進(jìn)行介紹。

2.1 如何查看Page Cache

可以使用vmstat -n 1查看讀寫(xiě),其中主要信息就是cache字段,另外更為詳細(xì)的信息可以使用cat /proc/meminfo查看,其部分內(nèi)容如圖:

圖片圖片

2.2 緩存管理

緩存管理主要的三個(gè)結(jié)構(gòu)就是inode、page和address_space,其代表的含義和核心關(guān)聯(lián)如下:

1)inode表示文件元數(shù)據(jù),并通過(guò)i_mapping關(guān)聯(lián)對(duì)應(yīng)的address_space。

2)address_space是連接元數(shù)據(jù)inode和物理頁(yè)page的核心,每個(gè)address_space對(duì)應(yīng)一個(gè)打開(kāi)的文件,根據(jù)index來(lái)找到對(duì)應(yīng)頁(yè),并通過(guò)統(tǒng)一抽象的operations來(lái)適配不同文件系統(tǒng)。

3)page是物理頁(yè)結(jié)構(gòu),描述實(shí)際數(shù)據(jù)信息。

圖片圖片

2.3 緩存交互

緩存交互可以分為讀寫(xiě)操作,先來(lái)看讀:

1)讀操作,先檢查緩存再實(shí)際讀取,其流程圖和交互圖示如下:

圖片圖片

圖片圖片

2)寫(xiě)操作,先寫(xiě)緩存然后標(biāo)記為臟頁(yè),異步回寫(xiě),主要流程如下:

圖片圖片

2.4 緩存淘汰

緩存淘汰邏輯較為簡(jiǎn)單,使用的是LRU算法進(jìn)行Page Cahce中頁(yè)的淘汰。

3.總結(jié)

本文從兩個(gè)角度來(lái)描述了IO高效的實(shí)現(xiàn)方式,一個(gè)是合理調(diào)度磁盤(pán),一個(gè)是減少磁盤(pán)訪問(wèn)。了解了實(shí)現(xiàn)磁盤(pán)高效IO的思想,下一篇將會(huì)講解特殊的優(yōu)化,零拷貝技術(shù)。

責(zé)任編輯:武曉燕 來(lái)源: 程序員學(xué)習(xí)隨筆
相關(guān)推薦

2025-07-23 08:13:10

2024-10-17 16:47:05

磁盤(pán)I/O計(jì)算機(jī)

2019-12-02 09:45:45

Linux IO系統(tǒng)

2017-09-01 12:26:18

Linux調(diào)度器系統(tǒng)

2022-04-23 16:30:22

Linux磁盤(pán)性能

2019-02-25 08:40:28

Linux磁盤(pán)IO

2014-07-28 16:47:41

linux性能

2017-02-09 09:00:14

Linux IO調(diào)度器

2017-03-25 21:33:33

Linux調(diào)度器

2009-05-14 10:16:36

Oracle優(yōu)化磁盤(pán)

2010-06-25 09:47:29

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

2009-10-10 10:10:29

服務(wù)器IO

2025-09-15 01:45:00

2023-06-05 08:19:20

性能優(yōu)化CPU

2020-06-10 08:28:51

Kata容器I

2021-02-10 08:09:48

Netty網(wǎng)絡(luò)多路復(fù)用

2025-10-13 04:00:00

2022-07-28 11:09:44

Linux優(yōu)化IO

2011-01-14 09:25:28

LinuxIO機(jī)制

2025-08-07 01:00:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)