What is page cache linux
В этой главе будет описан Linux 2.4 pagecache. Pagecache — это кэш страниц физической памяти. В мире UNIX концепция кэша страниц приобрела известность с появлением SVR4 UNIX, где она заменила буферный кэш, использовавшийся в операциях вода/вывода.
В SVR4 кэш страниц предназначен исключительно для хранения данных файловых систем и потому использует в качестве хеш-параметров структуру struct vnode и смещение в файле, в Linux кэш страниц разрабатывлся как более универсальный механизм, использущий struct address_space (описывается ниже) в качестве первого параметра. Поскольку кэш страниц в Linux тесно связан с понятием адресных пространств, для понимания принципов работы кэша страниц необходимы хотя бы основные знания об adress_spaces. Address_space — это некоторое программное обеспечение MMU (Memory Management Unit), с помощью которого все страницы одного объекта (например inode) отображаются на что-то другое (обычно на физические блоки диска). Структура struct address_space определена в include/linux/fs.h как:
Для понимания принципов работы address_spaces, нам достаточно остановиться на некоторых полях структуры, указанной выше: clean_pages , dirty_pages и locked_pages являются двусвязными списками всех «чистых», «грязных» (измененных) и заблокированных страниц, которые принадлежат данному адресному пространству, nrpages — общее число страниц в данном адресном пространстве. a_ops задает методы управления этим объектом и host — указатель на inode, которому принадлежит данное адресное пространство — может быть NULL, например в случае, когда адресное пространство принадлежит программе подкачки ( mm/swap_state.c, ).
Назначение clean_pages , dirty_pages , locked_pages и nrpages достаточно прозрачно, поэтому более подробно остановимся на структуре address_space_operations , определенной в том же файле:
Для понимания основ адресных пространств (и кэша страниц) следует рассмотреть -> writepage и -> readpage , а так же -> prepare_write и -> commit_write .
Из названий методов уже можно предположить действия, которые они выполняют, однако они требуют некоторого уточнения. Их использование в ходе операций ввода/вывода для более общих случаев дает хороший способ для их понимания. В отличие от большинства других UNIX-подобных операционных систем, Linux имеет набор универсальных файловых операций (подмножество операций SYSV над vnode) для передачи данных ввода/вывода через кэш страниц. Это означает, что при работе с данными отсутствует непосредственное обращение к файловой системе (read/write/mmap), данные будут читаться/записываться из/в кэша страниц (pagecache), по мере возможности. Pagecache будет обращаться к файловой системе либо когда запрошенной страницы нет в памяти, либо когда необходимо записать данные на диск в случае нехватки памяти.
При выполнении операции чтения, универсальный метод сначала пытается отыскать страницу по заданным inode/index.
Затем проверяется — существует ли заданная страница.
hash = page_hash(inode->i_mapping, index); page = __find_page_nolock(inode->i_mapping, index, *hash);
Если таковая отсутствует, то в памяти размещается новая страница и добавляется в кэш.
page = page_cache_alloc();
__add_to_page_cache(page, mapping, index, hash);
После этого страница заполняется данными с помощью вызова метода -> readpage .
И в заключение данные копируются в пользовательское пространство.
Для записи данных в файловую систему существуют два способа: один — для записи отображения (mmap) и другой — системный вызов write(2). Случай mmap наиболее простой, поэтому рассмотрим его первым. Когда пользовательское приложение вносит изменения в отображение, подсистема VM (Virtual Memory) помечает страницу.
Поток ядра bdflush попытается освободить страницу, в фоне или в случае нехватки памяти, вызовом метода -> writepage для страниц, которые явно помечены как «грязные». Метод -> writepage выполняет запись содержимого страницы на диск и освобождает ее.
Второй способ записи намного более сложный. Для каждой страницы выполняется следующая последовательность действий (полный исходный код смотрите в mm/filemap.c:generic_file_write() ).
page = __grab_cache_page(mapping, index, &cached_page);
mapping->a_ops->prepare_write(file, page, offset, offset+bytes);
copy_from_user(kaddr+offset, buf, bytes);
mapping->a_ops->commit_write(file, page, offset, offset+bytes);
Сначала делается попытка отыскать страницу либо разместить новую, затем вызывается метод -> prepare_write , пользовательский буфер копируется в пространство ядра и в заключение вызывается метод -> commit_write . Как вы уже вероятно заметили -> prepare_write и -> commit_write существенно отличаются от -> readpage и -> writepage , потому что они вызываются не только во время физического ввода/вывода, но и всякий раз, когда пользователь модифицирует содержимое файла. Имеется два (или более?) способа обработки этой ситуации, первый — использование буферного кэша Linux, чтобы задержать физический ввод/вывод, устанавливая указатель page->buffers на buffer_heads, который будет использоваться в запросе try_to_free_buffers ( fs/buffers.c ) при нехватке памяти и широко использующийся в текущей версии ядра. Другой способ — просто пометить страницу как «грязная» и понадеяться на -> writepage , который выполнит все необходимые действия. В случае размера страниц в файловой системе меньшего чем PAGE_SIZE этот метод не работает.
Источник
Linux pagecache и kswapd
Решение проблемы с высокой загрузкой процессора сервисом kswapd в Linux, очистка pagecache
После поднятия очередного сервиса я, внезапно, обнаружил «тормоза» при попытке работы с другими сервисами, поднятыми на той же виртуалке. Естественно, первым делом я посмотрел, а что же происходит. Команда top в этом деле часто оказывает неоценимую помощь:
Как видим, все довольно очевидно, но что такое этот самый kswapd0 ? Нет, название, конечно, говорящее, то есть, из него можно предположить, что процесс занимается, скорее всего, swap-ом — кэширует данные из памяти на диск, чтобы освободить хотя бы чуточку этого ценного и такого востребованного ресурса. Но… Во-первых, загрузка не изменилась и через полчаса, а во-вторых, она не изменилась даже тогда, когда я принудительно остановил почти все поднятые в контейнерах сервисы.
И именно тут меня настигло дежавю, так сильно эта ситуация напоминала ругаемую сторонниками Linux Windows — там тоже время от времени может выявиться какой-нибудь странный процесс, который, ни с того ни с сего, возьмет и отъест всю мощь CPU . Но в Windows , за долгие годы, я к этому привык и даже знаю, что и в каком случае надо делать. А тут я новичок, тут знания надо нарабатывать. Да и потом, Linux , вроде, должен был быть лишен такого рода заморочек, разве нет? 😜
Первый вопрос, который требует ответа: что такое этот процесс, насколько верна моя догадка, что он связан со swap-ом? Надо сказать, что найти описание процесса kswapd оказалось не так-то просто. Большинство предлагаемых ответов на запрос к Google сразу ведут на статьи о проблемах с этим процессом и путях их решения, и да, в основном — это проблема с высокой нагрузкой на CPU . В выборке, все же, нашлось краткое описание этого демона, а так же более подробное описание самой задачи, для решения которой и предназначен kswapd .
Если подытожить то, что удалось почитать, то получается, что этот процесс стартует во время запуска системы и большую часть времени проводит в «спячке». Информация о том, чем и когда этот демон «пробуждается» немного противиречива: в одних источниках указывается, что «просыпается» он по таймеру, в других — что его «дергает» распределитель физических страниц памяти (physical page allocator). В любом случае, если количество свободных страниц физической памяти меньше определенного порога (этим параметром можно управлять), то процесс начинает сохранять наименее используемые страницы во вторичной памяти, обычно, на диск. На самом деле, алгоритм работы сложнее, например, используются кэши swap-а, ну и все в таком роде, но самое главное, все должно работать без тех самых сторонних эффектов, которые происходят у меня, и которые описывают многочисленные пострадавшие в своих вопросах/комментариях в интернете.
Почему мы имеем то, что имеем, для меня остается пока тайной. В треде по похожей проблеме в Ubuntu писали, что во всем виновата ошибка в коде ядра, и что в новых версиях ситуация должна быть исправлена. Но! Запись эта старая, а есть вопросы, заданные уже для более современных версий. Так что, тайна не раскрыта. Но, что интересно, есть рабочее решение.
Лучше всего, на мой взгляд, как разобраться с проблемой описано вот по этой ссылке: A solution for kswapd0 going haywire on #Linux. Надо сказать, что мне пока довелось пару раз опробовать только вторую часть — сиюминутную очистку pagecache :
Выполнять эту команду следует из под суперпользователя (речь про root -а, естественно), или же воспользоваться такой модификацией:
Если, кончено, пользователю системы, под которым вы работаете, разрешено пользоваться командой sudo . Так вот, я работал под root -ом и все замечательно разрешилось!
Но все же, что это за волшебные манипуляции? Вот выдержка из документации, касающаяся данной команды:
Writing to this will cause the kernel to drop clean caches, as well as reclaimable slab objects like dentries and inodes. Once dropped, their memory becomes free.
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
echo 3 > /proc/sys/vm/drop_caches
This is a non-destructive operation and will not free any dirty objects. To increase the number of objects freed by this operation, the user may run `sync’ prior to writing to /proc/sys/vm/drop_caches. This will minimize the number of dirty objects on the system and create more candidates to be dropped.
This file is not a means to control the growth of the various kernel caches (inodes, dentries, pagecache, etc…) These objects are automatically reclaimed by the kernel when memory is needed elsewhere on the system.
Use of this file can cause performance problems. Since it discards cached objects, it may cost a significant amount of I/O and CPU to recreate the dropped objects, especially if they were under heavy use. Because of this, use outside of a testing or debugging environment is not recommended.
You may see informational messages in your kernel log when this file is used
:cat (1234): drop_caches: 3
These are informational only. They do not mean that anything is wrong with your system. To disable them, echo 4 (bit 2) into drop_caches.
Если излагать вкратце, то эта команда позволяет очистить всевозможные кэши и, таким образом, освободить память, которой так не хватает системе. Какие кэши должны быть очищены определяется записываемым значением. Надо также отметить, что важен сам факт записи данных в файл /proc/sys/vm/drop_caches — запись данных вызывает немедленную реакцию системы, но, в дальнейшем, записанное значение не влияет на ее работу.
Когда кэши очищаются, процессу kswapd больше нечего делать и он перестает загружать процессор. Но, очищая кэши, мы можем потенциально замедлить работу системы в целом, так как убираем из памяти некоторые данные, которые, когда они потребуются, придется пересоздавать, считывая с диска — как обычно, все имеет свою обратную сторону.
Как я уже писал выше, запись в файл /proc/sys/vm/drop_caches вызывает немедленную реакцию системы, после которой, лично у меня, kswapd переставал «грузить» систему. Есть утверждение, что если выполнить следующую команду под root -ом:
или, если работать под пользователем, которому разрешено использовать sudo:
или же просто отредактировать файл /etc/sysctl.conf каким-нибудь редактором (например, nano), добавив строку vm.swappiness=0 (как вы уже, наверное, догадались, редактор тоже надо вызывать из под root-а или при помощи sudo), то можно будет избавиться от описываемой мною проблемы на постоянной, так сказать, основе. Естественно, после того, как в файл /etc/sysctl.conf одним из вышеприведенным способом будут внесены нужные изменения, систему следует перезагрузить, ну или выполнить команду:
для обновления параметров без перезагрузки. Конечно, из под root-а, или при помощи sudo.
На самом деле, пока я разбирался с этой задачкой, я научился некоторым новым приемам и узнал много нового. О некоторых вновь приобретенных знаниях я, скорее всего, расскажу чуть позже, когда все немного утрясется и уложится. А пока — все…
Источник
unixforum.org
Форум для пользователей UNIX-подобных систем
- Темы без ответов
- Активные темы
- Поиск
- Статус форума
Разбираемся в кэшах Linux систем и Swaping-е
Модератор: Bizdelnick
Разбираемся в кэшах Linux систем и Swaping-е
Сообщение Gineaser » 05.06.2011 21:52
Доброго время суток.
Только начал осваивать линукс. Поэтому периодически возникают достаточно специфические вопросы, на которые я не смог найти ответы быстрым поиском по гуглу.
Есть сервер на базе Ubuntu-Server. На нем 12Gb оперативной памяти, а так же swap раздел объемом 20Gb. Решил разобрать по поводу кэша в линукс системах.
Мне кажется эта тема станет полезной не только для меня, но и для других пользователей операционных систем Unix и, наверное, даже для тех, кто далеко не новичок.
Для контроля за оперативной памятью, \\\\\\\»коробочного решения\\\\\\\» я знаю следующие методы: (Нажать на spoiler для просмотра)
Вывод команды free -m:
Вывод cat /proc/meminfo:
Изучение документации помогло кое что понять.
Во первых swap . Если swaping включен (man swapon, /proc/swaps) не используемые страницы в памяти будут скидываться в виртуальную область на жестком диске, тем самым освобождая физическую память (оперативную) и давая ресурсы для других приложений. Когда требуется обратиться к тем страницам, которые содержатся в свопе, они считываются с жесткого диска, помещаются в оперативку и обрабатываются.
Свапингом можно управлять, к примеру установить планку (значение свободной оперативки) при котором не используемые страницы начнут скидываться на жесткий диск.
Делать это можно посредством занесения значения в файл /proc/sys/vm/swappiness. По умолчанию значение 60. Оно в процентах. Что бы было проще понять приведу пример:
Если у меня оперативная память забивается больше чем на 40%, то не используемые страницы начинают писать на жесткий диск в swap. Если поставим значение 5% то swap начнет использоваться когда оперативная память забьется на 95%.
Еще, насколько я понял, можно то же самое сделать но с ограничением по количеству доступных страниц оперативки. Делается это в файле /proc/sys/vm/freepages
Файл имеет 3 значения через пробел в строчку. .
Первое значение — это предел, при котором система перестанет хранить в памяти не используемые страницы и начнет все скидывать в свап
Второе значение — это количество свободных страниц в оперативке, при котором система начнет \\\\\\\»суетится\\\\\\\» по в документации, на сколько я понял. Т.е. начнет активно использовать свап.
Третье значение — это количество свободных страниц в оперативке при котором система не свапит не используемые страницы.
Есть еще способ управление непосредственно самими страницами в оперативной памяти по средствам файла /proc/sys/vm/kswapd
Так же 3 значения.
Первое значение — максимальное количество страниц которые будут выбрасываться из памяти за раз. Если обрабатываются очень большие объемы данных с использованием свапа, мне кажется стоит увеличивать это значение.
Второе значение — количество попыток свапинга страницы. Не совсем понимая глубокую физику процесса сваппинга не знаю как влияет это значение и на что.
Третье значение — тоже не сосем понял предназначение, но если всё же понял из документации — это количество страниц которые будут считываться из/в оперативку за один запрос на отпраку в свап или извлечение из свапа. Ставить слишком много думаю не разумно. Тут скорее надо исходить из специфики железа (шина оперативной памяти, частота, двухканальные и прочие режимы работы)
Во вторых существует еще 2 вида кэша, что представляет для меня особый интерес.
Первый кэш из них — это кэш inode и dentry дескрипторов.
На сколько я понял из англоязычной документации это кэш который помещается в оперативную память при обращение к каталогам в файловой системе, которые грубо говоря являются файлами, содержащими как раз эти дескрипторы:
— (метаданные файлов внутри этого каталога) inode — время последнего доступа, права, UID/GID, размер. Не содержат имен, тем самым не имеют привязку к конкретному файлу, который представляет собой для ОС — набор байт.
— dentry — привязывают inode файла и имя файла в ФС.
И логически рассуждая, я пришел к выводу что кэш inode и dentry увеличивают время доступа к конкретному файлу, т.е. метаданные и связи хранятся в оперативки и считывать их с блочных устройств не надо.
Управлять этим кешем (очищать) можно по средстам принудительного ввода в файл /proc/sys/vm/drop_caches значения 2. К примеру так: echo 2 > /proc/sys/vm/drop_caches
Но как включить этот кэш я не нашел, на сколько я могу судить по командам мониторинга оперативки выше, он не используется. Можно посмотреть информацию о этих кешах через cat /proc/slabinfo | grep inode/dentry. Еще можно так: cat /proc/sys/fs/dentry-state,
cat /proc/sys/fs/inode-state
Второй кэш — это pagecache .
И вот тут я не совсем понял для чего он вообще и что из себя представляет. Непосредственно именно он забивает оперативную память. Хорошо понятно что это не swap. И по названию это какие то страницы оперативной памяти. Но какие и страницы чего?
Наверно к этому кэшу можно отнести следующие настройки: /proc/sys/vm/buffermem
Указывается в процентах общее количество системной буферной памяти. Имеет три значения идущие в строчку и разделенные проблемами. Из документации понял что:
первое значение — минимальный уровень буферной памяти
второе значение — уровень буферной памяти, который будет работать в том случае, если вы уберете скажем линейку оперативки, т.е. произойдет уменьшение общего количества оперативной памяти (?) так или нет не знаю.
третье значение — уровень максимально доступной буферной памяти.
Очистка этого кэша производится вводом в файл /proc/sys/vm/drop_caches значения 1
Сразу очищается почти вся оперативная память. Сбоев в работе не замечено. После очистки необходимо выполнять sync.
Кстати значение \\\\\\\»0\\\\\\\» для файла /proc/sys/vm/drop_caches установит значение по дефолту, а значение \\\\\\\»3\\\\\\\» очистит и inode+dentry кэш + pagecache.
Все что узнал вкратце изложил. Если я чего то не понимаю или не правильно представляю, очень прошу поправить и объяснить. Особенно хочу узнать что же такое всё же pagecache.
Источник