2012-05-09 2 views
5

У меня есть 2 сервера Linux в одной локальной сети.
Использование PHP мне нужно скопировать 100000 небольшие (10KB) файлы с сервера A на сервер B.быстрый способ сетевой передачи большого количества небольших файлов с PHP

Теперь я использую ssh2_scp_send и его очень медленно (10K файлы в 20 минут).

Как это сделать быстрее?

+2

их в архив, а затем скопировать .. – Vytautas

+0

Он ясно сказал, 'Использование PHP'. – Manuel

+0

это возможное, но более сложное решение. –

ответ

0

Можете ли вы выполнить внешний процесс через PHP? Если вы можете, Rsync это быстрый способ сделать то копия будет

0

Другой вариант будет Zip:

<?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(); 
?> 

Transfer, что один файл и разархивировать на другом конце, и использовать zip_entry_open и zip_entry_read на другой.

Я бы также предложил в кусках сказать 1000 файлов за раз?

0

Вероятно, накладные расходы на отправку большого количества небольших файлов - это замедление здесь.

Вы можете архивировать его на локальном сервере, shell_exec()

отправить его на удаленный сервер, ssh2_scp_send()

затем расширить его на другом конце. ssh2_exec()

Мое ощущение, что накладные расходы на архивирование/расширение будут меньше, но я не проверял это.

4

Использование gzipped TAR через туннель SSH быстро растет. Величины быстрее, чем чистый scp, особенно в отношении многих небольших файлов. Вот пример для командной строки Linux:

пользователя @ местного # Кд/источник /; tar czf - * | SSH пользователь @ удаленный "Кд/цель /; деготь xzf -"


Update: В соответствии с просьбой, здесь вы идете с чистым PHP решение - было немного весело возился этот каверзный немного.

Примечание: для этого необходимо PHPs libssh extension. Кроме того, STDIN, по-видимому, доступен только при использовании обтекателей потоков для SSH.

У этого почти нет накладных расходов, потому что он работает на потоках напрямую, и ваш процессор, скорее всего, всегда быстрее, чем сетевая ссылка, которую вы используете для передачи.

Для торговли сетью и скоростью процессора вы можете удалить опцию -z из командной строки. (Менее использование процессора, но больше данных на проводе)

Пример кода:

<?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; } 
} 
Смежные вопросы