Назад | Перейти на главную страницу

Интерпретация времени чтения, записи и общего времени ввода-вывода в / proc / diskstats

Я заметил, что когда я смотрю на вывод /proc/diskstats существует несоответствие между общим временем, затраченным на чтение, общим временем, затраченным на запись, и общим временем выполнения операций ввода-вывода. Например, я видел запись в /proc/diskstats это было:

$ cat /proc/diskstats
...
8       0 sda 944150584 590524 235547588959 780672196 833280352 534699043 322507689696 3472000824 1 812190100 4246357772
...

Согласно документации на https://www.kernel.org/doc/Documentation/iostats.txt,

Поле 4 - количество миллисекунд, потраченных на чтение. Это общее количество миллисекунд, потраченных на все чтения (измеряется от __make_request () до end_that_request_last ()).

Поле 8 - количество миллисекунд, затраченных на запись. Это общее количество миллисекунд, затраченных на все операции записи (измеряется от __make_request () до end_that_request_last ()).

Поле 10 - количество миллисекунд, затраченных на выполнение операций ввода-вывода. Это поле увеличивается, пока поле 9 не равно нулю.

Следовательно, я ожидал, что десятое поле будет суммой четвертого и восьми полей, поскольку я ожидал бы, что общее время ввода-вывода будет суммой времени, затраченного на чтение, и времени, затраченного на запись. Однако я никогда не замечал, что это так, и, более того, я всегда наблюдал, что сумма четвертого и восьмого полей больше десятого (например, в строке выше (780672196 + 3472000824 - 812190100 = Мне было интересно, может ли кто-нибудь объяснить, почему эти числа разные, кажется, что десятое поле пытается уловить что-то отличное от суммы четвертого и восьмого полей.

Я не смотрел исходный код, но похоже, что разница связана с двумя разными режимами учета.

Поля # 4 и # 8 суммируют время. каждый запрос принять для завершения. Это означает, что каждый из параллельных запросов по-прежнему способствует увеличению счетчика.

Поле # 10 учитывает только фактическое время, в течение которого очередь и диски были заняты, поэтому они учитывают параллельные запросы как один.

Приведу практический пример. На /boot перегородка, я dd файл размером ~ 4 МБ. Взгляните на статистику:

[root@localhost boot]# cat /proc/diskstats | grep sda1
   8       1 sda1 46256 0 255703 19332 2063 0 4162 538 0 11207 19862
[root@localhost boot]# dd if=initramfs-0-rescue-7dc32e3935ba4ce1ae50a0a8170e4480.img of=/dev/null
84099+1 records in
84099+1 records out
43058701 bytes (43 MB) copied, 0.347783 s, 124 MB/s
[root@localhost boot]# cat /proc/diskstats | grep sda1
   8       1 sda1 46342 0 339807 23011 2063 0 4162 538 0 11551 23540
[root@localhost boot]#

Для чтения файла требуется ~ 0,35 с, или ~ 350 мс. Однако счетчики №4 и №10 реагируют по-разному: первое увеличение примерно на 4000, а второе только примерно на 350. Легко увидеть, какие из них имеют «правильное» значение: это поле №10, как мы знаем по dd что вся операция заняла около 350 мс, и поле № 10 увеличилось на ту же величину.

Итак, почему поле №4 так увеличилось и что на самом деле измеряет?

Во-первых, давайте разберемся, что происходит на уровне запроса. dd по умолчанию использует запросы 512 Б, но кэш страниц Linux работает с детализацией 4 КБ, поэтому следует ожидать около 1000 запросов по 4 КБ. Эти 1000 запросов помещаются в очередь и выдаются один за другим (для простоты представим, что NCQ не существует) и отправляются на диск. Поскольку механические диски неплохо справляются с последовательным чтением, они обычно используют политику упреждающего чтения, то есть: они читают больше данных, чем требуется. Это означает, что после завершения первого запроса 4K все остальные последующие запросы будут обработаны в очень короткое время.

Давайте посчитаем с диким упрощением:

  • количество запросов: 1000 (все запросы попадают в очередь одновременно)
  • время выполнения первого запроса: 4 мс
  • время все последующий запрос для завершения: 0 мс (да, я сказал вам, что это дикий упрощение)

Общее время запросов по полю # 4: 1000 запросов в очереди * 4 мс каждый == 4000 мс. И это примерно значение, на которое увеличилось поле №4 ...

Нижняя граница:

  • поля №4 и №8 измеряют время, необходимое для обслуживания запросов ввода-вывода с точки зрения одного запроса, умножая его на количество запросов.
  • поле № 10 сообщает вам реальное прошедшее время ("настенные часы"), используемое в пути ввода / вывода

Чтобы провести одобрительный параллелизм: думаю о многоядерном процессоре. Два процесса могут одновременно работать с ЦП, выполняясь по 60 секунд каждый. Общее используемое время ЦП составляет 120 с (60 с * 2), но реальное прошедшее время остается на уровне 60 с, поскольку два процесса выполняются одновременно.