2008年8月17日日曜日

低コストかつ確実にプログラマっぽくバックアップする方法

はい、釣れましたねw

一言で言えば、失ってはマズイデータ本体と、失ってもかまわないプログラムやアドインなどのリストファイルを圧縮し、Rubyを使ってAmazon S3に転送しておくだけなんですけどね。

ネタ元はコレ。

はじめてのAmazon EC2&S3 ~これからの新サービスの公開の形~:第2回 Amazon S3をバックアップストレージとして使おう|gihyo.jp … 技術評論社

まぁほぼパクリなんだけど、実際に使ってみてわかったのは、思った以上に便利だったって事。

今回は自分のPC(MacOS10.5)を対象にしてるけど、WindowsXPだろうが、Linuxサーバだろうがちゃんと動くし、一番低コストだと思う。

検証1:本当に低コストか?

うん、たぶん圧倒的に低コスト。

普通バックアップ先にはテープとかハードディスクを使うと思うんだけど、 Amazon EC2とS3を使ってみる(その1 費用比較検討編) でも比較しているように、S3のストレージ容量は非常に安い。

実際おいらの利用料は毎月100円以下だよ。(ちょっと計算してみればどのくらいの容量まで100円でバックアップできるかわかるよね)

自分でHDD買ってきてタイムマシーン経由で使うよりずっと安い。現在の空き容量を気にする必要もないし。(まぁ定期的に消した方が安くあがるけど)

サーバのバックアップとして使うなら、それこそトータルコストを100分の1とかに圧縮できるかもね。ハード高いから。

検証2:本当に確実?

んーまー、今のところrubyのスクリプトを起動しないとバックアップしてくれないから、確実かどうかは微妙だなぁ。

cronに登録しても良いけど、その時間にPCを起動しているかわかんないしね。

この点ではタイムマシーンに劣るかも知れない。(タイムマシーンでも無線でHDDを接続してないと忘れそうだけど)

その点、サーバのバックアップだと、負荷さえ気をつければいつでもバックアップできそう。費用ならLVMでスナップショット取ってもいいだろうし。

今のところ重要なファイルはtar.gzに圧縮して、この1ファイルだけ転送してるんだけど、今のところ圧縮失敗とか転送失敗は起きていない。(まぁ、可能性が無いわけではない)

まぁ手動起動してるんだから、プロンプトの結果を確認すればわかるし。

バックアップ先のストレージは天下のAmazonの分散ストレージなんだから、ストレージ上のデータがクラッシュすることは無いだろうし、毎回フルバックアップしてるようなもんだから、リストアも楽。

検証3:本当にセキュア?

うん、たぶんこれは本当。

S3との通信はRSA認証鍵を使ったssh経由(あれ? SSLクライアント認証じゃないよな? ちょと混乱)で行われるから、経路は暗号化されている。

普通のサーバより堅牢(そのへんのレンタルサーバだとssh/telnet/ftp/pop3は平文のパスワード認証でしょ?)だと思うよ。

検証4:使いやすい?

これも問題にならないと思うなぁ。

上記の通り、rubyのスクリプトを起動しなきゃならないのは、面倒といえば面倒だけど、起動スクリプトをアイコン化(Dockに登録するとか)しておけば、ちょっとトイレに立つ時にクリックするだけだし。

おいらのバックアップファイルは圧縮後300MBぐらいなんだけど、10分以内にバックアップは終わっているみたい。

検証5:でもデータ全部をバックアップ取ると何百GBもあるんだけど…

いやいや。それはバックアップ対象をちゃんと分類できていないのが原因だ。

おいらも250GBのHDDがほぼ一杯の状態で使ってるけど、過去のソースや素材絡みとかは変化しないから、DVDなりHDDにバックアップしておけば、S3に取る必要はない。(使ってないHDDぐらいあるでしょ。1年に1回ぐらいしかこんなのバックアップしないんだから)

iTuneの中に入れた音楽とか、エロ関係その他は失っても痛くないだろう。

アプリとかプラグインとかMacPorts(Mac用パッケージシステム。apacheとかmysqlはこれで入れる)については、何を入れていたかだけ覚えておけば、もしもの時に復旧はすぐにできる。(どうせすぐバージョンアップするし)

今回のバックアップスクリプトも、インストール済みアプリのリストとport installedの結果とgem listの結果をテキストファイルとして保存しているよ。

今作業中の案件に関する資料とかソース類が、一番失っちゃマズイもので、毎日変化するモノなので、これを最優先でバックアップすべきだけど、subversionなどでソース管理してるなら必要ないかもね。

…とかとかやってくと、圧縮すべきファイルって相当限られてくると思うんだ。

んで、圧縮しやすいように、1つのディレクトリツリーの下にバックアップ対象をまとめるようにしておく。まぁ、実際にはまとめきれないから、3つぐらいのディレクトリを指定することになるんだろうけど。

検証6:もしかして、プログラマっぽくって、Ruby使うから?

…そうだよ?

でも、カスタマイズも楽だし、結構いいと思う。

よしわかった、で? どうやって使うの?

ソース短いので載せちゃおう。

#!/usr/bin/env ruby
require 'rubygems'
require 'aws/s3'
require 'tempfile'

include AWS::S3
Base.establish_connection!(
    :access_key_id => 'アクセスキーをここに入れる',
    :secret_access_key => 'シークレットアクセスキーをここに入れる'
)
bucket_name = 'バックアップに使うバケット名をここに入れる'

# 再インストールする事で復旧可能だけど、何をインストールしていたか知りたい場合、
# ここにそのテキストを生成するコマンドを書く
list_target_commands = [
  'gem list',
  'port installed',
  'ls -a /Applications/',
]

# 上記コマンドの出力を保存するためのファイルパスを書く
installed_list_file = '/pass/to/your/installed_list_file.txt'

# バックアップ対象ディレクトリ/ファイルを書く
backup_target_directories_and_files = [
  '/Users/maimuzo/Documents',
  '/Users/maimuzo/Sources',
  'installed_list_file'
]

puts "backup started at " + Time.now.strftime("%Y/%m/%d %H:%M:%S")
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
puts "Executing commands..."
File.open(installed_list_file, 'w') do |list_file|
  list_file.puts "This file was made at " + timestamp
  list_target_commands.each do |command|
    puts "$ " + command
    list_file.puts "$ " + command
    list_file.puts `#{command}`
  end
end

tempfile = Tempfile.open(bucket_name)
tempfile.close
tar_command = 'tar cfz ' + tempfile.path + ' ' + backup_target_directories_and_files.join(' ')
puts "Executing tar command..."
puts "$ " + tar_command
system tar_command 

puts "Saving to Amazon S3"
key = '%s.tar.gz' % timestamp
S3Object.store(key, tempfile.open, bucket_name)
puts "Backuped file to #{bucket_name}/#{key}"
puts "backup finished at " + Time.now.strftime("%Y/%m/%d %H:%M:%S")

でこれを起動するだけ。見通し良いからカスタマイズも簡単でしょ?

普通自分のPCなんてマメにバックアップしてる人はいないんだろうけど、これコピペして実行するだけで、かつ100円/月ぐらいで安心が買えるなら安いもんでしょ。バックアップ用市販ソフトとかいらないし。

下手に中途半端なリビジョンが出来ない分、subversionやgitより、自分のPCのバックアップ用としては、こちらの方が適しているかもね。

0 件のコメント: