Сплит большие файлы

Я занимаюсь разработкой распределенной системы, в которой на сервере будут распределены огромные задачи для клиентов, которые будут их обрабатывать и возвращать результат.
Сервер должен принимать огромные файлы размером порядка 20 Гб.

Сервер должен разбить этот файл на более мелкие части и отправить путь клиентам, которые, в свою очередь, будут проверять файл и обрабатывать их.

я использую read а также write выполнить разбиение файла, которое выполняется смехотворно медленно.

Код

//fildes - Source File handle
//offset - The point from which the split to be made
//buffersize - How much to split

//This functions is called in a for loop

void chunkFile(int fildes, char* filePath, int client_id, unsigned long long* offset, int buffersize)
{
unsigned char* buffer = (unsigned char*) malloc( buffersize * sizeof(unsigned char) );
char* clientFileName = (char*)malloc( 1024 );
/* prepare client file name */
sprintf( clientFileName, "%s%d.txt",filePath, client_id);

ssize_t readcount = 0;
if( (readcount = pread64( fildes, buffer, buffersize, *offset ) ) < 0 )
{
/* error reading file */
printf("error reading file \n");
}
else
{
*offset = *offset + readcount;
//printf("Read %ud bytes\n And offset becomes %llu\n", readcount, *offset);
int clnfildes = open( clientFileName, O_CREAT | O_TRUNC | O_WRONLY , 0777);

if( clnfildes < 0 )
{
/* error opening client file */
}
else
{
if( write( clnfildes, buffer, readcount ) != readcount )
{
/* eror writing client file */
}
else
{
close( clnfildes );
}
}
}

free( buffer );
return;
}
  1. Есть ли более быстрый способ разделения файлов?
  2. Есть ли способ, которым клиент может получить доступ к своему чанку в файле без использования scp (чтение без передачи)?

Я использую C ++. Я готов использовать другие языки, если они могут работать быстрее.

1

Решение

Вы можете разместить файл в пределах досягаемости веб-сервера, а затем использовать curl от клиентов

curl --range 10000-20000 http://the.server.ip/file.dat > result

получит 10000 байт (от 10000 до 20000)

Если файл сильно избыточен и сеть работает медленно, вероятно, использование сжатия может значительно ускорить передачу. Например выполнение

nc -l -p 12345 | gunzip > chunk

на клиенте, а затем выполняет

dd skip=10000 count=10000 if=bigfile bs=1 | gzip | nc client.ip.address 12345

на сервере вы можете перенести раздел, выполняющий сжатие gzip на лету, без необходимости создавать промежуточные файлы.

РЕДАКТИРОВАТЬ

Единственная команда для получения раздела файла с сервера, использующего сжатие по сети:

ssh server 'dd skip=10000 count=10000 bs=1 if=bigfile | gzip' | gunzip > chunk
1

Другие решения

Является ли rsync через SSH с параметром —partial опцией?
Тогда вам может не понадобиться разделять файлы, так как вы можете просто продолжить, если передача прервана.

Известны ли заранее разделенные размеры файлов или они разделены по некоторому маркеру в файле?

1

Вы можете поместить файл на общее устройство NFS, и клиент может подключить это устройство в режиме RO. После этого клиент может открыть файл и использовать mmap () или pread () для чтения его фрагмента (части файла). Таким образом, клиенту будет передана только необходимая часть файла.

0
По вопросам рекламы [email protected]