我正在开发一个分布式系统,在这个系统中,服务器会将大量任务分发给处理它们并返回结果的客户。
服务器必须接受大小为20Gb的大文件。
服务器必须将此文件拆分为较小的部分,然后将路径发送给客户端,客户端又会scp该文件并对其进行处理。
我正在使用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;
}
我正在使用C ++。如果他们能够更快地执行,我准备使用其他语言。
答案 0 :(得分:1)
使用--partial选项通过SSH进行rsync吗? 然后您可能不需要拆分文件,因为如果传输中断,您可以继续。
文件分割大小是预先知道的还是按文件中的某个标记分割?
答案 1 :(得分: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
答案 2 :(得分:0)
您可以将文件存放到NFS共享设备上,客户端可以将该设备安装在RO模式下。此后,客户端可以打开文件,并使用mmap()或pread()来读取它的片(文件片段)。通过这种方式,对于客户端,将只传输文件所需的部分。