#linux #io
#linux #io
Вопрос:
У меня есть процесс, который обрабатывает много файлов (~ 96 000 файлов, ~ 12 ТБ данных). Несколько запусков процесса привели к тому, что файлы были разбросаны по диску. Каждая итерация процесса использует несколько файлов. Это приводит к большому количеству операций по сбору файлов на диске.
В идеале я хотел бы, чтобы процесс записывал файлы, которые он использует, по порядку, чтобы следующий запуск читал их по порядку (размеры файлов меняются). Есть ли способ указать на физический порядок / группировку, за исключением записи в необработанный раздел?
Любые другие предложения были бы полезны.
Спасибо
Комментарии:
1. Похоже на вопрос для суперпользователя или Linux / Unix в stack exchange.
Ответ №1:
Есть два системных вызова, которые вы можете выполнить: , сообщите ядру, как вы собираетесь читать или записывать данный файл. fadvise64
fallocate
Еще один совет — «распределитель блоков Орлова» (Википедия, LWN) влияет на то, как ядро будет выделять новые каталоги и записи файлов.
Ответ №2:
В конце концов я решил не беспокоиться о записи файлов в каком-либо конкретном порядке. Вместо этого, прежде чем начать выполнение, я бы выяснил, где находится первый блок каждого файла, а затем отсортировал порядок обработки файлов по расположению первого блока. Не идеально, но это сильно повлияло на время обработки.
Вот код C, который я использовал для получения первого блока предоставленного списка файлов, я адаптировал его из примера кода, который я нашел в Интернете (похоже, не могу найти исходный источник).
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/fs.h>
//
// Get the first block for each file passed to stdin,
// write filename amp; first block for each file to stdout
//
int main(int argc, char **argv) {
int fd;
int block;
char fname[512];
while(fgets(fname, 511, stdin) != NULL) {
fname[strlen(fname) - 1] = '';
assert(fd=open(fname, O_RDONLY));
block = 0;
if (ioctl(fd, FIBMAP, amp;block)) {
printf("FIBMAP ioctl failed - errno: %sn", strerror(errno));
}
printf("0d, %sn", block, fname);
close(fd);
}
return 0;
}