一 應用場景描述
現在我需要向50+數量的伺服器分發Logstash新版本的rpm包,大概220MB左右,直接使用Ansible的copy指令進行傳輸,指令如下:
在執行的過程中,很快就收到Zabbix網絡監控的報警,報警項目就是瞬間流量變化大于5Mbps。同時,有的伺服器很快執行完成,有很多出現ssh連接配接錯誤,Ansible卡死。
開啟Ansible的pipelining功能依然卡在ssh連接配接上。分發檔案失敗!!
是以,使用Ansible來分發執行指令很快速,但是如果直接使用Ansible來處理稍微大一點的檔案分發就是一個很大的問題,即使耗費點時間可以忍受,但是單個分發點的帶寬也會直接影響分發效率。
對于大檔案分發,首先想到的就是BitTorrent,利用P2P協定實作快速分發,節省帶寬,提高效率。
二 P2P軟體介紹
這裡我們使用Twitter開源的murder。Twitter用它來分發大檔案完成代碼更新。在早期,Twitter為每天向上萬太台的伺服器釋出代碼而頭疼,從中央代碼伺服器向其他成千上萬的節點分發代碼存在很大瓶頸,因為分發代碼的執行時間與需要更新代碼的節點成線性關系,節點越多,分發時間越長。為了解決這個問題,Twitter抛棄了以往的集中式架構,轉向分布式架構,取名叫murder。使用murder後,他們以前需要40~60分鐘的代碼釋出任務,現在12秒以内就可以完成。
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
muder_tracker.py實際上調用的這個檔案BitTornado/BT1/track.py
track.py有很多參數,如果需要添加參數可以修改muder_tracker.py
幾個重要的參數
--port tracker監聽的端口,預設是8998
--dfile 存儲近期下載下傳資訊的檔案
--logfile tracker日志檔案,預設是标準輸出
為tracker添加啟動腳本/etc/init.d/murder-tracker
根據自己情況修改相應的參數
2.建立torrent檔案
murder_make_torrent.py檔案實際上調用的 BitTornado的makemetafile.py 檔案
3.Seed the package播種需要分發的檔案包
最後一個參數是本機的IP位址
4.從所有peers節點擷取檔案包
三 使用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
2.在seeder伺服器上制作torrent檔案并啟動seeder
seeder啟動腳本/etc/init.d/murder-seeder
啟動腳本依賴一個配置檔案seeder.conf
将需要的分發的檔案打包成deploy.tar.gz
啟動seeder
3.從seeder擷取種子檔案,然後分發到peers
調用synchronize子產品,pull模式就是從遠端擷取檔案到本地,預設是push模式,從本地推送檔案到遠端
然後将種子檔案分發出去
4.在各個peers端執行下載下傳任務
peer_download.sh
分發完成
可以将這些步驟寫成Ansible playbooks
需要注意一下:
我需要分發的伺服器是外網伺服器,每台伺服器開啟了iptables防火牆。總共有60多台伺服器同時下載下傳220M左右的壓縮包總共花了約20多分鐘時間。這個時間有點懷疑,通過再次了解BT原理和檢視源代碼發現是防火牆設定的問題。BT下載下傳之是以是下載下傳點越多,下載下傳速度越快,是因為各個下載下傳點之間可以交換資料,也就是說需要開啟TCP端口用于BT下載下傳。這點在murder的文檔中是沒有說明的,twitter預設是每台伺服器都關閉防火牆,并且是處于一個資料中心的彼此互相信任的内網伺服器。murder封裝的是BTTornado,代碼中預設是啟動一個10000~60000範圍的随機端口,每個murder peer在下載下傳的同時向其他peers提供下載下傳服務就是通過這個随機端口,如果防火牆全部關閉,這個不成問題,但是如果開啟了防火牆這麼大的端口範圍肯定不行的,就需要自己設定一個防火牆允許的範圍。
如果不開端口也是可以上傳資料的,但是會影響下載下傳速度,因為其他peer端無法連接配接到彼此。
有關下載下傳的參數在BitTornado/download_bt1.py中定義有
和端口相關的參數
這個範圍太大,根據自己情況設定小一點,然後讓防火牆通行
參考文檔:
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