Blog

Crows? von Dave W - Lizenz: Creative Commons BY

Schnelle Datacenter-Rollouts mit Krähenschwarm und BitTorrent

Das englische Wort Murder lässt sich nicht nur als Mord, also das Kapitalverbrechen, ins Deutsche übersetzen. Im Englischen hat es noch eine weitere Bedeutung, es ist nämlich auch die Bezeichnung für einen Krähenschwarm („a flock of crows“).

Twitter ist einer der größten Rechenzentren-Betreiber der Welt. Wenn der Kurznachrichtendienst eine neue Version seiner Webseite oder anderer Komponenten seines IT-Systems ausliefert, müssen astronomische Datenmengen auf unzählige Server verteilt werden. Mit herkömmlichen Rollout-Werkzeugen stößt man dabei schnell an die Grenzen des Machbaren.

Wenn es das Ziel ist, mehrmals täglich Updates zu verteilen, ein Update aber mehrere Stunden für sich in Anspruch nimmt, muss man besondere Wege beschreiten.

Die Idee der Entwickler bei Twitter war, sich dafür eines Filesharing-Protokolls zu bedienen, das vielen Leuten in einem anderen Kontext bekannt sein dürfte: BitTorrent.

Die Idee ist brilliant: Große Datenmengen in kürzester Zeit an viele Empfänger zu verteilen. Eigentlich liegt nichts näher, als BitTorent zu verwenden. Twitter hat mit Murder dafür eine BitTorrent-Erweiterung für das auf Ruby basierende Rollout-Tool Capistrano entwickelt. Capistrano verwendet unterschiedliche Strategien für das Rollout. Mit Murder lässt sich BitTorrent als eine Rollout-Strategie nutzen.

Deployment mit BitTorrent — Wie geht das?

Voraussetzungen

  • Ruby 2.0+ auf allen beteiligten Rechnern/Servern
  • Ruby Gem Capistrano 2.15.5 (mit neueren Versionen funktioniert Twitter Murder nicht!)
  • Ruby Gem Twitter Murder 0.12 (= aktuelle Version Stand Februar 2015)
  • Auf allen beteiligten Rechnern/Servern muss BitTornado installiert sein.
  • Weiterhin muss es im verwendeten Netzwerk möglich sein, über ssh und BitTorrent zu kommunizieren.
  • Für das Anmelden auf den Servern sollte ein Login über SSH-Schlüssel möglich sein.
  • Für alle beteiligten Rechner müssen DNS-Namen im Netzwerk verfügbar sein. Murder funktioniert nicht, wenn ausschließlich IP-Adressen verwendet werden.

Installation

Ich gehe davon aus, dass Ruby bereits installiert ist. Falls nicht, gibt es die entsprechende Anleitung hier: Ruby-Dokumentation.

Capistrano in der gewünschten Version installiert man über diesen Konsolenbefehl auf allen beteiligten Rechnern/Servern:

$ gem install capistrano -v 2.15.5

Wir benötigen noch die Erweiterung capistrano-ext:

$ gem install capistrano-ext

Auf dieselbe Art und Weise installiert man Twitter Murder:

$ gem install murder

Jetzt benötigen wir den Pfad des Installationsverzeichnisses von Murder. Dazu geben wir auf der Konsole den Befehl

$ gem environment

ein und suchen in der Ausgabe die Zeile INSTALLATION DIRECTORY:

RubyGems Environment:
  - RUBYGEMS VERSION: 2.4.2
  - RUBY VERSION: 2.0.0 (2014-05-08 patchlevel 481) [universal.x86_64-darwin14]
  - INSTALLATION DIRECTORY: /Library/Ruby/Gems/2.0.0
  - RUBY EXECUTABLE: /System/Library/Frameworks/...

In diesem Beispiel lautet der Pfad /Library/Ruby/Gems/2.0.0 — Murder wird im Unterverzeichnis
/Library/Ruby/Gems/2.0.0/gems/murder-0.1.2/dist zu finden sein.

Es handelt sich hier um einen Mac-OS-Rechner. Auf anderen Plattformen (Windows, Unix, etc.) werden die Pfade anders lauten, sich jedoch mit dem Aufruf gem environment schnell ausfindig machen lassen.

Ist der Pfad zur Murder-Installation ermittelt, so merken wir uns diesen für später.

Wichtig ist jedoch, dass wir Murder auf jeder Maschine installieren müssen, auf die wir später Software verteilen wollen. Im Worst Case haben wir also x Maschinen mit x unterschiedlichen Pfaden. Mithilfe symbolischer Links lassen sich diese auf Unix-Dateisystemen jedoch ganz gut vereinheitlichen. In der Windows-Welt ist dies seit Vista bzw. Server 2008 mit dem Befehl mklink ebenfalls möglich.

Wir legen auf allen Maschinen den symbolischen Link /usr/share/murder an, der auf unsere Murder-Installation zeigt:

/usr/share$ ln -s /Library/Ruby/Gems/2.0.0/gems/murder-0.1.2/dist murder
/usr/share$ cd murder
/usr/share/murder$

Konfiguration

Jetzt gehen wir in unser Projektverzeichnis, also dortin, wo die Dateien für unser Deployment zu finden sind. Dieses Verzeichnis richten wir als Capistrano-Projekt ein. Dazu geben wir auf der Konsole ein:

$ capify .

Dieser Befehl legt eine besondere Datei mit dem Namen Capfile im Projektverzeichnis an. Für unser Beispiel sieht das Capfile so aus:

require 'rubygems'
require 'murder'

# Pfad zur Murder-Installation
# auf den Servern
set :remote_murder_path, '/usr/share/murder' 

# Torrent-Rollen für SSH-Logins
role :peer, 'user@main.mydatacenter.corp',
	'user@node1.mydatacenter.corp',
	'user@node2.mydatacenter.corp:1022'
role :seeder, 'user@main.mydatacenter.corp'
role :tracker, 'user@main.mydatacenter.corp'

# Optional: weitere Einstellungen
# aus config/deploy.rb laden
# load 'config/deploy.rb'

Wir definieren unsere Maschine mit dem DNS-Namen main.mydatacenter.corp als Torrent-Tracker, Seeder und Peer.

Der Tracker wird den Deployment-Prozess koordinieren. Der Seeder wird die zu verteilenden Torrents initial zur Verfügung stellen.

Peers sind die Empfänger der Torrents (hunderte oder mehrere Tausend), die sich untereinander die Torrents zuschicken.

Die Servernamen werden für den ssh-Zugriff verwendet. Verwendet einer der Server einen anderen Port als 22 für ssh, so muss dies im Capfile extra angegeben werden.

Mit dem capify-Aufruf wird außerdem ein Default-Deployment-Script im Unterverzeichnis config/deploy.rb erstellt. In dieser Datei können weitere Details zu den beteiligten Server angegeben werden (Weitere Infos dazu gibt es in der Capistrano-Doku). Im hier beschriebenen Beispiel verwenden wir die Datei nicht.

Verteilung

Nun geht der Rest relativ einfach.

Wir starten auf main.mydatacenter.corp den Tracker:

$ cap murder:start_tracker

Wir erzeugen einen Torrent aus den Dateien im Verzeichnis /myproject/deploy:

cap murder:create_torrent tag="Deploy1" files_path="/myproject/deploy"
cap murder:start_seeding tag="Deploy1"

Wir verteilen den Torrent an alle Peers:

cap murder:peer tag="Deploy1" destination_path="/tmp"

Ist dieser Befehl ausgeführt, stoppen wir Seeder und Tracker wieder:

cap murder:stop_seeding tag="Deploy1"
cap murder:stop_tracker

Fazit

Murder kann nicht nur Dateien in Torrent-Geschwindigkeit kopieren. Auf den Peers lassen sich über Hooks vor und nach den Verteilungen Skripte starten, mit denen das Rollout noch weiter automatisiert werden kann. Denkbar sind das Starten und Stoppen von Servern, das Löschen und Kopieren von Dateien und vieles mehr.

Murder ist gedacht für den Einsatz innerhalb von großen Datacentern, in denen viele, ausschließlich vertrauenswürdige Parteien miteinander kommunizieren und in denen ausreichend Bandbreite zur Verfügung steht. Entsprechend müssen die Ports für SSH und das BitTorrent-Protokoll freigeschaltet sein. Das Aufsetzen und die Konfiguration eines Deployments sind mit geringem Aufwand möglich.

Im Ergebnis lassen sich dann umfangreiche Deployments innerhalb kurzer Zeit durchführen. Das BitTorrent-Protokoll sorgt dafür, dass die vorhandene Bandbreite effektiv ausgenutzt wird.

Abschließend verlinke ich noch auf ein Video mit einer Präsentation von Larry Gadea, einem der maßgeblichen Entwickler von Murder:

Twitter – Murder Bittorrent Deploy System from Larry Gadea on Vimeo.

Foto: Crows? von Dave Warley Lizenz: Creative Commons BY

Holisticon AG — Teile diesen Artikel

Über den Autor

Jan Weinschenker

Jan beschäftigt sich sich seit knapp sieben Jahren mit dem Design, der Entwicklung und der Verbesserung von verteilten Web- und Unternehmensanwendungen. Die Erstellung solider, qualitativ hochwertiger Software, sowie deren Wartbarkeit liegen ihm dabei besonders am Herzen. Jan Weinschenker ist Organisator des Web-Performance-Meetups Hamburg.

Antwort hinterlassen