Apakah penampan linux
Apr 21, 2023 pm 07:35 PMDi Linux, Buffer merujuk kepada penimbal, iaitu kawasan yang digunakan untuk menyimpan data antara peranti dengan kelajuan tidak disegerakkan atau peranti dengan keutamaan yang berbeza Ia adalah keseimbangan kelajuan pemprosesan di kedua-dua hujung sistem (dari a lama Ia digunakan apabila melihat skala); ia diperkenalkan untuk mengurangkan kesan letusan I/O dalam jangka pendek dan memainkan peranan membentuk trafik.
Persekitaran pengendalian tutorial ini: sistem linux7.3, komputer Dell G3.
Apakah penimbal dan cache?
1. Ia diperkenalkan untuk mengurangkan kesan I/O pecah dalam jangka pendek dan memainkan peranan membentuk trafik.
Penimbal ialah kawasan yang digunakan untuk menyimpan data yang dipindahkan antara peranti dengan kelajuan tidak disegerakkan atau peranti dengan keutamaan yang berbeza. Melalui penimbal, penantian antara satu sama lain antara proses dapat dikurangkan, supaya apabila data dibaca dari peranti yang perlahan, proses operasi peranti pantas tidak akan terganggu.
Contohnya: jika kita menggunakan X Thunder untuk memuat turun filem, adalah mustahil untuk memuat turun sedikit dan kemudian menulis sedikit pada cakera Tindakan sedemikian akan memusnahkan cakera keras. Sebaliknya, tulis kepada penimbal dahulu, dan kemudian tulis pada cakera sekali gus untuk mengurangkan I/O, yang kedua-duanya cekap dan mesra cakera keras.
2. Cache ialah strategi kompromi apabila kelajuan pemprosesan kedua-dua hujung tidak sepadan. Oleh kerana perbezaan kelajuan antara CPU dan memori semakin besar, orang ramai menggunakan sepenuhnya ciri-ciri tempatan data dan mengurangkan kesan perbezaan ini dengan menggunakan strategi hierarki sistem storan (hierarki memori).
Memahami Cache dan Buffer Linux
cache merujuk kepada cache halaman dalam Linux dan buffer merujuk kepada cache buffer, yang dipaparkan dalam cache cat /proc/meminfo dan penimbal.
Kami tahu bahawa apabila fail atau satu fail besar kerap diakses di bawah Linux, memori fizikal akan cepat habis Apabila program tamat, memori tidak akan dilepaskan secara normal tetapi akan sentiasa menduduki memori sebagai cahce. Oleh itu, sistem sering menyebabkan OOM kerana ini, terutamanya dalam senario tekanan tinggi Pada masa ini, adalah sangat tinggi untuk memeriksa cache dan memori penimbal pada kali pertama. Pada masa ini tidak ada penyelesaian yang baik untuk jenis masalah ini Pada masa lalu, kebanyakan orang yang menghadapinya akan mengelakkannya. Oleh itu, kes ini cuba memberikan idea analisis dan penyelesaian.
Kunci untuk menyelesaikan masalah ini ialah memahami apa itu cache dan penimbal, bila dan di mana ia digunakan serta cara mengawal cache dan penimbal, jadi soalan ini tertumpu terutamanya pada perkara ini. Keseluruhan proses perbincangan harus bermula dengan analisis kod sumber kernel sebanyak mungkin, kemudian memperhalusi antara muka berkaitan APP dan menjalankan pengesahan praktikal, dan akhirnya merumuskan dan memberi cadangan pengaturcaraan aplikasi.
Anda boleh menyemak status penimbal dan cache sistem melalui percuma atau cat /proc/meminfo.
Analisis penuh arahan bebas
1. Untuk memulakan, mari kita lihat dahulu pelaksanaan antara muka ini:
Antaranya, bingkai halaman digunakan sebagai unit dalam kernel, dan makro K digunakan untuk menukarnya kepada KB sebagai unit untuk keluaran. Nilai ini diperoleh melalui si_meminfo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
di mana bufferram berasal dari nr_blockdev_pages(). bingkai halaman digunakan. Ia tidak termasuk bilangan bingkai halaman yang digunakan oleh fail biasa.
1 2 3 4 5 6 7 8 9 10 |
|
Daripada perkara di atas, kita boleh menyimpulkan sumber cache dan penimbal dalam meminfo:
1 2 3 4 5 6 7 8 9 10 11 |
|
Penimbal ialah bilangan bingkai halaman yang diduduki oleh peranti blok;
Saiz Cache ialah Jumlah cache halaman kernel tolak bilangan bingkai halaman yang diduduki oleh cache swap dan peranti sekat Sebenarnya, cache adalah cache halaman yang diduduki oleh fail biasa.- Melalui analisis kod kernel (analisis kod kernel kompleks dilangkau di sini), walaupun perbezaan pelaksanaan antara kedua-duanya tidak begitu besar, kedua-duanya diuruskan melalui objek address_space, tetapi cache halaman adalah untuk fail Cache data dan cache buffer ialah cache data peranti blok. Setiap peranti blok akan diberikan kaedah operasi fail def_blk_ops Ini adalah kaedah pengendalian peranti akan ada pokok radix di bawah inod setiap peranti blok (inod sistem fail pseudo bdev ini akan diletakkan Halaman data cache. Nombor halaman ini akan dipaparkan dalam lajur cat /proc/meminfobuffer. Maksudnya, jika tiada sistem fail, data yang dikendalikan secara langsung pada peranti blok menggunakan alat seperti dd akan dicache dalam cache penimbal. Jika peranti blok digunakan sebagai sistem fail, maka setiap fail dalam sistem fail mempunyai inode, dan inode ini akan diberikan kaedah operasi seperti ext3_ops Kaedah ini adalah kaedah sistem fail , dan terdapat juga Halaman fail akan dicache Bilangan halaman cache dikira dalam lajur cache cat /proc/meminfo. Apabila beroperasi pada fail pada masa ini, kebanyakan data akan dicache dalam cache halaman, dan metadata fail sistem fail akan dicache dalam cache penimbal. Di sini, kami menggunakan arahan cp untuk menyalin operasi fail 50MB, apa yang akan berlaku kepada memori:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
可以看到cp命令前后,MemFree从65696 kB减少为13012 kB,Cached从8148 kB增大为60488 kB,而Buffers却不变。那么过一段时间,Linux会自动释放掉所用的cache内存吗?一个小时后查看proc/meminfo显示cache仍然没有变化。
接着,我们看下使用dd命令对块设备写操作前后的内存变化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
裸写块设备前Buffs为0,裸写硬盘过程中每隔一段时间查看内存信息发现Buffers一直在增加,空闲内存越来越少,而Cached数量一直保持不变。
总结:
通过代码分析及实际操作,我们理解了buffer cache和page cache都会占用内存,但也看到了两者的差别。page cache针对文件的cache,buffer是针对块设备数据的cache。Linux在可用内存充裕的情况下,不会主动释放page cache和buffer cache。
2. 使用posix_fadvise控制Cache
在Linux中文件的读写一般是通过buffer io方式,以便充分利用到page cache。
Buffer IO的特点是读的时候,先检查页缓存里面是否有需要的数据,如果没有就从设备读取,返回给用户的同时,加到缓存一份;写的时候,直接写到缓存去,再由后台的进程定期刷到磁盘去。这样的机制看起来非常的好,实际也能提高文件读写的效率。
但是当系统的IO比较密集时,就会出问题。当系统写的很多,超过了内存的某个上限时,后台的回写线程就会出来回收页面,但是一旦回收的速度小于写入的速度,就会触发OOM。最关键的是整个过程由内核参与,用户不好控制。
那么到底如何才能有效的控制cache呢?
目前主要由两种方法来规避风险:
- 走direct io;
- 走buffer io,但是定期清除无用page cache;
这里当然讨论的是第二种方式,即在buffer io方式下如何有效控制page cache。
在程序中只要知道文件的句柄,就能用:
1 |
|
POSIX_FADV_DONTNEED (该文件在接下来不会再被访问),但是曾有开发人员反馈怀疑该接口的有效性。那么该接口确实有效吗?首先,我们查看mm/fadvise.c内核代码来看posix_fadvise是如何实现的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
我们可以看到如果后台系统不忙的话,会先调用__filemap_fdatawrite_range把脏页面刷掉,刷页面用的参数是是 WB_SYNC_NONE,也就是说不是同步等待页面刷新完成,提交完写脏页后立即返回了。
然后再调invalidate_mapping_pages清除页面,回收内存:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
|
看到这里我们就明白了:为什么使用了posix_fadvise后相关的内存没有被释放出来:页面还脏是最关键的因素。
但是我们如何保证页面全部不脏呢?fdatasync或者fsync都是选择,或者Linux下新系统调用sync_file_range都是可用的,这几个都是使用WB_SYNC_ALL模式强制要求回写完毕才返回的。所以应该这样做:
1 2 |
|
总结:
使用posix_fadvise可以有效的清除page cache,作用范围为文件级。下面给出应用程序编程建议:
- 用于测试I/O的效率时,可以用posix_fadvise来消除cache的影响;
- 当确认访问的文件在接下来一段时间不再被访问时,很有必要调用posix_fadvise来避免占用不必要的可用内存空间。
- 若当前系统内存十分紧张时,且在读写一个很大的文件时,为避免OOM风险,可以分段边读写边清cache,但也直接导致性能的下降,毕竟空间和时间是一对矛盾体。
3. 使用vmtouch控制Cache
vmtouch是一个可移植的文件系统cahce诊断和控制工具。近来该工具被广泛使用,最典型的例子是:移动应用Instagram(照片墙)后台服务端使用了vmtouch管理控制page cache。了解vmtouch原理及使用可以为我们后续后端设备所用。
快速安装指南:
1 2 3 4 |
|
vmtouch用途:
- 查看一个文件(或者目录)哪些部分在内存中;
- 把文件调入内存;
- 把文件清除出内存,即释放page cache;
- 把文件锁住在内存中而不被换出到磁盘上;
- ……
vmtouch实现:
其核心分别是两个系统调用,mincore和posix_fadvise。两者具体使用方法使用man帮助都有详细的说明。posix_fadvise已在上文提到,用法在此不作说明。简单说下mincore:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
mincore需要调用者传入文件的地址(通常由mmap()返回),它会把文件在内存中的情况写在vec中。
vmtouch工具用法:
Usage:vmtouch [OPTIONS] ... FILES OR DIRECTORIES ...
Options:
- -t touch pages into memory
- -e evict pages from memory
- -l lock pages in physical memory with mlock(2)
- -L lock pages in physical memory with mlockall(2)
- -d daemon mode
- -m
max file size to touch - -p
use the specified portion instead of the entire file - -f follow symbolic links
- -h also count hardlinked copies
- -w wait until all pages are locked (only useful together with -d)
- -v verbose
- -q quiet
用法举例:
例1、 获取当前/mnt/usb目录下cache占用量
1 2 3 4 5 6 |
|
例2、 当前test.bin文件的cache占用量?
1 2 3 4 5 6 7 8 9 |
|
这时使用tail命令将部分文件读取到内存中:
1 |
|
现在再来看一下:
1 2 3 4 5 6 7 8 9 |
|
可知目前文件test.bin的最后240个page驻留在内存中。
例3、 最后使用-t选项将剩下的test.bin文件全部读入内存:
1 2 3 4 5 6 7 8 9 |
|
例4、 再把test.bin占用的cachae全部释放:
1 2 3 4 5 6 7 8 |
|
这时候再来看下是否真的被释放了:
1 2 3 4 5 6 7 8 9 |
|
以上通过代码分析及实际操作总结了vmtouch工具的使用,建议APP组后续集成或借鉴vmtouch工具并灵活应用到后端设备中,必能达到有效管理和控制page cache的目的。
4. 使用BLKFLSBUF清Buffer
通过走读块设备驱动IOCTL命令实现,发现该命令能有效的清除整个块设备所占用的buffer。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
光代码不够,现在让我们看下对/dev/h_sda这个块设备执行BLKFLSBUF的IOCTL命令前后的实际内存变化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
执行的效果如代码中看到的,Buffers已被全部清除了,MemFree一下增长了约46MB,可以知道原先的Buffer已被回收并转化为可用的内存。整个过程Cache几乎没有变化,仅增加的8K cache内存可以推断用于a.out本身及其他库文件的加载。
上述a.out的示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
综上,使用块设备命令BLKFLSBUF能有效的清除块设备上的所有buffer,且清除后的buffer能立即被释放变为可用内存。
利用这一点,联系后端业务场景,给出应用程序编程建议:
- 每次关闭一个块设备文件描述符前,必须要调用BLKFLSBUF命令,确保buffer中的脏数据及时刷入块设备,避免意外断电导致数据丢失,同时也起到及时释放回收buffer的目的。
- 当操作一个较大的块设备时,必要时可以调用BLKFLSBUF命令。怎样算较大的块设备?一般理解为当前Linux系统可用的物理内存小于操作的块设备大小。
5. 使用drop_caches控制Cache和Buffer
/proc是一个虚拟文件系统,我们可以通过对它的读写操作作为与kernel实体间进行通信的一种手段.也就是说可以通过修改/proc中的文件来对当前kernel的行为做出调整。关于Cache和Buffer的控制,我们可以通过echo 1 > /proc/sys/vm/drop_caches进行操作。
首先来看下内核源码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
|
综上,echo 1 > /proc/sys/vm/drop_caches会清除所有inode的缓存页,这里的inode包括VFS的inode、所有文件系统inode(也包括bdev伪文件系统块设备的inode的缓存页)。所以该命令执行后,就会将整个系统的page cache和buffer cache全部清除,当然前提是这些cache都是非脏的、没有正被使用的。
接下来看下实际效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
可以看到Buffers和Cached都降了下来,在drop_caches前建议执行sync命令,以确保数据的完整性。sync 命令会将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件等。
上面的设置虽然简单但是比较粗暴,使cache的作用基本无法发挥,尤其在系统压力比较大时进行drop cache处理容易产生问题。因为drop_cache是全局在清内存,清的过程会加页面锁,导致有些进程等页面锁时超时,导致问题发生。因此,需要根据系统的状况进行适当的调节寻找最佳的方案。
6. 经验总结
以上分别讨论了Cache和Buffer分别从哪里来?什么时候消耗在哪里?如何分别控制Cache和Buffer这三个问题。最后还介绍了vmtouch工具的使用。
要深入理解Linux的Cache和Buffer牵涉大量内核核心机制(VFS、内存管理、块设备驱动、页高速缓存、文件访问、页框回写),需要制定计划在后续工作中不断理解和消化。
相关推荐:《Linux视频教程》
Atas ialah kandungan terperinci Apakah penampan linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Artikel Panas

Alat panas Tag

Artikel Panas

Tag artikel panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

DeepSeek Web Versi Pintu Masuk Laman Web Rasmi DeepSeek

Android TV Box mendapat peningkatan Ubuntu 24.04 tidak rasmi

Alamat muat turun aplikasi dompet BitPie Bitpie

Pemasangan Laman Web Rasmi Bitget (Panduan Pemula 2025)

Pemasangan penyusunan kod sumber Zabbix 3.4

Penjelasan terperinci: Perintah parameter pertimbangan pembolehubah skrip Shell

Pakej pemasangan OUYI OKX disertakan secara langsung
