97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

營銷型網(wǎng)站優(yōu)化網(wǎng)站建設(shè)核心系統(tǒng)

鶴壁市浩天電氣有限公司 2026/01/24 14:04:22
營銷型網(wǎng)站優(yōu)化,網(wǎng)站建設(shè)核心系統(tǒng),復(fù)雜大型網(wǎng)站建設(shè)成本,做網(wǎng)絡(luò)傳銷網(wǎng)站犯罪嗎第一卷#xff1a;混沌初開 —— 啟動(dòng)、工具鏈與構(gòu)建系統(tǒng) (深度展開版) 本卷目標(biāo)#xff1a;在代碼還沒跑起來之前#xff0c;理解代碼是如何變成二進(jìn)制#xff0c;以及二進(jìn)制是如何被加載并控制 CPU 的。 第一章#xff1a;從按下電源到 Login Prompt (The Boot Process)…第一卷混沌初開 —— 啟動(dòng)、工具鏈與構(gòu)建系統(tǒng) (深度展開版)本卷目標(biāo)在代碼還沒跑起來之前理解代碼是如何變成二進(jìn)制以及二進(jìn)制是如何被加載并控制 CPU 的。第一章從按下電源到 Login Prompt (The Boot Process)大多數(shù)工程師只知道“BIOS - MBR - Bootloader - Kernel”。宗師級(jí)需要掌握每一步的寄存器狀態(tài)和內(nèi)存布局。1.1 固件層 (Firmware Phase)UEFI (Unified Extensible Firmware Interface):PE/COFF 格式UEFI 應(yīng)用其實(shí)就是 Windows 的 PE 格式。GPT (GUID Partition Table)放棄 MBR 的 512 字節(jié)限制。理解 LBA0 (Protective MBR) 和 LBA1 (GPT Header) 的結(jié)構(gòu)。SEC/PEI/DXE/BDS 階段理解 UEFI 的初始化階段特別是DXE (Driver Execution Environment)這是為什么現(xiàn)代 BIOS 可以支持鼠標(biāo)和網(wǎng)絡(luò)的原因。深度思考為什么 Secure Boot 需要簽名公鑰存在哪(PK, KEK, db, dbx)。1.2 引導(dǎo)加載層 (Bootloader - GRUB2)GRUB2 架構(gòu)Stage 1 (boot.img)寫入 MBR/GPT 前 440 字節(jié)除了加載 Stage 1.5/2 啥也干不了。Stage 1.5 (core.img)位于 MBR 和第一個(gè)分區(qū)之間的空隙。包含文件系統(tǒng)驅(qū)動(dòng) (ext4/xfs driver)否則無法讀取/boot。Stage 2讀取/boot/grub/grub.cfg加載內(nèi)核鏡像 (vmlinuz) 和初始內(nèi)存盤 (initrd/initramfs) 到內(nèi)存。1.3 內(nèi)核初始化層 (Kernel Initialization)這是源碼分析的起點(diǎn)arch/x86/boot/header.S。實(shí)模式到保護(hù)模式CPU 從 16-bit Real Mode 切換到 32-bit Protected Mode再到 64-bit Long Mode。開啟 A20 地址線設(shè)置 GDT (Global Descriptor Table)。解壓內(nèi)核vmlinuz是壓縮的 (zImage/bzImage)。內(nèi)核先自解壓 (arch/x86/boot/compressed/head_64.S)。start_kernel()init/main.c中的上帝函數(shù)。setup_arch(): 探測(cè) CPU 特性解析內(nèi)存分布 (e820 map)。mm_init(): 初始化內(nèi)存分配器 (Buddy System)。sched_init(): 初始化調(diào)度器。rest_init(): 創(chuàng)建 PID 1 (init) 和 PID 2 (kthreadd)。1.4 用戶空間初始化 (User Space Init)Initramfs (Initial RAM Filesystem)它是一個(gè) CPIO 格式的歸檔文件。目的加載掛載根文件系統(tǒng) (RootFS) 所需的驅(qū)動(dòng) (如 LVM, RAID, SCSI 模塊)。實(shí)驗(yàn)使用lsinitrd或解壓initramfs查看里面的 shell 腳本 (init)。Systemd (PID 1)并發(fā)啟動(dòng)Socket Activation 原理。依賴樹Requires, Wants, After, Before。Cgroups 掛載Systemd 將系統(tǒng)資源劃分為 slice (System, User, Machine)。第二章工具鏈與 ELF 格式 (The Toolchain)Linux 系統(tǒng)中沒有任何魔法一切皆由工具鏈構(gòu)建。2.1 編譯全鏈路 (GCC Internals)命令gcc -v -save-temps main.cCPP (C Pre-Processor)處理#include,#define。所有宏在這一步消失。CC1 (C Compiler)最核心部分。AST (Abstract Syntax Tree)將 C 代碼解析為樹狀結(jié)構(gòu)。GIMPLE/RTLGCC 的中間表示 (IR)。優(yōu)化 (O2/O3) 主要發(fā)生在這里死代碼消除、循環(huán)展開。Assembly輸出.s匯編文件。AS (Assembler)將匯編轉(zhuǎn)為機(jī)器碼 relocatable object (.o)。Collect2 / LD (Linker)將多個(gè).o和庫文件鏈接成最終可執(zhí)行文件。2.2 ELF 文件深度解剖 (Executable and Linkable Format)這是理解操作系統(tǒng)加載程序的基石。必須精通readelf和objdump。ELF HeaderMagic Number (7F 45 4C 46), 入口地址 (Entry Point)。Program Headers (Segments)告訴內(nèi)核如何把文件映射到內(nèi)存。LOADSegment: 哪些部分需要加載 (R, RW, RX)。Section Headers (Sections)鏈接時(shí)使用。.text: 代碼段 (Read-Exec)。.data: 已初始化的全局變量 (Read-Write)。.bss: 未初始化的全局變量 (占位符不占磁盤空間)。.rodata: 只讀數(shù)據(jù) (字符串常量)。符號(hào)表 (Symbols)readelf -s。理解 Function, Object, Weak, Strong 符號(hào)。Name ManglingC 中函數(shù)重載如何在符號(hào)表中區(qū)分。2.3 動(dòng)態(tài)鏈接機(jī)制 (Dynamic Linking)這是 Linux 運(yùn)行時(shí)的核心機(jī)制。PLT GOT (延遲綁定技術(shù))為什么調(diào)用printf時(shí)程序不知道printf的真實(shí)地址GOT (Global Offset Table)存放絕對(duì)地址的數(shù)據(jù)表。PLT (Procedure Linkage Table)一段跳轉(zhuǎn)代碼。過程第一次調(diào)用 - 查 PLT - 跳到 GOT (此時(shí)為空) - 回跳 PLT - 呼叫 Dynamic Linker (_dl_runtime_resolve) - 找到真實(shí)地址填入 GOT - 執(zhí)行。第二次調(diào)用 - 查 PLT - 跳到 GOT (已有地址) - 直接執(zhí)行。Interpreter/lib64/ld-linux-x86-64.so.2。是它在程序運(yùn)行前把依賴庫 (libc.so) 加載進(jìn)內(nèi)存的。第三章Shell 解釋器與系統(tǒng)編程基石Shell 不是一個(gè)簡單的應(yīng)用它是用戶與內(nèi)核交互的最簡接口。3.1 進(jìn)程創(chuàng)建模型Fork-Exec 悖論fork(): 復(fù)制當(dāng)前進(jìn)程包括打開的文件描述符、內(nèi)存、環(huán)境變量。execve(): 丟棄當(dāng)前進(jìn)程內(nèi)存加載新的 ELF。為什么不直接CreateProcess因?yàn)?Fork 允許在 Exec 之前修改子進(jìn)程配置如重定向文件描述符、改變信號(hào)掩碼。寫時(shí)復(fù)制 (COW)解釋為什么fork一個(gè) 64GB 內(nèi)存的進(jìn)程只需要幾毫秒。只復(fù)制了頁表并將 PTE 標(biāo)記為 Read-Only。3.2 管道與重定向的內(nèi)核實(shí)現(xiàn)文件描述符 (FD)它只是task_struct - files_struct - fd_array數(shù)組的索引。重定向 ()本質(zhì)是dup2(fd_file, 1)。將文件描述符 1 (Stdout) 的指針指向了新打開的文件結(jié)構(gòu)體。管道 (|)命令cmd1 | cmd2內(nèi)核創(chuàng)建了一個(gè)無名管道 (Pipe)本質(zhì)是環(huán)形緩沖區(qū) (Ring Buffer)。Shell 執(zhí)行fork兩次。子進(jìn)程 1dup2(pipe_write_end, 1)(Stdout - Pipe)。子進(jìn)程 2dup2(pipe_read_end, 0)(Stdin - Pipe)。Pipe Capacity默認(rèn) 64KB。如果 cmd1 寫太快cmd2 讀太慢cmd1 會(huì)被阻塞 (Blocked) 在write()系統(tǒng)調(diào)用上。3.3 信號(hào) (Signals)信號(hào)是軟中斷。注冊(cè)sigaction()系統(tǒng)調(diào)用。傳遞內(nèi)核在從內(nèi)核態(tài)返回用戶態(tài)前如系統(tǒng)調(diào)用返回、時(shí)鐘中斷返回檢查task_struct的pending信號(hào)位圖。處理如果已注冊(cè) Handler內(nèi)核會(huì)修改用戶棧壓入信號(hào)處理函數(shù)棧幀強(qiáng)行讓 CPU 跳轉(zhuǎn)到 Handler 執(zhí)行執(zhí)行完再調(diào)用sigreturn回到原斷點(diǎn)。第二卷乾坤挪移 —— 內(nèi)存管理子系統(tǒng) (MM)本卷目標(biāo)祛魅理解為什么top看到的 VIRT 很大但 RES 很小。溯源理解一次malloc到底觸發(fā)了多少內(nèi)核機(jī)制。優(yōu)化掌握如何通過 HugePages、NUMA 綁定和 Cache 親和性榨干硬件性能。第一章硬件基石 (The Hardware Layer)內(nèi)核的內(nèi)存管理代碼本質(zhì)上是在伺候硬件。不懂硬件特性就看代碼如看天書。1.1 MMU 與 TLB (地址轉(zhuǎn)換的性能瓶頸)MMU (Memory Management Unit)CPU 核心發(fā)出的地址都是虛擬地址 (Virtual Address)。MMU 負(fù)責(zé)查表頁表將虛擬地址轉(zhuǎn)換為物理地址 (Physical Address)然后通過總線發(fā)給 RAM。TLB (Translation Lookaside Buffer)本質(zhì)頁表存在內(nèi)存里查頁表太慢需多次訪存。TLB 是 CPU 內(nèi)部的高速緩存專門存“虛擬頁-物理頁”的映射。TLB Miss性能殺手。一旦 MissCPU 必須觸發(fā) Page Walk硬件遍歷頁表產(chǎn)生幾十個(gè)時(shí)鐘周期的停頓。TLB Shootdown多核 CPU 的噩夢(mèng)。當(dāng)一個(gè)核修改了頁表如munmap它必須通過 IPI (核間中斷) 通知其他核刷新 TLB這會(huì)引起巨大的鎖爭(zhēng)用和延遲。PCID (Process-Context ID)在舊 CPU 上進(jìn)程切換 (Context Switch) 必須清空 TLB因?yàn)?A 進(jìn)程的地址 0x1000 和 B 進(jìn)程的 0x1000 對(duì)應(yīng)的物理頁不同。PCID 允許 TLB 中同時(shí)存在不同進(jìn)程的條目大幅降低了上下文切換的開銷。1.2 CPU Cache 與 Cache LineCache Line (緩存行)CPU 不是按字節(jié)讀取內(nèi)存而是按行。x86_64 通常是 64 Bytes。性能啟示結(jié)構(gòu)體定義時(shí)如果兩個(gè)高頻競(jìng)爭(zhēng)的鎖放在一起 64B會(huì)導(dǎo)致False Sharing (偽共享)導(dǎo)致多核性能斷崖式下跌。需使用__cacheline_aligned對(duì)齊。MESI 協(xié)議多核之間保證緩存一致性的協(xié)議 (Modified, Exclusive, Shared, Invalid)。理解為什么volatile關(guān)鍵字在 C 語言中不足以保證并發(fā)安全它不管緩存一致性只管編譯器不優(yōu)化。1.3 NUMA (Non-Uniform Memory Access)拓?fù)浣Y(jié)構(gòu)在雙路/四路服務(wù)器上CPU 0 訪問插在 CPU 1 旁邊的內(nèi)存比訪問自己的內(nèi)存要慢 30% 以上。Zone Reclaim Mode理解為什么有時(shí)候系統(tǒng)還有內(nèi)存但卻頻繁觸發(fā) Swap因?yàn)楸镜毓?jié)點(diǎn)內(nèi)存不足且內(nèi)核配置為不愿去遠(yuǎn)程節(jié)點(diǎn)借內(nèi)存。第二章虛擬內(nèi)存 (Virtual Memory - The Illusion)每個(gè)進(jìn)程都以為自己獨(dú)占 48 位 (256TB) 的內(nèi)存空間。這是操作系統(tǒng)編織的最大的謊言。2.1 內(nèi)存布局 (Memory Layout)User Space (0 - 0x00007FFFFFFFFFFF)Text/Data/BSSELF 加載段。Heapbrk指針控制的區(qū)域向上增長。Mmap Region動(dòng)態(tài)庫、大塊內(nèi)存分配區(qū)向下增長通常在棧下方。Stack主線程棧向下增長默認(rèn) 8MB (ulimit -s)。Kernel Space (0xFFFF800000000000 - …)Direct Mapping (直接映射區(qū))物理內(nèi)存的 0-64TB 直接線性映射到這里phys_addr PAGE_OFFSET。內(nèi)核訪問物理內(nèi)存極其容易。Vmalloc Area用于vmalloc虛擬地址連續(xù)但物理地址不連續(xù)用于加載內(nèi)核模塊。2.2 核心結(jié)構(gòu)體mm_struct vm_area_structmm_struct進(jìn)程的內(nèi)存描述符。pgd_t * pgd指向頁全局目錄頁表的根。CR3 寄存器存的就是這個(gè)物理地址。vm_area_struct (VMA)內(nèi)核不記錄每一頁的狀態(tài)而是記錄“一段連續(xù)的虛擬內(nèi)存區(qū)域”。例如一段 VMA 是只讀的代碼段一段 VMA 是可寫的堆。數(shù)據(jù)結(jié)構(gòu)演進(jìn)鏈表 -紅黑樹 (Red-Black Tree)-Maple Tree (Linux 6.1)。隨著內(nèi)存越來越大紅黑樹的查找也嫌慢了最新的 Maple Tree 對(duì)范圍查找進(jìn)行了極致優(yōu)化。2.3 缺頁中斷 (Page Fault) —— 內(nèi)存管理的引擎當(dāng) CPU 訪問一個(gè)虛擬地址而頁表中 P (Present) 位為 0 時(shí)觸發(fā) #PF 異常陷入內(nèi)核do_page_fault。合法性檢查查找 VMA 紅黑樹。如果地址不在任何 VMA 內(nèi) -SIGSEGV (段錯(cuò)誤)。權(quán)限檢查如果 VMA 是只讀你試圖寫 -SIGSEGV。Handling (處理)Anonymous Page (匿名頁)如malloc新申請(qǐng)的內(nèi)存。內(nèi)核分配一個(gè)物理頁全填 0 (Security)修改頁表。這叫Minor Fault。File-backed Page (文件頁)如mmap一個(gè)文件。內(nèi)核啟動(dòng)磁盤 I/O將文件內(nèi)容讀入 Page Cache再映射到用戶空間。這叫Major Fault(此時(shí)進(jìn)程會(huì)進(jìn)入 Sleep 狀態(tài))。COW (Copy-On-Write)Fork 產(chǎn)生的只讀頁被寫入。內(nèi)核申請(qǐng)新物理頁拷貝數(shù)據(jù)將頁表改為可寫。第三章物理內(nèi)存管理 (Physical Memory - The Reality)內(nèi)核不僅要管理虛擬的幻象還要管理真實(shí)的硅片。3.1 物理尋址與 ZonesPFN (Page Frame Number)物理頁號(hào)。內(nèi)核用struct page結(jié)構(gòu)體每個(gè)結(jié)構(gòu)體 64字節(jié)管理每一個(gè)物理頁。計(jì)算如果你的機(jī)器有 128GB 內(nèi)存struct page數(shù)組本身就要占用約 2GB 內(nèi)存 (128GB / 4KB * 64B)。這叫Vmemmap開銷。ZonesZONE_DMA: 也就是低 16MB給老舊硬件 DMA 用。ZONE_NORMAL: 正常的內(nèi)存。ZONE_MOVABLE: 可熱插拔或可遷移用于減少碎片。3.2 伙伴系統(tǒng) (Buddy System)解決問題外部碎片 (External Fragmentation)。原理維護(hù) 11 個(gè)鏈表分別存 1, 2, 4, 8 … 1024 個(gè)連續(xù)頁塊 (Order 0 - Order 10)。分配申請(qǐng) 3 頁 - 找 Order 2 (4頁) - 拆分成 22 - 拿走一個(gè)剩下一個(gè)掛入 Order 1 鏈表。查看cat /proc/buddyinfo。3.3 Slab/Slub 分配器解決問題內(nèi)部碎片。內(nèi)核中大量小對(duì)象如task_struct,inode,dentry只有幾百字節(jié)給一整頁 (4KB) 太浪費(fèi)。Slub (默認(rèn))從 Buddy System 申請(qǐng)一整頁。切成無數(shù)小塊。Per-CPU Cache每個(gè) CPU 有自己的空閑對(duì)象鏈表分配時(shí)無鎖極快。實(shí)戰(zhàn)slabtop命令查看內(nèi)核都在緩存什么結(jié)構(gòu)體。如果dentry占用極高說明文件系統(tǒng)緩存太多。第四章內(nèi)存回收與 OOM (Reclaim OOM)出來混遲早要還的。當(dāng)物理內(nèi)存耗盡時(shí)內(nèi)核必須做出殘酷的決定。4.1 LRU 鏈表與頁面置換內(nèi)核維護(hù)四條 LRU (Least Recently Used) 鏈表Active Anon(活躍匿名頁)Inactive Anon(不活躍匿名頁)Active File(活躍文件頁 - Page Cache)Inactive File(不活躍文件頁)kswapd0內(nèi)核線程當(dāng)水位線 (Watermark) 低于low時(shí)喚醒掃描 Inactive 鏈表。如果是File頁直接釋放Clean或?qū)懟卮疟PDirty。如果是Anon頁必須寫入Swap 分區(qū)才能釋放。Swappiness/proc/sys/vm/swappiness(0-100)。60 (默認(rèn))傾向于回收 File 頁也適度使用 Swap。0只有當(dāng) File 頁很難回收時(shí)才用 Swap。誤區(qū)設(shè)為 0 不代表禁用 Swap只要物理內(nèi)存耗盡依然會(huì) Swap。4.2 反向映射 (Reverse Mapping - Rmap)難題當(dāng)內(nèi)核決定回收一個(gè)物理頁 P 時(shí)可能有 10 個(gè)進(jìn)程映射了它共享庫。內(nèi)核如何找到這 10 個(gè)進(jìn)程的頁表并把 PTE 設(shè)為 InvalidObj_rmap / Anon_rmapstruct page中有指針指向映射了它的 VMA 鏈表。這是內(nèi)存回收能工作的基石但也消耗了大量元數(shù)據(jù)空間。4.3 OOM Killer (終極審判)當(dāng)kswapd拼命回收也無法滿足新內(nèi)存請(qǐng)求時(shí)觸發(fā) Direct Reclaim如果還不行觸發(fā) OOM。Scores每個(gè)進(jìn)程初始分 內(nèi)存占用 (RSS)。OOM Score Adj/proc/pid/oom_score_adj(-1000 到 1000)。設(shè)為 -1000免死金牌如sshdsystemd。設(shè)為 1000優(yōu)先處決。第五章用戶態(tài)分配器 (glibc malloc)內(nèi)核只提供brk和mmap是glibc里的malloc幫我們管理了堆。5.1 Arena 與鎖競(jìng)爭(zhēng)Single Heap早期的malloc只有一塊堆多線程申請(qǐng)內(nèi)存需要爭(zhēng)搶一把大鎖 (mutex)。Arenas現(xiàn)在的malloc為每個(gè)線程或核心維護(hù)獨(dú)立的內(nèi)存池 (Arena)。Thread A 申請(qǐng) - Arena A (無鎖)。Thread B 申請(qǐng) - Arena B (無鎖)。內(nèi)存泄漏的假象有時(shí)候進(jìn)程free了內(nèi)存但 OS 沒看到 RSS 下降。原因free的內(nèi)存歸還給了 Arena 的 Bin (空閑鏈表)復(fù)用給下次malloc并沒有munmap還給內(nèi)核為了避免頻繁系統(tǒng)調(diào)用。5.2 性能調(diào)優(yōu)實(shí)戰(zhàn)HugePages (大頁)標(biāo)準(zhǔn)頁 4KB。大內(nèi)存應(yīng)用Oracle, Redis, DPDK頁表?xiàng)l目太多導(dǎo)致 TLB Miss。Transparent Huge Pages (THP)內(nèi)核自動(dòng)嘗試合并為 2MB 大頁。但有時(shí)會(huì)引起延遲抖動(dòng)合并過程需要鎖。Explicit Huge Pages (hugetlbfs)手動(dòng)預(yù)留 1GB 大頁TLB 命中率 100%。TCMalloc / JemallocGoogle 和 Facebook 為了解決 glibc malloc 的碎片和鎖問題開發(fā)的替代品。高并發(fā)服務(wù)器必備。第三卷萬物生息 —— 進(jìn)程管理與調(diào)度 (SCHED)本卷目標(biāo)解剖深入task_struct看到進(jìn)程的血肉。調(diào)度理解 CFS 算法如何用一顆紅黑樹實(shí)現(xiàn)“絕對(duì)公平”。并發(fā)看清自旋鎖、互斥鎖、RCU 背后的原子操作。第一章眾生相 —— 進(jìn)程描述符 (The Process Descriptor)在內(nèi)核眼中沒有“QQ音樂”或“Nginx”只有task_struct。這是 Linux 內(nèi)核中最大的結(jié)構(gòu)體之一在 x86_64 上有幾千字節(jié)記錄了一個(gè)生命體的一切。1.1task_struct解構(gòu)源碼位置include/linux/sched.h標(biāo)識(shí)符pid_t pid進(jìn)程 ID。pid_t tgid線程組 ID。注意在用戶態(tài)你看到的 PID其實(shí)是內(nèi)核里的 TGID。而在多線程程序中主線程的 PID TGID子線程有自己獨(dú)立的 PID但共享 TGID。狀態(tài) (state)TASK_RUNNING正在跑或者排隊(duì)等著跑。TASK_INTERRUPTIBLE淺睡眠等待 IO 或 信號(hào)能被kill喚醒。TASK_UNINTERRUPTIBLE深睡眠等待磁盤 IO不可殺即使kill -9也沒用因?yàn)樗豁憫?yīng)信號(hào)。如果 Load Average 飆高但 CPU 使用率不高通常就是有一堆這種進(jìn)程堵在磁盤 IO 上。親屬關(guān)系struct task_struct *parent父進(jìn)程。struct list_head children子進(jìn)程鏈表。實(shí)戰(zhàn)pstree命令就是遍歷這些指針畫出來的。1.2 它是怎么來的(Fork vs Clone)Linux 創(chuàng)建進(jìn)程極其高效因?yàn)樗鼧O其“懶惰”。Fork (傳統(tǒng))復(fù)制父進(jìn)程的task_struct。COW (Copy-On-Write)不復(fù)制內(nèi)存只復(fù)制頁表并標(biāo)記為只讀。Clone (現(xiàn)代)fork()和pthread_create()底層調(diào)用的都是clone()系統(tǒng)調(diào)用。Flags 決定一切CLONE_VM: 共享內(nèi)存線程。CLONE_FILES: 共享文件描述符線程。CLONE_NEWPID: 進(jìn)入新的 PID Namespace容器。內(nèi)核線程 (Kernel Threads)如kthreadd,ksoftirqd。它們沒有 mm指針mm為 NULL直接使用上一個(gè)進(jìn)程的內(nèi)核頁表。它們永遠(yuǎn)不會(huì)切換到用戶態(tài)。1.3 它是怎么沒的(Exit Wait)Do_exit進(jìn)程自殺調(diào)用exit或被殺。它會(huì)釋放內(nèi)存 (mm_put)、關(guān)閉文件 (files_put)但它不會(huì)釋放task_struct棧內(nèi)存。僵尸 (Zombie)此時(shí)進(jìn)程狀態(tài)變?yōu)镋XIT_ZOMBIE。它保留在內(nèi)核中只是為了把“退出碼 (Exit Code)”交給父進(jìn)程。收尸父進(jìn)程調(diào)用wait()讀取退出碼后內(nèi)核才會(huì)真正釋放task_struct(Slab 釋放)。第二章公平的藝術(shù) —— CFS 調(diào)度器 (The Scheduler)Linux 2.6.23 引入的CFS (Completely Fair Scheduler)是調(diào)度算法的里程碑。它的核心理念不再是“優(yōu)先級(jí)隊(duì)列”而是“物理模型”。2.1 理想多任務(wù)模型理念如果你有 N 個(gè)進(jìn)程CPU 應(yīng)該像流水一樣均分給它們。在任意時(shí)間段 T 內(nèi)每個(gè)進(jìn)程都應(yīng)該得到T/N的運(yùn)行時(shí)間。現(xiàn)實(shí)CPU 不能無限分割。所以 CFS 試圖讓每個(gè)進(jìn)程的虛擬運(yùn)行時(shí)間 (vruntime)保持一致。2.2 核心指標(biāo)vruntime公式vruntime實(shí)際運(yùn)行時(shí)間×1024進(jìn)程權(quán)重 vruntime 實(shí)際運(yùn)行時(shí)間 imes frac{1024}{進(jìn)程權(quán)重}vruntime實(shí)際運(yùn)行時(shí)間×進(jìn)程權(quán)重1024?權(quán)重 (Weight)由 Nice 值決定 (-20 到 19)。Nice 0 的權(quán)重是 1024。Nice -10 (高優(yōu)先級(jí)) 的權(quán)重很大分母變大 -vruntime漲得慢 - 總是比別人小 - 總是被調(diào)度。總結(jié)vruntime 越小越缺 CPU越需要被調(diào)度。2.3 核心數(shù)據(jù)結(jié)構(gòu)紅黑樹 (Red-Black Tree)內(nèi)核不用鏈表管理進(jìn)程O(n) 太慢而是用紅黑樹。Keyvruntime。邏輯樹的最左側(cè)節(jié)點(diǎn) (Leftmost Node)就是全系統(tǒng)vruntime最小的進(jìn)程。Pick Next調(diào)度器只需要把最左側(cè)節(jié)點(diǎn)取出來運(yùn)行即可。復(fù)雜度 O(1)因?yàn)榫彺媪?leftmost 指針。Enque進(jìn)程運(yùn)行了一會(huì)兒vruntime變大了把它放回樹里重新排序。復(fù)雜度 O(log N)。2.4 休眠與喚醒的作弊 (Place Entity)問題一個(gè)進(jìn)程睡了很久比如等待鍵盤輸入它的vruntime停滯了變得非常小。一旦醒來它會(huì)長期霸占 CPU 補(bǔ)課導(dǎo)致其他進(jìn)程卡頓。修正內(nèi)核維護(hù)一個(gè)min_vruntime當(dāng)前運(yùn)行隊(duì)列中最小的 vruntime。當(dāng)進(jìn)程醒來時(shí)內(nèi)核會(huì)重置它的 vruntimevruntime max(vruntime, min_vruntime - 補(bǔ)償)。既保證它能盡快搶到 CPU響應(yīng)快又不讓它餓死別人。第三章調(diào)度階級(jí) (Scheduling Classes)CFS 只是平民普通進(jìn)程的規(guī)則。Linux 內(nèi)核有著嚴(yán)格的階級(jí)制度。調(diào)度器在選擇下一個(gè)進(jìn)程時(shí)會(huì)按照以下順序遍歷調(diào)度類Stop Class(最高)用于 CPU 熱插拔、遷移等緊急任務(wù)。Deadline Class(SCHED_DEADLINE)硬實(shí)時(shí)。例如必須在 10ms 內(nèi)完成渲染?;?(Period, Runtime, Deadline) 模型。Real-Time Class(RT)SCHED_FIFO先進(jìn)先出。只要我不讓出 CPU誰也別想運(yùn)行。小心寫死循環(huán)會(huì)卡死整個(gè)核。SCHED_RR時(shí)間片輪轉(zhuǎn)。同優(yōu)先級(jí)的 RT 進(jìn)程輪流跑。Fair Class(CFS)SCHED_NORMAL絕大多數(shù)進(jìn)程都在這里。SCHED_BATCH適合不交互的批處理任務(wù)。Idle Class(最低)只有 CPU 沒事干時(shí)才跑它0 號(hào)進(jìn)程swapper。進(jìn)入省電模式 (C-State)。第四章乾坤大挪移 —— 上下文切換 (Context Switch)調(diào)度器決定換人后真正的“切換”動(dòng)作發(fā)生了。這是匯編級(jí)的藝術(shù)。4.1 切換流程函數(shù)context_switch()-switch_to()切換內(nèi)存 (switch_mm)更換 CR3 寄存器頁表基地址。優(yōu)化如果下一個(gè)進(jìn)程是內(nèi)核線程由于內(nèi)核空間頁表是一樣的不需要切換 CR3大大減少 TLB Miss。切換寄存器 (switch_to)保存當(dāng)前進(jìn)程的 RSP (棧指針), RIP (指令指針), RBP, RBX 等到task_struct。載入下一個(gè)進(jìn)程的寄存器。魔法瞬間當(dāng) RIP 載入的那一刻CPU 就開始執(zhí)行新進(jìn)程的代碼了。4.2 搶占 (Preemption)用戶態(tài)搶占當(dāng)系統(tǒng)調(diào)用返回用戶態(tài)或中斷處理返回用戶態(tài)時(shí)。檢查TIF_NEED_RESCHED標(biāo)志。如果置位調(diào)用schedule()。內(nèi)核態(tài)搶占 (Kernel Preemption)這是 Linux 低延遲的關(guān)鍵。即使 CPU 在內(nèi)核里跑比如正在執(zhí)行系統(tǒng)調(diào)用只要沒有持有自旋鎖高優(yōu)先級(jí)的進(jìn)程如鼠標(biāo)中斷也可以搶占它。第五章多核與并發(fā)原語 (SMP Locking)現(xiàn)在的服務(wù)器動(dòng)輒 64 核、128 核。如何防止它們打架5.1 負(fù)載均衡 (Load Balancing)每個(gè) CPU 都有自己的 Runqueue (rq)。理想情況下大家互不干擾。問題CPU 0 忙死CPU 1 閑死。機(jī)制Work StealingCPU 1 醒來發(fā)現(xiàn)自己沒事干去 CPU 0 的隊(duì)列里“偷”幾個(gè)任務(wù)過來。Scheduling DomainsSMT Domain (超線程)遷移成本極低共享 L1 Cache。MC Domain (多核)遷移成本中等共享 L3。NUMA Domain (跨路)遷移成本極高。5.2 鎖的物理學(xué) (Locking Primitives)當(dāng)多核同時(shí)訪問共享數(shù)據(jù)如dentry緩存必須加鎖。Spinlock (自旋鎖)行為while(lock_is_taken); // 忙等待。場(chǎng)景持有時(shí)間極短且不可睡眠中斷上下文。底層LOCK前綴指令 CAS (Compare-And-Swap) 原子操作。Mutex (互斥量)行為拿不到鎖就去睡覺 (Schedule Out)讓出 CPU。場(chǎng)景持有時(shí)間長可能發(fā)生 IO。Futex (Fast Userspace Mutex)性能神器。在沒有競(jìng)爭(zhēng)時(shí)完全在用戶態(tài)原子變量不需要陷入內(nèi)核系統(tǒng)調(diào)用。只有發(fā)生競(jìng)爭(zhēng)Contention時(shí)才 syscall 進(jìn)內(nèi)核掛起線程。Java 的synchronized和 Go 的Mutex底層都是 Futex。RCU (Read-Copy-Update)黑科技。內(nèi)核中最復(fù)雜的同步機(jī)制。理念讀鎖完全無開銷無鎖。寫者去拷貝一份數(shù)據(jù)修改改完指過去。等所有讀者讀完了舊數(shù)據(jù)再釋放舊內(nèi)存。場(chǎng)景讀多寫少如路由表、文件描述符表。第六章容器的心臟 —— Cgroups CPU 子系統(tǒng)Docker 限制 CPU 到底是怎么做到的6.1 CPU Bandwidth Control源碼kernel/sched/fair.c配額機(jī)制cpu.cfs_period_us(周期)通常 100ms。cpu.cfs_quota_us(配額)比如 20ms。原理內(nèi)核為每個(gè) Cgroup 維護(hù)一個(gè)vruntime賬本。容器里的進(jìn)程每跑 1ms扣除 1ms 配額。Throttling當(dāng)配額扣光時(shí)內(nèi)核強(qiáng)制把該 Cgroup 下的所有進(jìn)程踢出 Runqueue設(shè)為睡眠狀態(tài)。下一周期開始時(shí)重新注資喚醒進(jìn)程?,F(xiàn)象如果你發(fā)現(xiàn)容器 CPU 使用率才 20% 但響應(yīng)極慢檢查nr_throttled計(jì)數(shù)。這通常是因?yàn)橹芷谠O(shè)置不合理導(dǎo)致短時(shí)間內(nèi)配額耗盡被強(qiáng)制“關(guān)小黑屋”。第四卷經(jīng)絡(luò)血脈 —— 網(wǎng)絡(luò)協(xié)議棧 (NET)本卷目標(biāo)透視從網(wǎng)卡電信號(hào)到recv()返回追蹤一個(gè)數(shù)據(jù)包的奇幻漂流。解構(gòu)理解 Linux 網(wǎng)絡(luò)核心對(duì)象sk_buff的設(shè)計(jì)哲學(xué)。極速掌握 C10K/C10M 問題背后的 Epoll、零拷貝與 Kernel Bypass 技術(shù)。第一章從網(wǎng)線到內(nèi)存 (Layer 1 2 - The Driver Layer)數(shù)據(jù)包到達(dá)服務(wù)器時(shí)CPU 還毫不知情。網(wǎng)卡NIC是第一個(gè)接待員。1.1 DMA 與 Ring BufferDMA (Direct Memory Access)網(wǎng)卡內(nèi)部有一個(gè)Rx Ring Buffer接收環(huán)形緩沖區(qū)。這其實(shí)是主機(jī)內(nèi)存中的一段區(qū)域DMA 區(qū)域。當(dāng)光/電信號(hào)到達(dá)網(wǎng)卡控制器直接將數(shù)據(jù)搬運(yùn)到內(nèi)存中不需要 CPU 參與。硬中斷 (Hard IRQ)數(shù)據(jù)搬完后網(wǎng)卡發(fā)起一個(gè)硬件中斷告訴 CPU“喂有貨來了快來處理”。CPU 暫停當(dāng)前手頭的工作執(zhí)行網(wǎng)卡驅(qū)動(dòng)注冊(cè)的中斷處理函數(shù)。性能瓶頸如果每來一個(gè)包都中斷一次CPU 會(huì)被“中斷風(fēng)暴”淹沒Livelock導(dǎo)致用戶態(tài)進(jìn)程完全餓死。1.2 NAPI (New API) —— 中斷與輪詢的妥協(xié)Linux 2.6 引入 NAPI 機(jī)制解決中斷風(fēng)暴。第一個(gè)包到達(dá)觸發(fā)硬中斷。關(guān)閉中斷驅(qū)動(dòng)程序告訴網(wǎng)卡“先別發(fā)中斷了我去叫人”。喚醒軟中斷觸發(fā)NET_RX_SOFTIRQ。輪詢 (Polling)內(nèi)核線程ksoftirqd/n開始批量從 Ring Buffer 取包一次取budget個(gè)默認(rèn) 300 或 64?;謴?fù)中斷如果 Ring Buffer 空了重新開啟網(wǎng)卡硬中斷進(jìn)入休眠。1.3 核心數(shù)據(jù)結(jié)構(gòu)sk_buff(Socket Buffer)Linux 網(wǎng)絡(luò)棧的通用貨幣。理解它就能理解零拷貝。結(jié)構(gòu)包含head,data,tail,end四個(gè)指針。操作封包當(dāng) TCP 層要把數(shù)據(jù)傳給 IP 層時(shí)不需要拷貝數(shù)據(jù)只需要移動(dòng)data指針預(yù)留頭部空間填充 IP 頭即可??寺‘?dāng)tcpdump抓包時(shí)只需要拷貝sk_buff結(jié)構(gòu)體元數(shù)據(jù)不需要拷貝實(shí)際的數(shù)據(jù)負(fù)載 (Payload)。代價(jià)sk_buff結(jié)構(gòu)體本身較大200 字節(jié)高并發(fā)下頻繁分配釋放會(huì)造成 Slab 壓力。第二章協(xié)議棧的迷宮 (Layer 3 4 - IP TCP)軟中斷拿到了包開始向上層層遞交。2.1 網(wǎng)絡(luò)層的關(guān)卡 (IP Layer)路由子系統(tǒng) (FIB)數(shù)據(jù)包進(jìn)來內(nèi)核要問這是給我的還是路過的Local Process目的 IP 是本機(jī) - 往上送。Forward目的 IP 是別人且net.ipv4.ip_forward1- 查路由表轉(zhuǎn)發(fā)。FIB Trie路由表不是簡單的數(shù)組而是 LC-Trie (最長前綴匹配前綴樹)查找速度極快。Netfilter (防火墻基石)Iptables, IPVS, Docker, K8s Service 全靠它。5 Hook PointsPREROUTING(剛進(jìn)來還沒查路由)。INPUT(給本機(jī)的)。FORWARD(轉(zhuǎn)發(fā)的)。OUTPUT(本機(jī)發(fā)出的)。POSTROUTING(馬上要滾出去的)。Conntrack (連接跟蹤)Netfilter 會(huì)記錄每一條流的狀態(tài) (NEW, ESTABLISHED, RELATED)。這是 NAT (網(wǎng)絡(luò)地址轉(zhuǎn)換) 能工作的前提。故障典籍nf_conntrack: table full, dropping packet。這是高并發(fā)服務(wù)器常見故障意味著連接跟蹤表滿了內(nèi)核開始丟包。2.2 傳輸層的精密機(jī)器 (TCP Layer)這是內(nèi)核里最復(fù)雜的代碼之一。三次握手 (The Handshake)SYN Queue (半連接隊(duì)列)收到 SYN狀態(tài)變SYN_RECV放入此隊(duì)列。如果滿了開啟tcp_syncookies抵御攻擊。Accept Queue (全連接隊(duì)列)收到 ACK三次握手完成狀態(tài)變ESTABLISHED移入此隊(duì)列。應(yīng)用層應(yīng)用調(diào)用accept()就是從全連接隊(duì)列里取出一個(gè) Socket。擁塞控制 (Congestion Control)CUBIC (默認(rèn))基于丟包作為信號(hào)。一旦丟包窗口減半。在現(xiàn)代高帶寬網(wǎng)絡(luò)中過于保守。BBR (Google)基于帶寬和延遲 (BDP)模型。不看丟包看網(wǎng)絡(luò)是不是真的堵了。在弱網(wǎng)環(huán)境下能提升數(shù)倍吞吐量。重傳機(jī)制RTO (Retransmission Timeout)超時(shí)重傳慢。Fast Retransmit收到 3 個(gè)重復(fù) ACK立即重傳快。第三章Socket 接口與高性能網(wǎng)絡(luò) (Layer 5 - User Space)終于數(shù)據(jù)要交給用戶進(jìn)程了。3.1 Socket 的本質(zhì)Everything is a FileSocket 也是文件有inode有file_operations。接收緩沖區(qū)recv()不是直接從網(wǎng)卡讀。而是把內(nèi)核緩沖區(qū) (sk_receive_queue) 里的數(shù)據(jù)拷貝到用戶提供的 buffer 中。這就是網(wǎng)絡(luò) I/O 慢的根本原因上下文切換 內(nèi)存拷貝。3.2 I/O 模型的進(jìn)化BIO (Blocking I/O)read()沒數(shù)據(jù)就卡住線程。一個(gè)連接需要一個(gè)線程。并發(fā)上限 線程上限。NIO (Non-blocking I/O)read()沒數(shù)據(jù)返回EAGAIN。應(yīng)用層寫死循環(huán)輪詢。CPU 空轉(zhuǎn)發(fā)熱。I/O Multiplexing (多路復(fù)用)Select/Poll把 1000 個(gè) fd 給內(nèi)核“誰有數(shù)據(jù)告訴我不” 內(nèi)核遍歷一遍返回。缺點(diǎn)O(N)連接多了遍歷太慢。Epoll (Linux 專屬)RB-Tree在內(nèi)核里維護(hù)一個(gè)紅黑樹存所有待監(jiān)控的 socket。Callback當(dāng)網(wǎng)卡收到數(shù)據(jù)協(xié)議棧走到 TCP 層觸發(fā)回調(diào)把該 socket 加入Ready List (雙向鏈表)。Epoll_wait只需要查看 Ready List 有沒有東西。O(1)。C10K 問題Epoll 使得單機(jī)維護(hù) 100 萬長連接成為可能。第四章零拷貝與旁路技術(shù) (Zero Copy Kernel Bypass)即使是 Epoll依然要把數(shù)據(jù)從內(nèi)核拷貝到用戶態(tài)。在 40Gbps/100Gbps 網(wǎng)絡(luò)下這依然太慢。4.1 零拷貝 (Zero Copy)Sendfile傳統(tǒng)發(fā)文件Disk - Kernel Cache - User Buffer - Kernel Socket Buffer - NIC。 (4次拷貝4次切換)SendfileDisk - Kernel Cache - NIC。 (2次拷貝2次切換)。Kafka和Nginx高性能的秘訣。Splice兩個(gè)文件描述符之間傳遞數(shù)據(jù)如 Pipe 到 Socket完全在內(nèi)核完成零拷貝。4.2 Kernel Bypass (繞過內(nèi)核)如果內(nèi)核協(xié)議棧太慢那就不要用它了。DPDK (Data Plane Development Kit)Intel 推出的框架。UIO用戶態(tài)驅(qū)動(dòng)直接接管網(wǎng)卡 PCI 設(shè)備映射網(wǎng)卡內(nèi)存到用戶空間。PMD (Poll Mode Driver)一個(gè)死循環(huán)在 CPU 專核上狂轉(zhuǎn)輪詢網(wǎng)卡。無中斷、無拷貝、無系統(tǒng)調(diào)用。代價(jià)你需要自己實(shí)現(xiàn) TCP/IP 棧如 F-Stack。XDP (eXpress Data Path)Linux 內(nèi)核原生的 Bypass。在網(wǎng)卡驅(qū)動(dòng)層sk_buff分配之前運(yùn)行 eBPF 字節(jié)碼。場(chǎng)景DDOS 防御直接 Drop不進(jìn)協(xié)議棧、負(fù)載均衡直接修改 MAC/IP 轉(zhuǎn)發(fā)。第五章故障排查實(shí)戰(zhàn) (Troubleshooting)場(chǎng)景 1Ping 得通Curl 不通分析Ping 是 ICMP (Layer 3)Curl 是 TCP (Layer 4)??赡茉騃ptables 允許了 ICMP 但 DROP 了 TCP 80或者 MTU 問題大包被丟棄Ping 包小沒發(fā)現(xiàn)。場(chǎng)景 2TCP 連接建立慢伴有丟包工具dmesg | grep conntrack看是不是連接表滿了。工具netstat -s | grep listen queue看是不是全連接隊(duì)列溢出 (Syn Flood)。場(chǎng)景 3網(wǎng)卡中斷不均衡CPU 0 跑死其他核圍觀解決檢查irqbalance服務(wù)是否開啟。優(yōu)化配置RPS (Receive Packet Steering)或RFS軟件模擬多隊(duì)列把包分發(fā)給其他核處理。 第五卷有容乃大 —— 存儲(chǔ)與文件系統(tǒng) (VFS Storage)本卷目標(biāo)抽象徹底理解 VFS 四大對(duì)象明白為什么 socket 和 pipe 也是文件。路徑追蹤一個(gè)write()調(diào)用從 Page Cache 到 BIO 再到磁盤扇區(qū)的全過程。演進(jìn)掌握從傳統(tǒng)的 Journaling 到現(xiàn)代 CoW (Copy-on-Write) 文件系統(tǒng)的技術(shù)變革。第一章偉大的抽象 —— VFS (Virtual File System)Linux 支持 100 多種文件系統(tǒng)。為什么cp命令不需要針對(duì) ext4 寫一套代碼針對(duì) ntfs 寫一套代碼因?yàn)?VFS。1.1 VFS 四大金剛內(nèi)核中用 C 結(jié)構(gòu)體模擬了面向?qū)ο蟮睦^承多態(tài)。Superblock (超級(jí)塊)代表一個(gè)已掛載的文件系統(tǒng)如/dev/sda1。存儲(chǔ)元數(shù)據(jù)塊大小、魔數(shù)、Inode 總數(shù)。Inode (索引節(jié)點(diǎn))文件的靈魂。存儲(chǔ)權(quán)限、大小、時(shí)間戳、數(shù)據(jù)塊指針。唯一性在同一個(gè)文件系統(tǒng)中Inode 號(hào)是唯一的。注意Inode 不包含文件名文件名只是目錄中的記錄。Dentry (目錄項(xiàng))文件名的載體。連接文件名和 Inode。Dentry Cache (Dcache)內(nèi)核為了加速路徑查找如/etc/nginx/nginx.conf會(huì)緩存解析過的目錄項(xiàng)。內(nèi)存泄漏高發(fā)區(qū)如果大量生成臨時(shí)文件名如 PHP 的 session 文件Dcache 會(huì)迅速吃光 RAM。File (文件對(duì)象)代表進(jìn)程打開的文件。包含核心字段f_pos(當(dāng)前讀寫偏移量)。區(qū)別兩個(gè)進(jìn)程打開同一個(gè)文件有 2 個(gè)struct file但共享 1 個(gè)struct inode。1.2 掛載 (Mount) 與命名空間Mount Point掛載點(diǎn)其實(shí)就是覆蓋了原目錄的 Dentry。Bind Mountmount --bind /A /B。讓兩個(gè)目錄指向同一個(gè) Dentry。容器中掛載 Volume 就是用的這個(gè)。Mount Namespace容器隔離的基礎(chǔ)。每個(gè)容器有自己獨(dú)立的掛載樹互不干擾。第二章數(shù)據(jù)的高速公路 —— I/O 棧 (The I/O Stack)write()返回成功了數(shù)據(jù)就存好了嗎差得遠(yuǎn)呢。2.1 Page Cache (頁緩存)Write Back (回寫)write()只是把用戶態(tài)數(shù)據(jù)拷貝到了內(nèi)核態(tài)的Page Cache(Radix Tree/XArray 管理)。頁面被標(biāo)記為Dirty (臟頁)。write()隨即返回。速度極快。內(nèi)核線程kworker后臺(tái)異步將臟頁刷入磁盤。風(fēng)險(xiǎn)如果此時(shí)斷電數(shù)據(jù)丟失。Write Through / Sync調(diào)用fsync()或open(O_SYNC)。強(qiáng)制立刻刷盤寫完才返回。慢但安全數(shù)據(jù)庫 WAL 日志必備。2.2 通用塊層 (Block Layer)BIO (Block I/O)當(dāng) Page Cache 決定刷盤或者發(fā)生缺頁讀取時(shí)會(huì)組裝一個(gè)struct bio。合并與排序塊層會(huì)將對(duì)相鄰扇區(qū)的多個(gè) BIO 合并成一個(gè) Request以減少機(jī)械臂移動(dòng)HDD或各種開銷。I/O 調(diào)度器CFQ(已淘汰)完全公平隊(duì)列針對(duì)機(jī)械盤優(yōu)化。Deadline保證讀寫延遲不超過最后期限。NOOP/None啥也不干。NVMe SSD 必選因?yàn)?SSD 隨機(jī)讀寫極快不需要排序CPU 排序反而是累贅。2.3 異步 I/O 的進(jìn)化AIO (Legacy)僅支持 Direct I/O限制多難用。io_uring (Modern)Linux 5.1 引入的神器?;赟Q/CQ (提交/完成) 環(huán)形隊(duì)列用戶態(tài)和內(nèi)核態(tài)共享內(nèi)存。零系統(tǒng)調(diào)用批量提交 I/O 請(qǐng)求無需頻繁陷入內(nèi)核。性能碾壓 Epoll AIO。第三章文件系統(tǒng)內(nèi)幕 (EXT4 XFS)3.1 EXT4 的數(shù)據(jù)一致性突然斷電了文件系統(tǒng)會(huì)壞嗎Journaling (日志)JBD2Ext4 的日志子系統(tǒng)。流程寫數(shù)據(jù)前先在日志區(qū)記錄“我要寫數(shù)據(jù)了” (Transaction) - 寫實(shí)際數(shù)據(jù) - 在日志區(qū)記錄“我寫完了” (Commit)。模式dataordered(默認(rèn))只記錄元數(shù)據(jù)日志但保證先寫數(shù)據(jù)再寫元數(shù)據(jù)。性能與安全平衡。datawriteback最快但斷電可能導(dǎo)致文件內(nèi)容包含舊垃圾數(shù)據(jù)。datajournal所有數(shù)據(jù)都寫兩次。最慢最安全。3.2 現(xiàn)代特性Extent Tree老文件系統(tǒng)用“塊列表”記錄大文件元數(shù)據(jù)太大。Extent 用(起始?jí)K, 長度)記錄高效管理大文件。Delayed Allocation (延遲分配)數(shù)據(jù)先寫在 Cache 里不急著分配磁盤塊。等刷盤時(shí)一次性分配一大塊連續(xù)空間減少碎片。第四章下一代存儲(chǔ)技術(shù) (CoW Overlay)4.1 Copy-On-Write (Btrfs/ZFS)原理修改數(shù)據(jù)時(shí)不覆蓋原位置而是找個(gè)新地方寫然后修改指針指向新地方。優(yōu)勢(shì)秒級(jí)快照快照只是復(fù)制了一份 B 樹的根指針不拷貝數(shù)據(jù)。數(shù)據(jù)校驗(yàn)每個(gè)塊都有 Checksum徹底解決靜默數(shù)據(jù)損壞 (Bit Rot)。4.2 OverlayFS (容器存儲(chǔ))Docker 鏡像分層的秘密。結(jié)構(gòu)LowerDir(只讀)基礎(chǔ)鏡像層 (Image Layers)。UpperDir(讀寫)容器層 (Container Layer)。MergedDir用戶看到的掛載點(diǎn)。寫操作當(dāng)你要修改基礎(chǔ)鏡像里的/etc/hosts時(shí)OverlayFS 會(huì)觸發(fā)Copy-up把文件從 LowerDir 復(fù)制到 UpperDir然后修改 UpperDir 里的副本。這也是為什么在容器里修改大文件如數(shù)據(jù)庫數(shù)據(jù)文件會(huì)很慢的原因。第六卷天眼洞察 —— 虛擬化與可觀測(cè)性 (Virtualization Observability)本卷目標(biāo)矩陣從硬件虛擬化到輕量級(jí)容器理解“云”的本質(zhì)。天眼掌握 eBPF 和 Perf將 Linux 內(nèi)核變成透明的水晶。心法學(xué)會(huì)系統(tǒng)級(jí)性能調(diào)優(yōu)的方法論。第一章虛擬化基石 (KVM QEMU)云服務(wù)器 (EC2/CVM) 到底是什么1.1 CPU 虛擬化 (VT-x)Root Mode vs Non-Root ModeIntel CPU 引入的新模式。Host OS 運(yùn)行在 Root 模式Guest OS 運(yùn)行在 Non-Root 模式。VM-Exit當(dāng) Guest OS 試圖執(zhí)行敏感指令如修改頁表、IO 操作時(shí)CPU 強(qiáng)制暫停 Guest切回 Root 模式交給 KVM 處理。這是虛擬化開銷的主要來源。vCPU在 Linux 看來一個(gè) vCPU 就是一個(gè)普通的 QEMU 線程 (task_struct)。1.2 內(nèi)存與 I/O 虛擬化EPT (Extended Page Tables)硬件支持的二級(jí)地址翻譯。Guest 虛擬地址 - Guest 物理地址 - Host 物理地址。無需 KVM 軟件模擬頁表 (Shadow Page Table)性能大增。VirtIO (半虛擬化)Guest OS 知道自己是虛擬機(jī)不裝傻去讀寫 IDE 寄存器而是通過共享內(nèi)存隊(duì)列 (Virtqueue)直接把數(shù)據(jù)扔給宿主機(jī)。第二章容器技術(shù) (Container Internals)Docker/K8s 沒有任何“黑科技”只是組合了 Linux 的現(xiàn)有功能。Namespace (隔離)決定了你能看見什么。PID: 也就是ps只能看到容器內(nèi)的進(jìn)程。NET: 獨(dú)立的網(wǎng)卡、IP、路由表、Iptables。Cgroups (限制)決定了你能用多少。文件系統(tǒng)接口/sys/fs/cgroup/。K8s 的 QoS (Guaranteed/Burstable) 就是通過調(diào)整cpu.shares和cpu.cfs_quota_us實(shí)現(xiàn)的。Capabilities (權(quán)限)Root 不再是全能神。將 Root 權(quán)限拆分為細(xì)粒度權(quán)限如CAP_NET_ADMIN,CAP_SYS_TIME。容器默認(rèn)雖然是 Root 運(yùn)行但被剝奪了絕大多數(shù) Cap所以無法修改系統(tǒng)時(shí)間或加載內(nèi)核模塊。第三章上帝視角 —— eBPF 與可觀測(cè)性傳統(tǒng)的監(jiān)控Top, Zabbix只能告訴你“CPU 高”eBPF 能告訴你“CPU 都在執(zhí)行哪個(gè)函數(shù)”。3.1 eBPF內(nèi)核的可編程性革命Linux 內(nèi)核不僅是可配置的現(xiàn)在是可編程的。Verifier在加載字節(jié)碼前內(nèi)核會(huì)進(jìn)行極其嚴(yán)格的安全檢查防止死循環(huán)、內(nèi)存越界確保不會(huì)搞崩系統(tǒng)。MapseBPF 程序內(nèi)核態(tài)和用戶態(tài)程序Go/Python通過 MapHash/Array共享數(shù)據(jù)。3.2 動(dòng)態(tài)追蹤實(shí)戰(zhàn)Kprobe/Kretprobe在任意內(nèi)核函數(shù)的入口和出口插樁。Uprobe在用戶態(tài)函數(shù)如 MySQL 的dispatch_command插樁。Tracepoints內(nèi)核源碼里預(yù)留的穩(wěn)定靜態(tài)鉤子。場(chǎng)景抓取所有執(zhí)行open(/etc/passwd)的進(jìn)程 PID。統(tǒng)計(jì) TCP 重傳率最高的 IP。繪制 Off-CPU 火焰圖分析進(jìn)程睡著時(shí)在等什么鎖。第四章宗師的心法 —— 性能調(diào)優(yōu)方法論工具只是術(shù)方法論才是道。4.1 USE 方法 (Utilization, Saturation, Errors)Brendan Gregg 提出針對(duì)任何資源CPU/內(nèi)存/磁盤/網(wǎng)絡(luò)Utilization (利用率)忙的時(shí)間比例是多少(如磁盤 IO 利用率 90%)Saturation (飽和度)有多少任務(wù)在排隊(duì)(如 Load Average, Wait Queue)Errors (錯(cuò)誤)有沒有報(bào)錯(cuò)(如 Dropped Packets, IO Errors)4.2 性能分析檢查清單 (Checklist)當(dāng)面對(duì)一臺(tái)慢機(jī)器uptime- 看 Load Avg (系統(tǒng)堵沒堵)。dmesg | tail- 看內(nèi)核有沒有報(bào)錯(cuò) (OOM, 硬件錯(cuò)誤)。vmstat 1- 看r(運(yùn)行隊(duì)列),b(IO等待),si/so(Swap)。mpstat -P ALL 1- 看有沒有單核跑死。pidstat 1- 找元兇進(jìn)程。iostat -xz 1- 看磁盤利用率和延遲。sar -n DEV 1- 看網(wǎng)絡(luò)吞吐。perf top/profile- 抓火焰圖看代碼熱點(diǎn)。
版權(quán)聲明: 本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

網(wǎng)站系統(tǒng)開發(fā)在線查詢營業(yè)執(zhí)照

網(wǎng)站系統(tǒng)開發(fā),在線查詢營業(yè)執(zhí)照,織夢(mèng)模板首頁修改,wordpress 用戶權(quán)限分配PyTorch鏡像運(yùn)行Flask API服務(wù)#xff1a;模型部署新模式 在AI應(yīng)用從實(shí)驗(yàn)室走向生產(chǎn)線的過程中#xff

2026/01/23 18:38:02

溫泉網(wǎng)站建設(shè)小程序開店流程

溫泉網(wǎng)站建設(shè),小程序開店流程,怎樣更新目錄wordpress,WordPress首頁登錄插件MonitorControl#xff1a;讓你的Mac外接顯示器亮度控制更智能 【免費(fèi)下載鏈接】Monito

2026/01/23 16:10:02

上海企業(yè)建站步驟做網(wǎng)站為什么要做備案接入

上海企業(yè)建站步驟,做網(wǎng)站為什么要做備案接入,網(wǎng)站首頁關(guān)鍵字方案,網(wǎng)站的營銷推廣Wan2.2-T2V-A14B如何確保醫(yī)學(xué)解剖結(jié)構(gòu)的準(zhǔn)確性#xff1f; 在數(shù)字醫(yī)療飛速發(fā)展的今天#xff0c;我們正見證

2026/01/23 16:40:01

怎么做可上傳圖片的網(wǎng)站在哪里申請(qǐng)網(wǎng)站域名

怎么做可上傳圖片的網(wǎng)站,在哪里申請(qǐng)網(wǎng)站域名,攝像頭監(jiān)控設(shè)備企業(yè)網(wǎng)站模板,微信小程序怎么關(guān)閉防沉迷鳴潮自動(dòng)化工具完全指南#xff1a;從零開始掌握智能游戲輔助技術(shù) 【免費(fèi)下載鏈接】ok-wutherin

2026/01/23 02:12:01

做網(wǎng)站原型圖軟件網(wǎng)站建設(shè)技術(shù)開發(fā)

做網(wǎng)站原型圖軟件,網(wǎng)站建設(shè)技術(shù)開發(fā),百度網(wǎng)站制作公司,浙江建設(shè)局網(wǎng)站首頁KindEditor是一款優(yōu)秀的開源富文本編輯器#xff0c;專為Web開發(fā)者設(shè)計(jì)#xff0c;讓網(wǎng)頁內(nèi)容編輯變得前所未有的簡單

2026/01/21 17:54:01