Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用PHP实现大量小文件的快速网络传输_Php - Fatal编程技术网

用PHP实现大量小文件的快速网络传输

用PHP实现大量小文件的快速网络传输,php,Php,我在同一局域网上有两台Linux服务器。 使用PHP,我需要将100000个小型(10KB)文件从服务器A复制到服务器B 现在我使用的是ssh2\u scp\u send,速度非常慢(20分钟内有10K个文件) 如何使其更快?您可以通过PHP执行外部进程吗?如果可以的话,rsync是进行复制的更快的方法另一个选项是Zip: <?php $zip = new ZipArchive(); if ($zip->open('TempFileToTransfer.zip', ZIPARCHI

我在同一局域网上有两台Linux服务器。
使用PHP,我需要将100000个小型(10KB)文件从服务器A复制到服务器B

现在我使用的是ssh2\u scp\u send,速度非常慢(20分钟内有10K个文件)


如何使其更快?

您可以通过PHP执行外部进程吗?如果可以的话,rsync是进行复制的更快的方法

另一个选项是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();
?>

传输一个文件,在另一端解压缩,在另一端使用zip_entry_open和zip_entry_read


我还建议一次发送1000个文件?

发送大量小文件的开销可能是这里的速度减慢

您可以将其归档到本地服务器上, shell_exec()

将其发送到远程服务器, ssh2_scp_发送()

然后在另一端展开它。 ssh2_exec()


我的感觉是拱起/扩展的开销会更少,但我还没有测试过这一点。

通过SSH隧道使用gzip TAR非常快。数量级比纯scp快,特别是对于许多小文件。以下是linux命令行的一个示例:

user@local#cd/来源/;焦油czf-*| sshuser@remote“cd/target/;tar xzf-


更新:根据要求,这里是一个纯PHP解决方案——在处理这一棘手问题时玩得很开心

注意:您需要这样才能工作。而且,STDIN似乎只有在使用SSH的流包装器时才可用

这几乎没有开销,因为它直接在流上运行,而且您的CPU很可能总是比用于传输的网络链路快

要权衡网络与CPU速度,可以从命令行中删除选项
-z
。(CPU使用率降低,但线路上有更多数据)

代码示例:

<?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; }
}

这是一个可能但更复杂的解决方案。FTP通常是最快的解决方案。如果使用cmd行进行复制,它会更快吗?这是php函数的慢部分,还是复制大量小文件的开销?@bumperbox我认为是它的开销。仅仅创建所有这些文件就需要第二次归档。归档这些文件并不难。如果可能的话,可以使用命令行,或者php有很多这样的类,甚至像Phar这样的扩展。我相信你甚至可以从中找到例子。。