1

サーバーで巨大なタスクをクライアントに分散し、それらを処理して結果を返す分散システムを開発しています。
サーバーは、サイズが 20Gb 程度の巨大なファイルを受け入れる必要があります。

サーバーはこのファイルを小さな断片に分割し、パスをクライアントに送信する必要があります。クライアントはファイルを scp して処理します。

私は and を使用readwriteて、とてつもなく遅いファイル分割を実行しています。

コード

//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++を使用しています。他の言語の方が高速に実行できる場合は、他の言語を使用する準備ができています。

4

3 に答える 3

1

ファイルをWebサーバーの届くところに置き、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
于 2013-09-20T17:14:36.807 に答える