Упорядочивание расположения файлов в разделе Linux

#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;
}