プログラマでありたい

おっさんになっても、プログラマでありつづけたい

QNAP TurboNASの新作、Turbo NAS TS-x21とTS-x20シリーズが出たよ〜


 一家に一台のNASは常識だと思いますが、NASのバックアップは未だ難しい問題です。別エントリーに詳しく書いていますが、個人的にはAmazon S3+(Glaicer)が今のところ最善だと思います。そうなるとNAS自体にS3へのバックアップ機能があればベストです。現状の選択肢の中では、QNAPが中々良い製品ではと考えています。そんな中でQNAPが2年ぶりに新モデルの発表をしています。これは、夏のボーナスで買わないとダメですね。

QNAPとは?



 QNAPは、NASです。しかし、NASの割には保存用のディスクがついていないという珍しいNASです。少し触ってみて解ったのですが、QNAPの実体はUbuntuベースのサーバです。普通にsshでログインすることも出来ます。UbuntuのサーバにWebのユーザインターフェースをつけて、筐体にディスクを追加出来るようにしているのがQNAP TurboNASです。つまりただのNASではなく、サーバとして考えれば魅力度は195%します。LinuxのサーバなのでS3にバックアップすることはジョブとして実行することはお手のものです。sshでログイン出来るので、独自で作ったjobを動かすことも可能でしょう。ということで、定期的なjobを実行してくれるサーバが、自宅でファイルサーバのような形でやってきたとなればお得感が伝わると思います。

QNAPの型番



 今回発表されたのは、TS-x21とTS-x20シリーズです。xの部分がディスクが入る本数です。TS-x21シリーズは、4ベイのTS-421、2ベイのTS-221、1ベイのTS-121があります。同じくTS-x20シリーズは、4ベイのTS-420、2ベイのTS-220、1ベイのTS-120があります。どのタイプにするかは、用途次第だと思います。私は、TS-221でRaid1で使うのが良いかなぁと考えています。

まとめ



 LinkStationを魔改造してsshを使えるようにするという人は、それなりにいるようです。でも、そんなことをしなくても、QNAPだと最初から出来ます。NASと常時起動しているサーバというのは相性が良いです。自宅の執事代わりに、QNAPを買うのは如何でしょうか?


See Also:
QNAPのNASで、Amazon S3で自動バックアップしたい
Amazon Glacierも出たので、改めて個人のバックアップ戦略を考えてみる
Amazon S3からGlacierへの自動アーカイブ機能が出来たので、個人のデータ保管戦略をしつこく考える



s3fsの何が悪いのか?

 awsでシステムを組んでいると、一度は使ってみたくなるのがs3fsです。まずs3ですが、これはAmazonが誇るオンラインストレージです。容量の拡張も思いのままで、ほぼ無限の領域を使える夢のようなサービスです。一方で、現在のところAmazonのデフォルトのサービスでNASにあたるものは提供されていません。AWS上でシステムを組む上で、ここが制約になる場合があります。それであれば、s3をファイルシステムとして扱えば良いじゃないかというのが、s3fsプロジェクトです。
 コンセプトが解りやすく、上手くいけばAWSのサービスを保管する素晴らしいプロジェクトに思えます。しかし、実際のところ中々運用ベースで使うのが難しいのが、このs3fsです。理由としては、遅い・安定しないの2点に尽きます。何故なのでしょうか?s3fsのアプリとしての成熟度の問題でしょうか?ということで、アーキテクチャレベルで考えてみました。(単純化していて正確ではない部分もあり、突っ込みどころは多いと思います。)

一般的なファイルシステムの構造



 物理デバイス(ディスク)の上に、OSレイヤーが乗っかりアプリからファイルが扱えるようになっています。

S3の構造



 S3はオンラインストレージです。ファイルシステムではありません。OSレイヤーの上のアプリ層で、ストレージを扱えるようにしています。厳密にいうとS3は多重化されているので、この上のネットワークでユーザがどのファイルにアクセスするかが決定されます。

s3fsの構造



 s3fsは、オンラインストレージであるS3を束ねて仮想的にファイルシステムとして扱おうというアプリです。ネットワーク(インターネット)を挟んでいるのが解りますね。

 内部的な構造はみていませんが、S3をブロックストレージとして扱う為にキャッシュやバッファの仕組みを内包していると思います。一方でインターネット経由というところに根本的な不安定さの原因があるのではと思います。インターネットですから接続の不安定さもあり、またそもそもレイテンシが通常のファイルシステムより数百倍はあります。そこを解消する為の仕組みと解消しきれない部分が、アーキテクチャとしてのs3fsの問題だと思います。

まとめ



 上記のような理由でs3fsは、余りお勧めできません。一方で、特性を理解した上で選択的に使うのは良いと思います。個人的にはAmazonさん自身に、S3ベースのファイルシステムを出して貰うことを切に願います。ただし、アーキテクチャから考えれば、かなり難しいのではと思います。現状でのAmazonさんが出した解の1つは、StorageGateway on EC2なんでしょうね。


See Also:
Storage Gateway on EC2とオンプレミスのStorage Gatewayの構成について


参照:
s3fs


Gitのフック機能で、リポジトリをAmazon S3にバックアップする

 Gitのリポジトリ運用の要となるのが、バックアップ運用です。一般的には、定期的なバックアップを仕込むといった運用をしている所が多いと思います。一方で、定期作業であれば最終バックアップから障害発生時点でのデータ消失という危険性はあります。ということで、プッシュごとにフルバックアップが取れれば理想です。それも利用者が意識しない形でないといけません。
#Gitなので分散リポジトリから復旧という話もありますが。


 ということで、Gitのフック機能でAmazon S3にバックアップするパターン例です。やり方は簡単で、リポジトリ毎のhooksの部分に同期スクリプトを呼び出すコマンドを書けば良いだけです。


post-receive,post-update等に記載

#!/usr/bin/env bash
/foo/var/sync.sh &

ポイントは、&でバックグランドプロセスにした上で同期プログラムを呼び出すことです。何故ならデータ量に応じて、同期に時間が応じます。その間、コミットしたユーザを待たせるのを防ぐためです。


同期方法は、s3syncでもs3cmd syncでも何でも構いません。
sync.sh

s3cmd sync --verbose --recursive --delete-removed --reduced-redundancy /some/git/project s3://yourbuket/git/project


 簡単便利で、安心のgit+s3のバックアップでした。もちろん、GitではなくSubversionでも大丈夫です。是非、お試しあれ!!


See Also:
Amazon EC2からS3にバックアップする為のS3Sync
Amazon Linux AMIにGit + Gitolite + Gitlabをインストールして、プライベートGitHubを構築する
Git+DropBoxで、プライベートリポジトリ作成。或いはGitをAmazon S3でバックアップ
週末プログラマにお薦め!!Subversion+DropBoxで似非分散型バージョン管理


Windows機からS3をマウントして、ネットワークドライブとして使う方法

 AWSのサービスの中でS3が一番ラブです。最近20%程値下げされたので、東京リージョンでも1ヶ月1GB保存しても$0.100と約8円と格安です。さらにS3からGlacierに自動でアーカイブするサービスが出来たので、更に安く使うこともできます。ということで、個人でももっともっとS3を使ったら良いと思います。そこで、今回はWindowsでS3をマウントして、ネットワークドライブとして使う為のツールを2つ紹介します。GladinetTntDriveです。


 どちらもWindowsでS3のバケットをマウント出来るツールです。イメージ的には、一つのバケットを一つのドライブとして扱うことが出来ます。


 セットアップは簡単で、どちらもサイトからダウンロードしてウィザードに従ってインストールするだけです。その際は、.Net Framework 2.0が必要です。インストール後に、ドライブの設定を行います。必要な情報は、AccessKeyとSecretAccessKey、そしてマウントするバケット名です。

Gladinetの設定



 まずマウントする対象を選びます。S3のリージョンを選びます。S3の他に、Windows AzureやSkyDrive、Google DriveやPicasaなどの色々なクラウド・ストレージや、FTPやWebDavなどの定番のプロトコルなど、割とありとあらゆるがマウント出来ます。


 次にBucket ACLとAccess Key、SecretとBucket Nameの指定です。Bucket ACLは特に指定する必要がありません。Access KeyとSecretAccessKeyは、マスターアカウントの場合はAWSコンソールのアカウント管理のセキュリティー証明書から取得できます。IAMアカウントの場合は、発行時に取得出来ます。Bucket Nameはマウントしたいものを指定してください。注意点としては、前の画面で選択したリージョンと同一のものを指定してください。

TntDriveの設定



 TntDriveもGladinetとほぼ同様の設定で利用可能です。AccessKeyとSecretAccessKeyとS3のBucket名を指定します。TntDriveの場合は、マッピングするドライブ名も指定出来ます。

ドライブの使い方



 マウントした後は、GladinetもTntDriveもほぼ同等に扱えます。クラウド上のファイルも閲覧できますし、ファイルを置くと自動的にアップロードされます。(Gladinetの場合はProfessionalライセンスが必要です。)結構便利です。注意点としては、通信料は当然ながらS3の体系に従います。アップロードは無料ですが、ダウンロードは1GBあたり$0.201(1GBまで無料)かかります。またPUT、COPY、POST、または LIST リクエスト等でもリクエスト数の応じて課金されます。

ライセンス料



 GladinetとTntDriveとも、1ヶ月は無料で使えます。Gladinetの場合はその後はフリーのライセンスになりダウンロードだけ出来ます。Gladinetは$49.99のProfessionalライセンスと$59.99のPremiumライセンスがあります。TntDriveは、$39.95のPersonal Licenseと$59.95のCommercialライセンスがあります。

まとめ



 Windowsをメインに使っていませんが、マウント出来るというのは中々便利です。GladinetかTntDriveのどちらを選ぶと言われると、S3の方に特化しているTntDriveで充分だと思います。DropBoxなどフリーで便利なオンライン・ストレージがあるので、個人でS3をストレージとして使おうという人は少ないと思います。ただ従量課金で容量無制限に使えることや、Glaicerとの連携等も含めて、ディープなことに使おうと思うとS3はかなり有力な選択肢だと思います。Windowsユーザの方は、Gladinet/TntDrive+S3を試してみては如何?


See Also:
Amazon S3からGlacierへの自動アーカイブ機能が出来たので、個人のデータ保管戦略をしつこく考える
Route53+S3 Web Hostingでホスト名無しのドメイン設定が出来るのか?
Git+DropBoxで、プライベートリポジトリ作成。或いはGitをAmazon S3でバックアップ
Amazon Glacierも出たので、改めて個人のバックアップ戦略を考えてみる
本当に月額10円でレンタルサーバを始められるのか? S3で静的サイト構築を検証


参照:
Download TntDrive. Download TntDrive to Mount S3 Bucket as Windows Drive!
GLADINET - Download Gladinet Cloud Suite

AWS SDK for RubyでS3の操作をする

AWS SDK for Rubyでのファイル関係のS3の操作です。一覧取得とファイルの取得の方法をメモ程度にまとめています。一覧取得については、基本的には2通りあってBucket.as_treeからツリー形式で取得する方法とBucket.objects.collectからキーの一覧を取得する方法があります。S3の構造をよくよく見てみると、フラット構造のものを擬似的にツリー構造にしているだけのようです。Bucket.objects.collectからフィルターして取得するのが効率が良いかもしれません。

require 'aws-sdk'

AWS.config({
  :access_key_id => 'your_access_key_id',
  :secret_access_key => 'your_secret_access_key',
})
s3 = AWS::S3.new

bucket = s3.buckets['yourbucketname']
tree = bucket.as_tree

#ディレクトリ一覧
directories = tree.children.select(&:branch?).collect(&:prefix)
directories.each{|directory|
  puts directory
}

#ファイル一覧
files = tree.children.select(&:leaf?).collect(&:key)
files.each{|file|
  puts file
}


#キー一覧(ファイル&ディレクトリ一覧)
puts "keys"
keys = bucket.objects.collect(&:key)
keys.each{|key|
  puts key
}


#サブフォルダ以下のファイルの一覧表示
puts "sub folder"
tree = bucket.as_tree({:prefix => 'subfoldername/'})
files = tree.children.select(&:leaf?).collect(&:key)
files.each{|file|
  puts file
}


 オブジェクトの取得

s3 = AWS::S3.new
obj = s3.buckets['yourbucketname'].objects['filename']
#ファイルの書き込み
obj.write('Hello World!')
#パス指定でファイルの書き込み
obj.write(:file => path_to_file)
#ファイルの読み込み
obj.read
#認証付きURLの発行
puts obj.url_for(:read, :expires => 60) #seconds


 後はStreamingアップロードや暗号化など色々な機能あります。公式のドキュメントを読めばひと通り書いてあるので、是非ご一読ください。


参照:
AWS SDK for Ruby


AWS SDK for RubyでS3へのアクセス認証付きURLを生成する


 Amazon S3のアクセスコントロール(Access Control)には、次の5タイプがあります。

  1. IAMのポリシーを使った制御(Using IAM Policies)
  2. バケットポリシーを使った制御(Using Bucket Policies)
  3. ACLを使った制御(Using ACLs)
  4. ACLとバケットポリシーを併用した制御(Using ACLs and Bucket Policies Together)
  5. 認証付きクエリーを使った制御(Using Query String Authentication)


 用途に応じて上記の方法を使い分けるのですが、この中で面白いのが認証付きクエリーを使った制御です。要は、一時的に使用権を与えたURLを発行するという方法です。有効期限等を設定出来るので、期間限定のURL等を発行出来ます。キャンペーンで使用するといった方法や、アプリケーションから安全にアクセスさせるなど色々な用途があると思います。
 AWS SDK for Rubyを使って簡単に実現出来るので、サンプルのプログラムを書いてみました。

require 'aws-sdk'

AWS.config({
  :access_key_id => 'your_access_key_id',
  :secret_access_key => 'your_secret_access_key',
})

s3 = AWS::S3.new
obj = s3.buckets['yourbucketname'].objects['file_name']
puts obj.url_for(:read, :expires => 60) #seconds

これを実行すると、次のようなURLが発行されます。

https://yourbucketname.s3.amazonaws.com/file_name?AWSAccessKeyId=your_access_key_id&Expires=1348903870&Signature=we8vmLn%2BMB4nDx8bl7rz4nN0qcU%3D

 この例では、60秒間だけ有効なURLを発行されています。期限内でアクセスすると無事ダウンロード出来ますが、時間が過ぎると下記のようなエラーが出ます。Signatureがついているので、ExpiresやAccessKeyIDを勝手に変更しても無効になります。


有効期限が切れた場合のエラー


AccessDenied
Request has expired
964B6939794DBCEC
2012-09-29T07:18:01Z

1sFYnUfBAzVXwpgU1xMZa2C+02wLSp4CZLTFdp+wfzoOJcqiyj8r3zwQ3J41rnR2

2012-09-29T07:26:02Z


パラメータを改変した場合のエラー例


SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method.
47 45 54 0a 0a 0a 31 33 34 38 39 30 35 37 35 32 0a 2f 64 6f 63 6c 69 73 74 2d 74 6f 6b 79 6f 2d 72 65 67 69 6f 6e 2f 41 57 53 5f 53 69 6d 70 6c 65 5f 49 63 6f 6e 73 5f 70 70 74 2e 70 70 74 78
4B4BC82317D4BDC7
FPI7UtPOi6TRbQrDaWUEy2qme3UrqjpsV0zYMm8TNkfj3i0Qvs5JGswZAR78KFWE
imgbX/858pTQvsNmR8lbbOA8LDE=
GET 1348905752 /yourbucketname/file_name
your_access_key_id


 例えばS3と連携するiPhone/iPadアプリを作ろうとする場合、方法としてはiOSとS3を直接やりとりするという方法があります。その為のSDKも提供されています。一方で、そうするとアクセスコントロールをS3の方ですべてコントロールする必要があります。IAMを使えば可能ですが、現状の所まだ面倒くさいと思います。
 そんな時に、既存のサーバ側のアクセス・コントロールの資産を活用して、S3=>サーバ・アプリ=>iOSアプリという3層構造にしておけば楽な場合もあります。その際に、サーバ側でユーザごとの権限を確認した上で、認証付きURLを発行しiOSとS3の間でファイルのやり取りをするというのは有効な方法なのではと思います。
 活用方法は色々あるので、ぜひ一度ご検討あれ!


参照:
Access Control - Amazon Simple Storage Service
Signing and Authenticating REST Requests - Amazon Simple Storage Service
cloudpackブログ - AWS SDK for RubyでS3の期間限定のURLを生成する
Module: AWS — AWS SDK for Ruby

Git+DropBoxで、プライベートリポジトリ作成。或いはGitをAmazon S3でバックアップ

 2年程前に書いたSubversion+DropBoxの焼き直しです。今風にGitで書きなおして見ました。後は、同期だけでは心許無いので、バックアップ戦略について考えてみました。


まず解決したい問題は、下記の3つです。2年前から変わっていませんね。

  1. ソースのバックアップをどこか違うところに持ちたい
  2. ネットワークがオフラインの時でも、コミット出来るようにしたい
  3. 違う環境から作業しても、最新のソースを取れるようにしたい


 まず1のソースのバックアップについてです。厳密にはバックアップではなく、同期で実現しています。開発機単体ではなくDropBoxにコピーされるので物理的障害等に対する対策は充分です。一方でDropBoxの特性として、DropBox上に置いているリポジトリを消してしまうと、消された状態で同期されてしまいます。DropBox上のリポジトリと、ローカルのワーキング・リポジトリに分ければ問題はなくなります。保険の為にAmazon S3にバックアップも設定する方法も、併せて紹介したいと思います。
 次に2のネットワークがオフラインの時でもコミットしたいという点ですが、実はGitを採用している時点で実現できています。GitにDropBoxを併用することで、3の違う環境から作業しても最新のソースを取れるようにしたいを実現出来ます。それでは、具体的な手順を見て行きましょう

DropBoxの準備



 何はさておき、DropBoxのアカウントが必要です。まだアカウントを持っていない方は、この招待コードから開設して頂けたら通常で開設するより、+500MBの容量をゲット出来ます。(私のアカウントも+500MBになりますので、宜しければお願いします。)
 アカウント開設したら、Windows,Macそれぞれの手順に従ってDropBoxアプリをインストールしてください。あまり難しくないのと、バージョンごとにUI等の見た目が変わるので、手順は割愛します。

DropBox上にリポジトリの作成



 Macを想定してのコマンドです。Windowsの方は、適当にコマンド置き換えてください。
ポイントとしてはリポジトリの作成時にbareオプションを指定して、DropBox上のGitリポジトリにはGitの管理情報のみを作成するようにします。

cd ~/Dropbox/
mkdir git
mkdir git/project1
cd git/project1
git --bare init --shared=true

DropBoxからクローンして、ローカルで開発する



 プログラミング等の作業用ディレクトリは、DropBox以外のローカルディスク上につくります。

cd ~/projects
git clone ~/Dropbox/project1

 後は、通常のGitの使い方と同じです。

cd ~/projects/project1
〜プロジェクトのファイル等作成〜
git add .
git commit -m"最初のコミット"
git push origin master

 逆に、XCode等でローカルのGitリポジトリが既にある場合は、次のように追加します。

git remote add origin ~/Dropbox/git/project1/
git push origin master

共有してチームで使う



 またDropBoxの共有機能を利用することにより、GitHubのTeam共有的なことも出来ます。やり方は簡単で、DropBoxのWeb管理画面から該当のリポジトリを共有するだけです。そうすると、任意の相手を招待できます。共有した後の手順は、先ほどの手順と同じです。なんちゃって共有リポジトリの出来上がりです。

 注意点としては、同時にgit pushするとコンフリクトの恐れがあります。シビアな使い方をする場合は、GitHubのPrivateリポジトリを使うか、正規のGitサーバを用意しましょう。

Amazon S3を使ったバックアップの戦略



 最後に、DropBox領域のバックアップです。DropBoxの内部構造的には、Amazon S3のストレージを使っているので論理上の堅牢性はAmazon S3と同等の99.999999999%と9が11個並ぶレベルです。一方で、DropBox社や自分自身の問題でデータを消失する可能性は、一定の確率であると考えるべきです。その為のバックアップです。バックアップ先はどこでも良いと思うのですが、やはりクラウドのストレージにバックアップするのが便利で良いです。
 アーキテクチャ的に考えるとAmazon以外のクラウドにバックアップするのが本来良いのですが、私はAWS一押しなのでAmazon S3にバックアップします。単純にDropBoxの領域とS3を同期するだけでは全く意味が無いので、どうバックアップするか考える必要があります。
 まず防ぎたい事態とはDropBoxのGitのフォルダを間違えて消してしまい、それがそのまま消された状態で同期されることです。対策としては2つ考えられます。1つ目は、DropBoxの領域を定期的にバックアップして何世代か持つことです。誤って消してしまったとしても、世代が残っている間に気がつけば復元できます。問題は、何世代持つか。またバックアップの間隔をどうするか。間隔を長くすれば、その間に気づく可能性が高くなります。一方で前回バックアップからの差分が取りこぼされる恐れがあります。対策としては、間隔を短く世代数を多くすることです。ストレージ料が掛かる以外は、問題は少ないように見えます。
 一方でバックアップ間隔を短くしても、その間でバックアップ漏れが起こる可能性は否定できません。漏れを無くすにはgitのpush時にS3に対する同期コマンドを発行すれば良いのです。先ほど同期は意味がないと言いましたが、Gitコマンドをトリガーとする同期であれば、人的ミスによるリポジトリ消失を防ぐことが出来ます。
 また全く別の方法として、S3自体にリポジトリを置くという方法があります。JGitを使えば実現できますが、クライアント側の制約がある程度つきます。これについても、また機会を改めて紹介したいと思います。

GitのHookコマンドによる同時の実行



 Gitには、各種のフックが用意されています。主にクライアント側とサーバー側のフックの2種類があります。今回はサーバ側のフックであるpost-updateで実行します。これはgit pushが実行された後に実施されます。ここに同期プログラムを仕込めばよいです。S3への同期はs3syncもしくはs3cmdで可能です。この辺りにまとめてるので、参照してください。

まとめ



 DropBox+○○という組み合わせは、今では色々と出ています。これはDropBoxの単純性+手軽さが優れている点だと思います。一方でDropBoxだけでは解決出来ない問題は、他のサービスと組み合わせを試してみてください。効果抜群になるケースも沢山ありますよ。


See Also:
週末プログラマにお薦め!!Subversion+DropBoxで似非分散型バージョン管理
StatSVNのGit版 GitStatsを使ってみる
XcodeでGitのリモートリポジトリ(remote repository)を追加する方法
Amazon EC2からS3にバックアップする為のS3Sync
Markdown記法+Git+md2review+ReVIEWで原稿・ドキュメント管理


参照:
Git 7.3 Git のカスタマイズ - Git フック