2012-05-09 6 views
5

Ho 2 server Linux sulla stessa LAN.
Utilizzo di PHP devo copiare 100000 file di piccole dimensioni (10KB) dal server A al server B.veloce per trasferire in rete molti piccoli file con PHP

ora sto usando ssh2_scp_send ed è molto lento (10K file in 20 minuti).

Come rendere più veloce?

+2

archiviarli e quindi copiare .. – Vytautas

+0

Ha detto chiaramente 'Utilizzando php'. – Manuel

+0

è una soluzione possibile ma più complicata. –

risposta

0

È possibile eseguire processi esterni tramite PHP? Se è possibile, rsync è il modo più veloce per fare la copia

0

Un'altra opzione sarebbe postale:

<?php 
$zip = new ZipArchive(); 

if ($zip->open('TempFileToTransfer.zip', ZIPARCHIVE::CREATE)!==TRUE) { 
    exit("cannot open <$filename>\n"); 
} 

$zip->addFile('File 1'); 
$zip->addFile('File 2'); 
$zip->addFile('File 3'); 
$zip->close(); 
?> 

di trasferimento che un file e decomprimere all'altra estremità, e utilizzare zip_entry_open e zip_entry_read all'altra.

Vorrei suggerire anche in blocchi di dire 1000 file alla volta?

0

È probabile che il sovraccarico di invio di molti file di piccole dimensioni sia il rallentamento qui.

Si potrebbe archiviare sul vostro server locale, shell_exec()

inviarlo al server remoto, ssh2_scp_send()

quindi espandere esso all'altra estremità. ssh2_exec()

La mia sensazione è che l'overhead di archiviare/espandere sarà inferiore, ma non l'ho testato.

4

L'utilizzo di TAR gzip attraverso un tunnel SSH è veloce. Magnitudini più veloci del puro scp, in particolare per quanto riguarda molti piccoli file. Ecco un esempio per la linea di comando di Linux :

user @ locale # cd/source /; tar czf - * | ssh user @ remoto "cd/target /; tar xzf -"


Aggiornamento: Come richiesto, qui si va con una soluzione PHP puro - ha avuto un certo divertimento giocherellare questo po 'complicato.

Nota: è necessario PHPs libssh extension affinché funzioni. Inoltre, STDIN sembra essere disponibile solo quando si usano i wrapper di flusso per SSH.

Questo non ha quasi nessun sovraccarico, perché funziona direttamente sui flussi e la tua CPU è molto probabilmente sempre più veloce del collegamento di rete che stai utilizzando per il trasferimento.

Per la negoziazione della velocità della rete o della CPU, è possibile rimuovere l'opzione -z dalla riga di comando. (Utilizzo della CPU meno, ma più dati sul filo)

Codice esempio:

<?php 
$local_cmd = "cd /tmp/source && tar -czf - *"; 
$remote_cmd = "tar -C /tmp/target -xzf -"; 

$ssh = new SSH_Connection('localhost'); 
$auth = $ssh->auth_password('gast', 'gast'); 
$bytes = $ssh->command_pipe($local_cmd, $remote_cmd); 
echo "finished: $bytes bytes of data transfered\n"; 

class SSH_Connection { 
    private $link; 
    private $auth; 

    function __construct ($host, $port=22) { 
     $this->link = @ssh2_connect('localhost', 22); 
    } 

    function auth_password ($username, $password) { 
     if (!is_resource($this->link)) 
      return false; 
     $this->auth = @ssh2_auth_password($this->link, $username, $password); 
     return $this->auth; 
    } 

    function command_pipe ($localcmd, $remotecmd) { 
     if (!is_resource($this->link) || !$this->auth) 
      return false; 
     // open remote command stream (STDIN) 
     $remote_stream = fopen("ssh2.exec://{$this->link}/$remotecmd", 'rw'); 
     if (!is_resource($remote_stream)) 
      return false; 
     // open local command stream (STDOUT) 
     $local_stream = popen($localcmd, 'r'); 
     if (!is_resource($local_stream)) 
      return false; 
     // connect both, pipe data from local to remote 
     $bytes = 0; 
     while (!feof($local_stream)) 
      $bytes += fwrite($remote_stream,fread($local_stream,8192)); 
     // close streams 
     fclose($local_stream); 
     fclose($remote_stream); 
     return $bytes; 
    } 

    function is_connected() { return is_resource($this->link); } 
    function is_authenticated() { return $this->auth; } 
}