unison是目前接触在处理海量文件同步的时候最有效率性能影响最小的软件了,在轻量级即文件数10万内的情况下可选syncthing,有较好的UI和跨平台(包括手机)。

20180919补充:用户手册
unison-2.48.4-manual.pdf
安装(ocaml的版本和unison版本是有点要求的)

wget  --no-check-certificate http://caml.inria.fr/pub/distrib/ocaml-4.03/ocaml-4.03.0.tar.gz
tar -zxvf ocaml-4.03.0.tar.gz
cd ocaml-4.03.0
./configure
make world opt
make install

cd /usr/tmp
yum -y install ctags-etags
wget  --no-check-certificate http://www.seas.upenn.edu/~bcpierce/unison//download/releases/stable/unison-2.48.4.tar.gz
mkdir unison-2.48.4 && cd unison-2.48.4
tar -zxvf /usr/tmp/unison-2.48.4.tar.gz
cd src
make UISTYLE=text THREADS=true
cp unison /usr/local/bin/
unison -version

配置文件位于~/.unison目录 下 ,因为部署的应用较多,个人创建了子目录shw/config

创建一个配置文件test.prf

配置内容:

#需要同步的目录
root = /home/html/test/www
#目标服务器目录 IP端口之后接的目录要两个斜线,不然会变成root/下的目录而不是根目录
root = ssh://192.168.0.8:22//home/public_html/test/www
#以本地文件为标准,此项开启后,同步变成单向
force = /home/html/test/www

#仅同步以下子目录
#path = web1
#path = web2

#忽略的目录
ignore = Path temp/log

#prefer表示有冲突时, 以哪边的文件为主
#prefer = /monitor

#静默模式
#terse = true
#silent = true

#全自动模式,接受缺省动作,并执行
batch = true

#同步时最大线程数
maxthreads = 10

#间隔多少秒 开始新的一次同步检查
repeat = 30

#失败重试次数
retry = 3

#保持同步过来读写权限
owner = true
group = true
perms = -1

#使用ssh压缩传输方式
perms = -1 

#true表示同步时通过文件的创建时间来比较两地文件,若为false,则比较两地文件的内容。
fastcheck = true

#激活rsync传输模式 默认true
rsync = false 

#备份所有
#backup = Name *
#备份方式一 在目标机器设定的外部目录下,接目录结构创建和备份文件,支持删除备份和修改备份
#backuplocation central
#backupdir = /home/html_backup/test/www
#备份方式二 在目标机器每个操作的子目录下建.unison,支持删除备份和修改备份
##backuplocation local
#backupprefix = .unison/$VERSION.


#询问删除
confirmbigdel = false
#
xferbycopying = true

#默认值是true,表示当需要同步的两个目录一个为空时,unison将停止,这里设置为false,即便为空unison也不会停止
confirmbigdel = false 

#日志
log = true
logfile = /home/unison_log/unison_test.log

创建一个调用脚本shell

sync_test.sh

/usr/local/bin/unison /shw/config/test #不需要写扩展名
echo "working..."

把运行命令加到开机启动后运行命令即可

nohup /root/.unison/shw/config/sync_test.sh >> /dev/null &

注意点

  1. 使用了保留文件属性权限之后,目标服务器必须存在要备份文件的用户组和用户
  2. 建立好目标的存储目录,版本更改保存目录
  3. 脚本的日志务必放在一个有空间的分区目录下,脚本的nohub务必输出到/dev/null
  4. 脚本务必随机启动

2018-09-14更新:
取消sync_test.sh这样类型的启动脚本 ,使用python启动脚本
取消sync_test.sh放入开机启动,而使用自动任务调用python启动脚本
网络问题会导致进程异常结果,python启动脚本带检测和自重运行同步的功能

#!/usr/bin/python
#coding:utf-8
import os,time
sites = ['ad','w8686','database']
no_img = ['database']
tag = 'shw/config'
log_file = '/root/.unison/'+tag+'/check.log'

def is_runing(process_name):
        try:
                process = len(os.popen('ps aux | grep "' + process_name + '" | grep -v grep').readlines())
                if process > 0:
                        return 1
                else:
                        return 0
        except:
                return 0

def log(message):
    os.popen('echo ['+time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))+'] '+message+' >> '+log_file)

for site in sites:
    web_unison = '/usr/local/bin/unison /'+tag+'/'+site+'$'
    img_unison = '/usr/local/bin/unison /'+tag+'/'+site+'_img$'
    if is_runing(web_unison) == 0:
        print web_unison+'--------------不存在'
        log(web_unison+'--------------不存在')
        os.popen('nohup '+web_unison.replace('$','')+' >> /dev/null &')
    else:
        print web_unison+'存在'
        log(web_unison+'存在')

    if site not in no_img:
        if is_runing(img_unison) == 0:
            print img_unison+'--------------不存在'
            log(img_unison+'--------------不存在')
            os.popen('nohup '+img_unison.replace('$','')+' >> /dev/null &')
        else:
            print img_unison+'存在'    
            log(img_unison+'存在')