предисловие
Только лысина может стать сильнее
Читая «Проектирование и реализация Redis» о расширении хеш-таблицы, я нашел этот отрывок:
В процессе выполнения команды BGSAVE или команды BGREWRITEAOF Redis необходимо создать дочерний процесс текущего серверного процесса, и большинство операционных систем используютКопирование при записи для оптимизации использования дочерних процессов, поэтому за время существования дочернего процесса сервер будет повышать порог коэффициента загрузки, тем самым избегая операции расширения хеш-таблицы за время существования дочернего процесса, избегая ненужных операций записи в память и максимально экономя память.
Я коснулся слепого пятна знаний, поэтому я искал, на что похожа технология копирования при записи. Я обнаружил, что здесь задействовано довольно много вещей, и это довольно сложно читать. Поэтому я написал эту заметку, чтобы записать свой процесс обучения копированию при записи.
эта статьяСтремитесь кратко объяснить суть копирования при записи., я надеюсь, что каждый сможет получить что-то после прочтения.
1. Копирование при записи под Linux
Прежде чем объяснять механизм копирования при записи в Linux, мы должны сначала узнать две функции:fork()
иexec()
. должен быть в курсеexec()
это не конкретная функция, этособирательное название набора функций, который включаетexecl()
,execlp()
,execv()
,execle()
,execve()
,execvp()
.
1.1 Простота использования с вилкой
Сначала давайте посмотрим наfork()
Какая, черт возьми, функция:
fork is an operation whereby a process creates a copy of itself.
fork находится в Unix-подобных операционных системахсоздать процессосновной метод. вилка используется длясоздать дочерний процесс(эквивалент копии текущего процесса).
- Новый процесс должен быть получен путем копирования самого себя из старого процесса, который является форком!
Если вы столкнулись с Linux, мы будем знать, что под LinuxПроцесс init — отец всех процессов(эквивалентно объекту Object в Java)
- Все процессы Linux разветвляются (vfork) через процесс инициализации или подпроцесс инициализации.
Давайте проиллюстрируем вилку на примере:
#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid; //fpid表示fork函数返回的值
int count=0;
// 调用fork,创建出子进程
fpid=fork();
// 所以下面的代码有两个进程执行!
if (fpid < 0)
printf("创建进程失败!/n");
else if (fpid == 0) {
printf("我是子进程,由父进程fork出来/n");
count++;
}
else {
printf("我是父进程/n");
count++;
}
printf("统计结果是: %d/n",count);
return 0;
}
В результате получается:
我是子进程,由父进程fork出来
统计结果是: 1
我是父进程
统计结果是: 1
объяснять:
- fork вызывается как функция. Эта функция будет иметьвернуться дважды,будетPID дочернего процесса возвращается родительскому процессу, а 0 возвращается дочернему процессу.. (Если он меньше 0, значит, создание дочернего процесса не удалось).
- Опять же: текущий процесс вызывает
fork()
, создаст дочерний процесс, точно такой же, как текущий процесс (за исключением pid), поэтому дочерний процесс также будет выполняться.fork()
код после.
так:
- Когда родительский процесс выполняет блок кода if,
fpid变量
Значением является pid дочернего процесса. - Когда дочерний процесс выполняет блок кода if,
fpid变量
значение равно 0
1.2 Давайте еще раз посмотрим на функцию exec()
Из вышеизложенного мы уже знаем, что fork создаст дочерний процесс.Дочерний процесс является копией родительского процесса.
Роль функции exec:загрузить новую программу(исполняемый образ) оверлейтекущий процессобраз в памяти,для выполнения разных задач.
- Когда выполняется серия функций exec, ониНапрямую заменить адресное пространство текущего процесса.
Нарисую картинку для понимания:
Использованная литература:
- Необходимые знания для программистов - подробное объяснение функций fork и execblog.CSDN.net/8:00_good_horse…
- Подробное объяснение функции fork() в Linux (оригинал!! Пример объяснения):blog.CSDN.net/Jason314/AR…
- Введение и использование функций fork() и exec в языке linux c:blog.CSDN.net/women's 11/art IC…
- Fork и Exec используют под Linux:woo woo .cn blog on.com/Привет посещает A/ah…
- Системный вызов Linux — анализ исходного кода ядра fork():blog.CSDN.net/Chen8927040…
1.3 Оглядываясь назад на COW под Linux
fork() создаст дочерний процесс, точно такой же, как родительский процесс (за исключением pid).
Если вы нажметеТрадицияподход, будетнепосредственныйСкопируйте данные родительского процесса в дочерний процесс.После копирования сегмент данных и стек между родительским процессом и дочерним процессомвзаимно независимый.
Однако по нашему опыту: часто дочерние процессы будут выполнятьсяexec()
делать то, чего вы хотите достичь.
- Таким образом, если вы следуете описанному выше подходу, бесполезно копировать прошлые данные при создании дочернего процесса (поскольку дочерний процесс выполняет
exec()
, исходные данные будут очищены)
Поскольку данные, копируемые в дочерний процесс, часто оказываются недействительными, существует технология Copy On Write, принцип которой также очень прост:
- Дочерний процесс, созданный fork,Общая память с родительским процессом. То есть, если дочерний процессЕсли в области памяти не выполняется операция записи, данные в области памяти не будут скопированы в дочерний процесс., так что скорость создания дочерних процессов очень быстрая! (Никакого копирования, прямая ссылка на физическое пространство родительского процесса).
- и если после возврата функции fork дочерний процесспервый разexec новый исполняемый образ, тогда он не будет тратить время и память.
Другое выражение:
выполнить два процесса до и после forkиспользуя одно и то же физическое пространство(область памяти), сегмент кода, сегмент данных и стек дочернего процесса — все они указывают на физическое пространство родительского процесса, то есть виртуальные пространства этих двух процессов различны, но их соответствующиефизическое пространство такое же.
когда родительско-дочерний процессКогда есть действие, которое изменяет соответствующий сегмент,СноваВыделить физическое пространство для соответствующего сегмента дочернего процесса.
Если это не для exec, ядро выделит соответствующее физическое пространство для сегмента данных и сегмента стека дочернего процесса (пока что они имеют собственное пространство процесса и не влияют друг на друга), и сегмент кода продолжается. разделить физическое пространство родительского процесса (два кода точно такие же).
И если это из-за exec, потому что код, выполняемый этими двумя, отличается, сегмент кода дочернего процесса также будет выделять отдельное физическое пространство.
Технология копирования при записиПринцип реализации:
После fork() ядро устанавливает разрешения всех страниц памяти в родительском процессе только для чтения, а затем адресное пространство дочернего процесса указывает на родительский процесс. Когда родительский и дочерний процессы являются постоянной памятью, все в порядке. Когда один из процессов записывает память, аппаратное обеспечение ЦП определяет, что страница памяти доступна только для чтения, поэтому вызывает ошибку страницы и попадает в процедуру прерывания ядра. В подпрограмме прерывания ядро будетСделайте копию страницы, вызвавшей исключение, поэтому родительский и дочерний процессы содержат независимую копию.
Технология копирования при записивыгодачто это?
- технология COW можетуменьшатьпри выделении и дублировании больших объемов ресурсовМгновенная задержка.
- Технология COW снижаетненужное выделение ресурсов. Например, при разветвлении процесса не нужно копировать все страницы, а родительский процессНи сегмент кода, ни сегмент данных только для чтения не могут быть изменены, поэтому нет необходимости копировать.
Технология копирования при записинедостатокчто это?
- Если и родительский, и дочерний процессы должны продолжать писать после fork(),Тогда будет много ошибок пейджинга (страница ненормальное прерывание страница-ошибка), так что это не стоит потери.
Несколько слов, чтобы обобщить технологию копирования при записи в Linux:
- Дочерний процесс из fork разделяет физическое пространство родительского процесса, когда родительский и дочерний процессыКогда есть операция записи в память, страница постоянной памяти прерывается,Скопируйте страницу памяти сработавшего исключения(Остальные страницы по-прежнему используются совместно с родительским процессом).
- Реализация функции дочернего процесса из fork такая же, как и у родительского процесса. При необходимости воспользуемся
exec()
Замените текущий образ процесса новым файлом процесса, чтобы завершить функцию, которую вы хотите достичь.
Использованная литература:
- Основы процесса Linux:Woo Woo Woo.cn Blog On.com/va No / Arc Hi ...
- Технология копирования при записи в Linux (copy-on-write)Блог Woohoo.cn на.com/Есть ли работа после окончания учебы…
- Что происходит, когда вы запускаете процесс в Linux?zhuanlan.zhihu.com/p/33159508
- Нужно ли так называемое копирование при записи (COW) в Linux fork() сначала копировать, а затем записывать в конце?Ууху. Call.com/question/26…
- Технология копирования при записи COWBlog.csdn.net/u012333003 / ...
- Принцип копирования при записиblog.CSDN.net/papapapapapapapapa20…
Во-вторых, объясните COW Redis
Исходя из вышеприведенного фундамента, мы уже должны понимать такую технологию, как COW.
Позвольте мне рассказать о моем понимании отрывка из «Проектирование и реализация Redis»:
- Когда Redis сохраняется, если используется команда BGSAVE или BGREWRITEAOF, RedisСоздайте дочерний процесс для чтения данных и записи их на диск..
- В целом в Redis по-прежнему больше операций чтения. Если во время существования дочернего процесса происходит большое количество операций записи, может возникнутьМного ошибок пейджинга (страница прерывает ошибку страницы), что будет стоить много производительности при репликации.
- пока вНа этапе перефразирования операции записи неизбежны.из. Итак, после того, как Redis разветвит дочерний процесс,Увеличьте порог коэффициента загрузки, сведите к минимуму операции записи, избегайте ненужных операций записи в память и максимально экономьте память.
Использованная литература:
- Некоторые особенности копирования при записи после fork():Чжоу Цзянь is.GitHub.IO/articles/20…
- Копирование при записи:Секунды 1007.GitHub.IO/git book/ просто av…
3. COW файловой системы
Давайте посмотрим, что означает COW в файловой системе:
Когда копирование при записи изменяет данные,Не работает непосредственно с исходным местоположением данных, но чтобы найти новое место для изменения, преимущество этого заключается в том, что после внезапного отключения питания системы нет необходимости выполнять Fsck после перезапуска. Преимущество в том, чтоОбеспечить целостность данных, легко восстановить в случае сбоя питания.
- Например: чтобы изменить содержимое блока данных A, сначала прочитайте A и запишите его в блок B. Если в это время питание отключено, содержимое оригинального A все еще там!
Использованная литература:
- Каковы конкретные преимущества режима копирования при записи в файловых системах?Ууху. Call.com/question/19…
- Введение в файловую систему Linux нового поколения btrfs:Woohoo. IBM.com/developer Я…
Наконец
Наконец, давайте рассмотрим идею копирования при записи (выдержка из Википедии):
Копирование при записи (COW) — это стратегия оптимизации в области компьютерного программирования. Основная идея заключается в том, что если несколько вызывающих объектов одновременно запрашивают один и тот же ресурс (например, память или хранилище данных на диске), они совместно получат один и тот же указатель на один и тот же ресурс до тех пор, пока вызывающий объект не попытается изменить ресурс. фактически копирует частную копию вызывающему объекту, когда содержимое присутствует, в то время как исходные ресурсы, видимые другими вызывающими объектами, остаются неизменными. Этот процесс прозрачен для других вызывающих абонентов. Основное преимущество этого подхода заключается в том, что если вызывающий объект не изменяет ресурс, копия (частная копия) не создается, поэтому несколько вызывающих объектов могут совместно использовать один и тот же ресурс только для операций чтения.
По крайней мере, из этой статьи мы можем сделать вывод:
- Linux значительно улучшился благодаря технологии Copy On Write.Снижение накладных расходов на вилку.
- Файловая система в определенной степени гарантируется технологией Copy On Write.целостность данных.
На самом деле в Java тоже есть технология Copy On Write.
Эта часть останется в следующей статье, так что следите за обновлениями~
Если у вас есть лучший способ понять или в статье есть ошибки, пожалуйста, не стесняйтесь оставлять сообщение в области комментариев, чтобы мы могли учиться друг у друга~~~
Использованная литература:
- Копирование при записи, копирование при записи, разделение при записи, копирование при записи:№ OSCHINA.net/Lunibonju/No…
- COW (Copy-On-Write), которая не производит молокоу-у-у. Краткое описание.com/afraid/inconvenient 2 удобно 2 ой 5 ой...
ОдинПридерживайтесь общедоступной учетной записи оригинальной технологии Java: Java3y, приветствую всех, чтобы обратить внимание
Все 3 года оригинальные статьи:
- Навигация по каталогу статей (карта мозга + обширные видеоресурсы):GitHub.com/Zhongf UC очень…