perl多线程rsync备份文件到远端主机

需求:

主机上有上百G的备份文件要rsync到远端主机,我们将大文件进行切割为几十个小文件进行多线程传输。

这里使用14个1G的文件进行演示:

[[email protected] test]# pwd
/root/test
[[email protected] test]# ll
总用量 13631540
-rw-r--r--. 1 root root 1073741824 6月  11 18:29 test10.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:30 test11.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:31 test12.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:31 test13.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:32 test14.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:23 test2.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:24 test3.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:25 test4.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:26 test5.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:26 test6.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:27 test7.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:28 test8.data
-rw-r--r--. 1 root root 1073741824 6月  11 18:29 test9.data
[[email protected] test]#

脚本名:tq.pl

#!/usr/bin/env perl

use strict;
use threads;
use Thread::Queue;
use File::Find;
use File::Rsync;
use POSIX qw(strftime);

#本地主机文件目录
my $srcFilePath=‘/root/test/‘;
#使用队列,将要备份的文件逐一插入队列
my $fileQueue = Thread::Queue->new();
#远端主机备份目录
my $remotedir=‘[email protected]::lansggtest‘;
#最大线程数
my $thread_max = 5;
my $backupTime = strftime("%Y%m%d%H%M%S",localtime(time));
print "begin : $backupTime\n";

#检索要备份目录下的所有文件,. 除外。 linux中 . 代表当前目录
sub findAllFile {
        unless ( $_ eq ‘.‘){
        print "corrent file : $File::Find::name \n";
        $fileQueue->enqueue($_);
        }
}

find(\&findAllFile,$srcFilePath);

#使用rsync进行传输
sub rsync {
    my $file = shift;
    print "rsync -- $file \n";
    my $obj = File::Rsync->new(
    {
    archive    => 1,
    compress => 1,
    checksum => 1,
    recursive => 1,
    times => 1,
#    verbose => 1,
    timeout => 300,
    progress => 1,
    stats => 1,
    ‘ignore-times‘ => 1,
    ‘password-file‘ => ‘./rsync.pass‘,
    }
);

$obj->exec( { src => "$srcFilePath$file", dest => $remotedir } ) or warn "rsync Failed ! \n";

#print $obj->out;

}
#检查队列中未传输的文件
while ($fileQueue->pending()){
    while (scalar(threads->list()) < $thread_max ){
#        my $readQueue = $fileQueue->dequeue();        #此做调试使用,查看当前传输的文件
#        print "current file Queue is $readQueue \n";
#生成线程
        threads->create(\&rsync,$readQueue);

#查看当前线程总数
        my $thread_count = threads->list();
#        print "thread_count is $thread_count\n"; 
    }
#确定当前线程是否作业完成,进行回收
    foreach my $thread (threads->list(threads::all)){
        if ($thread->is_joinable()){
                $thread->join();
            }
        }
}

#join掉剩下的线程(因为在while中的队列为空时,可能还有线程在执行,但是此时程序将退出while循环,所以这里需要额外程序join掉剩下的线程)

foreach my $thread ( threads->list(threads::all) ) {
    $thread->join();
    }

$backupTime = strftime("%Y%m%d%H%M%S",localtime(time));
print "end : $backupTime\n";

此脚本是使用了核心功能,后期可以加上日志记录,邮件发送等功能。

当我们执行该脚本时,查看主机线程情况

[[email protected] pl]# ps -ef |grep tq
root       6377   2152 88 19:05 pts/3    00:00:12 perl ./tq.pl
[[email protected] pl]# pstree -p 6377
perl(6377)─┬─rsync(6379)
           ├─rsync(6381)
           ├─rsync(6383)
           ├─rsync(6385)
           ├─rsync(6387)
           ├─{perl}(6378)
           ├─{perl}(6380)
           ├─{perl}(6382)
           ├─{perl}(6384)
           └─{perl}(6386)
          
 [[email protected] pl]# ps -ef |grep rsync
root       6379   6377 14 19:05 pts/3    00:00:14 rsync --archive --checksum --compress --ignore-times --progress --recursive --stats --times --password-file=./rsync.pass --timeout=300 /root/test//test13.data [email protected]::lansggtest
root       6381   6377 14 19:05 pts/3    00:00:14 rsync --archive --checksum --compress --ignore-times --progress --recursive --stats --times --password-file=./rsync.pass --timeout=300 /root/test//test12.data [email protected]::lansggtest
root       6383   6377 14 19:05 pts/3    00:00:14 rsync --archive --checksum --compress --ignore-times --progress --recursive --stats --times --password-file=./rsync.pass --timeout=300 /root/test//test1.data [email protected]::lansggtest
root       6385   6377 14 19:05 pts/3    00:00:14 rsync --archive --checksum --compress --ignore-times --progress --recursive --stats --times --password-file=./rsync.pass --timeout=300 /root/test//test8.data [email protected]::lansggtest
root       6387   6377 12 19:05 pts/3    00:00:12 rsync --archive --checksum --compress --ignore-times --progress --recursive --stats --times --password-file=./rsync.pass --timeout=300 /root/test//test3.data [email protected]::lansggtest
root       6399   2193  0 19:06 pts/2    00:00:00 grep rsync
时间: 2024-12-19 16:46:59

perl多线程rsync备份文件到远端主机的相关文章

LINUX下的远端主机登入 校园网络注册 网络数据包转发和捕获

第一部分:LINUX 下的远端主机登入和校园网注册 校园网内目的主机远程管理登入程序 本程序为校园网内远程登入,管理功能,该程序分服务器端和客户端两部分:服务器端为remote_server_udp.py 客户端分为单播客户端和广播客户端: 单播客户端client_unicast.py 广播客户端client_broadcast.py 1.单播客户端为根据net.info文件中的网络记录遍历目标网段中的所有IP,向其发送UDP封包. net.info中记录了目标网络中的一个样例IP和目标网段的子

perl多线程

2000 年 5 月发布的 Perl v5.6.0 中开始引入了一个全新的线程模型,即 interpreter threads, 或称为 ithreads,也正是在这个版本的发布申明中第一次提出了 5005threads 线程模型将来可能会被禁用的问题. perl线程的生命周期 创建线程 线程作为Perl中的一种实体,其周期包括创建,运行和退出. Perl里创建一个新的线程非常简单,主要有两种方法,他们分别是: 1.使用threads包的create方法 use threads; sub say

Shell脚本:使用rsync备份文件/目录

本文我们介绍一个shell脚本,用来使用rsync命令将你本地Linux机器上的文件/目录备份到远程Linux服务器上.使用该脚本会以交互的方式实施备份,你需要提供远程备份服务器的主机名/ip地址和文件夹位置.我们使用一个单独的列表文件,在这个文件中你需要列出要备份的文件/目录.我们添加了两个脚本,第一个脚本在每次拷贝完一个文件后询问密码(如果你启用了ssh密钥验证,那么就不会询问密码),而第二个脚本中,则只会提示一次输入密码. 我们打算备份bckup.txt,dataconfig.txt,do

perl多线程理解

Thread:在使用多线程处理比较大的数据量的扫描,遇到读写文件可能死锁的问题. Perl 线程的生命周期 1.使用 threads 包的 create() 方法: use threads; sub say_hello { printf("Hello thread! @_.\n"); return( rand(10) ); } my $t1 = threads->create( \&say_hello, "param1", "param2&q

perl 多线程理解

Thread:在使用多线程处理比较大的数据量的扫描,遇到读写文件可能死锁的问题. Perl 线程的生命周期 1.使用 threads 包的 create() 方法: use threads; sub say_hello { printf("Hello thread! @_.\n"); return( rand(10) ); } my $t1 = threads->create( \&say_hello, "param1", "param2&q

Perl多线程(1):解释器线程的特性

本文关于Perl线程的内容初始主要来自于<Pro Perl>的第21章,未来可能会逐渐添加.完善更多内容,当然也可能分离一部分内容单独成文. 线程简介 线程(thread)是轻量级进程,和进程一样,都能独立.并行运行,也由父线程创建,并由父线程所拥有,线程也有线程ID作为线程的唯一标识符,也需要等待线程执行完毕后收集它们的退出状态(比如使用join收尸),就像waitpid对待子进程一样. 线程运行在进程内部,每个进程都至少有一个线程,即main线程,它在进程创建之后就存在.线程非常轻量级,一

windows上配置rsync服务器收集linux主机巡检报告

客户这里,有很多linux主机,都是centos7的,我们需要定期每天对linux主机进行巡检,然后把巡检结果集中保存,方便对主机状态检查.为了巡检工作需要,需要在linux主机上编写巡检脚本,配置rsync客户端.. linux巡检脚本 我收集了一个巡检脚本,如下所示: #!bin/bash #主机信息每日巡检 IPADDR=$(ifconfig eth0 | grep '\<inet\>' | awk '{print $2}') #环境变量PATH没设好,在cron里执行时有很多命令会找不

perl多线程使用

原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun <<=========================threads===========================>> #!/usr/bin/perl use?threads ('yield', ????????????'stack_size'?=> 64*4096, ????????????'exit'?=> 'threads_only'

2.Perl 多线程:Threads(线程返回值)

1 use warnings; 2 use strict; 3 use threads; 4 5 sub TEST{ 6 print "Hello, World!\n"; 7 return (qw/1 2 3 4 'a'/); 8 } 9 10 #返回列表方法1 11 my ($t1) = threads->new('TEST'); 12 print $t1->join, "\n"; 13 14 #返回列表方法2 15 # 16 my $t2 = thr