一 应用场景描述

现在我需要向50+数量的服务器分发Logstash新版本的rpm包,大概220MB左右,直接使用Ansible的copy命令进行传输,命令如下:

1
ansible all  -m copy -a "src=/opt/software/logstash/logstash-agent-2.3.3-fb.centos6.x86_64.rpm dest=/opt/software/logstash"

在执行的过程中,很快就收到Zabbix网络监控的报警,报警项目就是瞬间流量变化大于5Mbps。同时,有的服务器很快执行完成,有很多出现ssh连接错误,Ansible卡死。

开启Ansible的pipelining功能依然卡在ssh连接上。分发文件失败!!

所以,使用Ansible来分发执行命令很快速,但是如果直接使用Ansible来处理稍微大一点的文件分发就是一个很大的问题,即使耗费点时间可以忍受,但是单个分发点的带宽也会直接影响分发效率。

对于大文件分发,首先想到的就是BitTorrent,利用P2P协议实现快速分发,节省带宽,提高效率。

二 P2P软件介绍

这里我们使用Twitter开源的murder。Twitter用它来分发大文件完成代码更新。在早期,Twitter为每天向上万太台的服务器发布代码而头疼,从中央代码服务器向其他成千上万的节点分发代码存在很大瓶颈,因为分发代码的执行时间与需要更新代码的节点成线性关系,节点越多,分发时间越长。为了解决这个问题,Twitter抛弃了以往的集中式架构,转向分布式架构,取名叫murder。使用murder后,他们以前需要40~60分钟的代码发布任务,现在12秒以内就可以完成。

     

1
2
3
wget https://github.com/lg/murder/archive/master.zip -O murder.zip
unzip murder.zip
cd murder-master

muder是基于BitTornado来实现的。主要有以下几个组件:

torrent tracker

tracker使用murder_tracker.py运行,tracker实际上就是运行在一台服务器上的单个服务,其他任何成员都要依赖这个tracker。tracker-less disctribution(DHT)目前不支持。tracker存放BitTorrent客户端需要更新状态的路径。

seeder

seeder就是存放需要向其他主机分发的文件的服务器。这些文件存放在seeder的一个目录,torrent根据这个目录创建。Murder会将这个目录打包成tgz格式,然后创建一个.torrent文件,这个文件很小,只存放关于这个tgz文件的基本哈希信息。这个.torrent文件让各个peers节点知道他们下载的是什么文件。同时,tracker会保持跟踪有哪些 .torrent文件正在被分发。一旦Murder开始传输文件,seeder服务器是众多主机首先获取文件碎片的地方。

peers

peers就是成百上千需要接收文件的服务器,并且在它们之间可以相互传输文件。一旦一个peer节点下载整个tgz文件完成,它将继续seeding一段时间防止蜜罐效应。

命令行使用murder

1.开启tracker

1
python murder_tracker.py

muder_tracker.py实际上调用的这个文件BitTornado/BT1/track.py

track.py有很多参数,如果需要添加参数可以修改muder_tracker.py

几个重要的参数

--port tracker监听的端口,默认是8998

--dfile  存储近期下载信息的文件

--logfile  tracker日志文件,默认是标准输出

为tracker添加启动脚本/etc/init.d/murder-tracker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#! /bin/sh
#
# Start/Stop murder-tracker
#
# chkconfig: 345 99 99
# description: murder-tracker
# processname: murder-tracker
if [ -f /etc/rc.d/init.d/functions ]; then
    /etc/rc.d/init.d/functions
fi
name="murder-tracker"
murder_tracker_bin="/opt/app/murder/dist/murder_tracker.py"
murder_tracker_log="/opt/logs/murder/murder_tracker.log"
murder_tracker_data="/opt/data/murder/tracker_data"
murder_user=murder
find_tracker_process () {
    PID=`ps -ef | grep murder_tracker | grep python |grep -v $0|grep -v grep|grep -v sh|grep -v root| awk '{ print $2 }'`
}
start () {
    getent passwd $murder_user  >/dev/null || useradd -r  -s /sbin/nologin $murder_user
    LOG_DIR=`dirname ${murder_tracker_log}`
    DATA_DIR=`dirname ${murder_tracker_data}`
    if [ ! -d $LOG_DIR ]; then
      echo -e  "\e[35mLog dir ${LOG_DIR} doesn't exist. Creating\e[0m"
      mkdir -p $LOG_DIR     
    fi
    if [ ! -d $DATA_DIR ]; then
      echo -e  "\e[35mLog dir ${DATA_DIR} doesn't exist. Creating\e[0m"
      mkdir -p $DATA_DIR
    fi
    chown -R $murder_user:$murder_user $DATA_DIR  $LOG_DIR
    find_tracker_process
    if "$PID" != "" ]; then
       echo -e  "\e[35m$name is already running!\e[0m"
    else
       daemon --user $murder_user  nohup  python $murder_tracker_bin  > /dev/null 2>&1 &
       echo -e "\e[35mStarting $name Done\e[0m"
    fi
}
stop () {
    find_tracker_process
    if "$PID" != "" ]; then
        echo -e "\e[35mStopping $name\e[0m"
        kill $PID
    else
        echo -e "\e[35m$name is not running yet\e[0m"
    fi
}
case $1 in
start)
        start
        ;;
stop)
        stop
        exit 0
        ;;
reload)
        stop
        sleep 2
        start
        ;;
restart)
        stop
        sleep 2
        start
        ;;
status)
        find_tracker_process
        if "$PID" != "" ]; then
          echo -e "\e[35m$name is running: $PID\e[0m"
          exit 0
        else
          echo -e "\e[35m$name is not running\e[0m"
          exit 1
        fi
        ;;
*)
        echo -e "\e[35mUsage: $0 {start|stop|restart|reload|status|configtest}\e[0m"
        RETVAL=1
esac
exit 0

根据自己情况修改相应的参数

2.创建torrent文件

1
python murder_make_torrent.py deploy.tar.gz tracker.twitter.com:8998 deploy.torrent

murder_make_torrent.py文件实际上调用的 BitTornado的makemetafile.py 文件

3.Seed the package播种需要分发的文件包

1
python murder_client.py seed  deploy.torrent deploy.tar.gz 172.28.2.200

最后一个参数是本机的IP地址

4.从所有peers节点获取文件包

1
python murder_client.py peer  deploy.torrent deploy.tar.gz 172.28.2.220

三 使用Ansible执行分发命令

tracker  172.168.2.171

seeder   172.168.2.179

peers    172.168.2.180~200

murder执行文件目录            /opt/app/murder

tracker和seeder的murder数据目录    /opt/data/murder

peers下载目录               /opt/software/download/

1.在tracker服务器上启动tracker

1
# ansible 172.168.2.171  -m service -a "name=murder-tracker state=started"

2.在seeder服务器上制作torrent文件并启动seeder

seeder启动脚本/etc/init.d/murder-seeder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#! /bin/sh
#
# Start/Stop murder-seeder
#
# chkconfig: 345 99 99
# description: murder-seeder
# processname: murder-seeder
if [ -f /etc/rc.d/init.d/functions ]; then
    /etc/rc.d/init.d/functions
fi
name="murder-seeder"
murder_seeder_data="/opt/data/murder"
murder_seeder_log="/opt/logs/murder/murder_seeder.log"
murder_seeder_bin="/opt/app/murder/dist/murder_client.py"
murder_make_torrent_bin="/opt/app/murder/dist/murder_make_torrent.py"
murder_seeder_conf="/opt/app/murder/dist/seeder.conf"
deploy_file=$(awk -F= '/deploy_file/{print $2}' /opt/app/murder/dist/seeder.conf)
torrent_file=$(awk -F= '/torrent_file/{print $2}' /opt/app/murder/dist/seeder.conf)
tracker_ip=$(awk -F= '/tracker_ip/{print $2}' /opt/app/murder/dist/seeder.conf)
local_ip=$(awk -F= '/local_ip/{print $2}' /opt/app/murder/dist/seeder.conf)
murder_user=murder
find_seeder_process () {
    PID=`ps -ef | grep murder_client|grep seed | grep python |grep -v $0|grep -v grepawk '{ print $2 }'`
    #PID=`ps -ef | grep murder_client|grep seed | grep python |grep -v $0|grep -v grep|grep -v sh|grep -v root| awk '{ print $2 }'`
}
start () {
    getent passwd $murder_user  >/dev/null || useradd -r  -s /sbin/nologin $murder_user
    LOG_DIR=`dirname ${murder_seeder_log}`
    DATA_DIR=${murder_seeder_data}
    if [ ! -d $LOG_DIR ]; then
      echo -e  "\e[35mLog dir ${LOG_DIR} doesn't exist. Creating\e[0m"
      mkdir -p $LOG_DIR     
    fi
    if [ ! -d $DATA_DIR ]; then
      echo -e  "\e[35mLog dir ${DATA_DIR} doesn't exist. Creating\e[0m"
      mkdir -p $DATA_DIR
    fi
  
    ####### make torrent 
    python $murder_make_torrent_bin $deploy_file $tracker_ip $torrent_file   
    #######
    chown -R $murder_user:$murder_user $DATA_DIR  $LOG_DIR
    find_seeder_process
    if "$PID" != "" ]; then
       echo -e  "\e[35m$name is already running!\e[0m"
    else
       nohup  python $murder_seeder_bin  seed  $torrent_file $deploy_file $local_ip     > $murder_seeder_log 2>&1 &
       #daemon --user $murder_user  nohup  python $murder_seeder_bin  seed  $torrent_file $deploy_file $local_ip     > $murder_seeder_log 2>&1 &
       echo -e "\e[35mStarting $name Done\e[0m"
    fi
}
stop () {
    find_seeder_process
    if "$PID" != "" ]; then
        echo -e "\e[35mStopping $name\e[0m"
        kill $PID
    else
        echo -e "\e[35m$name is not running yet\e[0m"
    fi
}
case $1 in
start)
        start
        ;;
stop)
        stop
        exit 0
        ;;
reload)
        stop
        sleep 2
        start
        ;;
restart)
        stop
        sleep 2
        start
        ;;
status)
        find_seeder_process
        if "$PID" != "" ]; then
          echo -e "\e[35m$name is running: $PID\e[0m"
          exit 0
        else
          echo -e "\e[35m$name is not running\e[0m"
          exit 1
        fi
        ;;
*)
        echo -e "\e[35mUsage: $0 {start|stop|restart|reload|status|configtest}\e[0m"
        RETVAL=1
esac
exit 0

启动脚本依赖一个配置文件seeder.conf

1
2
3
4
5
# cat /opt/app/murder/dist/seeder.conf 
deploy_file=/opt/data/murder/deploy.tar.gz
torrent_file=/opt/data/murder/deploy.torrent
tracker_ip=172.168.2.171:8998
local_ip=172.168.2.179

将需要的分发的文件打包成deploy.tar.gz

启动seeder

1
# ansible 172.168.2.179  -m service -a "name=murder-seeder state=started"

3.从seeder获取种子文件,然后分发到peers

1
# ansible 172.168.2.179  -m synchronize -a "mode=pull src=/opt/software/download/deploy.torrent dest=/opt/software/download"

调用synchronize模块,pull模式就是从远端获取文件到本地,默认是push模式,从本地推送文件到远端

然后将种子文件分发出去

1
# ansible all  -m synchronize -a "src=/opt/software/download/deploy.torrent dest=/opt/software/download"

4.在各个peers端执行下载任务

1
# ansible all  -m shell -a "sh /opt/app/murder/dist/peer_download.sh"

peer_download.sh

1
2
3
4
5
6
7
8
#!/bin/bash
#this file is used to download bt files
torrent_file=/opt/software/download/deploy.torrent
download_file=/opt/software/download/deploy.tar.gz
local_ip=$(hostname -I|awk '{print $1}')
murder_client_bin=/opt/app/murder/dist/murder_client.py
python  $murder_client_bin peer $torrent_file $download_file $local_ip

分发完成

可以将这些步骤写成Ansible playbooks

需要注意一下:

我需要分发的服务器是外网服务器,每台服务器开启了iptables防火墙。总共有60多台服务器同时下载220M左右的压缩包总共花了约20多分钟时间。这个时间有点怀疑,通过再次了解BT原理和查看源代码发现是防火墙设置的问题。BT下载之所以是下载点越多,下载速度越快,是因为各个下载点之间可以交换数据,也就是说需要开启TCP端口用于BT下载。这点在murder的文档中是没有说明的,twitter默认是每台服务器都关闭防火墙,并且是处于一个数据中心的彼此相互信任的内网服务器。murder封装的是BTTornado,代码中默认是启动一个10000~60000范围的随机端口,每个murder peer在下载的同时向其他peers提供下载服务就是通过这个随机端口,如果防火墙全部关闭,这个不成问题,但是如果开启了防火墙这么大的端口范围肯定不行的,就需要自己设置一个防火墙允许的范围。

如果不开端口也是可以上传数据的,但是会影响下载速度,因为其他peer端无法连接到彼此。

有关下载的参数在BitTornado/download_bt1.py中定义有

和端口相关的参数

1
2
3
4
('minport', 10000, 'minimum port to listen on, counts up if unavailable'),
('maxport', 60000, 'maximum port to listen on'),
('random_port', 1, 'whether to choose randomly inside the port range ' +
        'instead of counting up linearly'),

这个范围太大,根据自己情况设置小一点,然后让防火墙通行

参考文档:

http://blogs.cornell.edu/info4220/2013/04/05/murder-distributed-large-scale-code-deployment/

http://www.royans.net/wp/tag/tools/

https://github.com/lg/murder

https://github.com/effigies/BitTornado

https://github.com/russss/Herd

https://github.com/masahide/ansible-lssd

http://www.361way.com/python-p2p/4737.html

http://bt.degreez.net/firewalled.html

结合P2P软件使用Ansible分发大文件 1相关推荐

  1. 利用P2P软件(Murder)大规模分发大文件

    引言 当服务器多时,为了管理方便和提升效率,就会用到自动化管理工具(如Ansible)来自动部署和批量分发文件. 场景描述:目前有50+台服务器,已部署Ansible用于自动化部署和批量分发文件.批量 ...

  2. 4种大文件传输工具和软件,用于共享大文件

    无论是个人还是与团队一起工作,大文件传输软件和网站都能协助提高工作效率.有效地管理工作内容.疫情原因有时我们不得不居家办公,在这种情况下可以分享文件的工具就显得尤为重要. 每个公司都需要一个文件传输软 ...

  3. P2P技术软件Murder分发大文件

    一般情况下,在运维多台服务器的时候,使用Ansible来完成文件的分发和命令的执行.但如果运维的机器数量多,而且内网带宽有限的情况下,比如,需要向500台机器分发一个1G大小的升级包,这时候如果使用A ...

  4. 如何分发大文件、大文件传输解决方案

    随着云计算.大数据技术不断发展,4K 视频.虚拟现实(VR).视频直播等互联网应用领域不断升级更新,企业网.数据中心规模持续扩大,企业拥有的数据急剧增长,海量文件随之产生. 同时,互联网时代,众多行业 ...

  5. 如何分发大文件、文件夹传输解决方案

    总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...

  6. 如何分发大文件、大文件断点续传解决方案

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  7. win7文件传输服务器,大文件传输,教您大文件如何快速传输

    小伙伴们,你们传输大文件给别人的时候是怎么操作的呢?小编我这儿有一种可以快速传输大文件的方法,小伙伴们有兴趣了解一下吗?有的话那现在就六和小编一起去看看吧~ 我们在使用电脑的时候,经常会遇到需要传输大 ...

  8. 为什么大文件删除后不在回收站?大文件删除后不在回收站怎么恢复

    案例分享:我加班加点将准备好的文件发给了领导,但是领导没有及时接收过期了,显示已失效无法下载,而那天我鬼使神差的误将源文件删除了,删除的时候提示文件太大无法放入回收站,然后就直接删除了,现在回收站也找 ...

  9. 浅谈HTTP FTP和P2P网络大文件传输的优劣势

    随着各种行业和硬件设备的发展,大文件越来越多,比如在媒体行业为了保证图片和视频的清晰,和以前的相比,都比较大,尤其是出版社等行业.确保文件能快速的传输,现在很多企业还是使用的硬盘邮寄的方式.如果使用网 ...

  10. 大文件传输软件的优势有哪些?-镭速传输

    互联网时代,大数据传输是企业面临的必不可免的问题,可以选择传统的FTP.网盘等方式来传输,对于小型文件或许是有优势的:但是对于大型文件数据的话,也许会出现传输速度慢,数据不可靠的情况,极大的影响了企业 ...

最新文章

  1. FPGA之道(3)数字系统之间的接口电平标准
  2. 原理:什么是Quadtrees?(转)
  3. java ls_linux ls 命令
  4. python(matplotlib2)——legend图例,Annotation图片注解
  5. aspx隐藏前台控件div_javascript总结--div
  6. python中合法的二进制整数_python:求整数的二进制表示
  7. 微软未来五年将把80%资源投入云计算
  8. MVC IIS创建过程问题收录
  9. 《基因大数据智能生产及分析》笔记
  10. Owin Katana 的底层源码分析
  11. 实现信息化企业供应链管理,上云是大势所趋
  12. 解决U盘使用DVD镜像安装Fedora15需要联网的问题
  13. 【汇正财经】企业资本的意义
  14. Python学习a1——背景及基础
  15. study mysql
  16. html5页面打不开原因,部分网页打不开是什么原因,详细教您网页打不开怎么解决...
  17. 什么是 Ubuntu?
  18. windows的gitbash使用jq
  19. 秋招深信服技术服务1面过2面挂
  20. Sql server mssqlserver 服务无法启动

热门文章

  1. linux wps 公式编辑器,WPS 2012数学公式编辑器的使用方法(详细图解)
  2. 软件测试自学乐器儿童画,查找「国庆节儿童画大全」安卓应用 - 豌豆荚
  3. 关于 Unity 绑定手机 收不到验证码 的解决方案
  4. fatal error: gnu/stubs-32.h: No such file or directory
  5. 2019 GDUT 新生专题I选集 L题(CodeForces - 1260B)
  6. 网易buff服务器不稳定,《梦幻西游》手游平民94方寸逆袭成神分享心得助你腾飞_ 《梦幻西游》手游官网-人人都玩,无处不在...
  7. 抖音上热门的小技巧,不看后悔
  8. 色相/饱和度趣味调节
  9. 仙侣情缘之麒麟劫java_《仙侣情缘之麒麟劫》详细流程攻略[多图]
  10. 【拿到offer】2020农业银行校园秋季招聘面试心得