この記事は、ConoHa Advent Calendar2015の1日目の記事です。
こんにちは、ひろのぶ(@hironobu_s)です( ´ ω ` )
勢いでカレンダー作った本人です。
つくった。さみしいからみんな登録してね。 / ConoHa Advent Calendar 2015 https://t.co/Y8bu8NRtmC
— Hironobu Saitoh (@hironobu_s) 2015, 11月 10
なーんにも考えてなかったのですが、イベントなどで「オブジェクトストレージをもっと簡単に使えたら良いのだけど」と聞かれることが多いのを思い出したので、今回はそれをネタにしてみます。
ConoHaオブジェクトストレージ
オブジェクトストレージはREST APIを使ってアクセスするタイプのストレージです。おおざっぱに言って「アクセス速度は遅いが、大容量のデータを安価に格納できて、HTTPSが通ればどこからでもアクセス可能」という特徴があります。詳しくはSoftware Design2015年10月号に書いたのでそちらをご覧下さい。
ConoHaにはOpenStack Swiftベースのオブジェクトストレージが用意されていて、これを使うと100GB/450円から上限無しで容量を増やせるストレージが手に入ります。
ちなみにGMOアプリクラウド(あんず側)にも同じものが用意されていますし、この記事の内容もきっと使えるはずです(アカウントがなかったので試せなかった)
オブジェクトストレージをマウントする
オブジェクトストレージはREST API経由でアクセスするので、そのままではファイルシステムとしては使えません。サーバーなどからアクセスするには、REST APIを叩くクライアントツールなどが必要です。
そこでSwiftFSというツールを作成しました。これはOpenStack Swiftベースのオブジェクトストレージをファイルシステムとしてマウントするものです。これにより、あたかもローカルストレージのように使うことができるようになります。
同じアプローチのものでcloudfuseがありますが、複数ノードからマウントすると同期が取れなくなる(キャッシュが入っているため?)ことと、C++実装なので自分でいじれなかった(私がC++知らない)ので、FUSEの勉強がてら自分で作ってみることにしました。
SwiftFS
SwiftFSはGoで実装されたファイルシステムです。GitHub Releaseから実行ファイルをダウンロードするだけで使えます。現状ではLinux(amd64)環境のみで動作します。
インストール
curl -sL https://github.com/hironobu-s/swiftfs/releases/download/current/swiftfs.amd64.gz | zcat > swiftfs && chmod +x swiftfs
使ってみる
ConoHaで使ってみましょう。まずコントロールパネルにアクセスしてAPIの情報を確認します。必要なのは「テナント名」「Identity Serviceのエンドポイント」「APIユーザー名」「APIパスワード」です。
それらを、README.mdの「認証情報の設定」に従って設定を行います。環境変数で設定しても良いですし、コマンドライン引数で渡してもOKです。
コマンドライン引数で渡す
一応可能ですが、長くなるのでなかなかしんどいです。
./swiftfs --os-username [APIユーザー名] --os-tenant-name [テナント名] --os-password [APIパスワード] --os-auth-url [Identity Serviceエンドポイント] コンテナ名 マウントポイント
環境変数で渡す
こちらがおすすめです。このOS_で始まる環境変数はOpenStack系ツールでよく使われるもので、オープンスタッカー(?)の皆さんにはおなじみですね。下記の内容を括弧内を埋めて、そのままターミナルにペーストします。
export OS_USERNAME=[APIユーザー名]
export OS_TENANT_NAME=[APIテナント名]
export OS_PASSWORD=[APIパスワード]
export OS_AUTH_URL=[Identity Serviceエンドポイント]
その後、swiftfsを実行します
$ swiftfs [コンテナ名] [マウントポイント]
-cオプションをつけると、コンテナが存在しない場合に自動的に作成してくれます。初回起動時はこちらが便利でしょう。
$ swiftfs -c [コンテナ名] [マウントポイント]
こんな感じでマウントされます(一番下)。あとは普通にcpやmvやmkdirなど、おなじみのコマンドが使えます。
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/dev--vg-root 47G 9.1G 35G 21% /
none 4.0K 0 4.0K 0% /sys/fs/cgroup
udev 2.0G 4.0K 2.0G 1% /dev
tmpfs 394M 3.2M 391M 1% /run
none 5.0M 0 5.0M 0% /run/lock
none 2.0G 168K 2.0G 1% /run/shm
none 100M 0 100M 0% /run/user
/dev/sda1 236M 38M 186M 17% /boot
.host:/ 233G 131G 102G 57% /mnt/hgfs
swiftfs 100G 247M 100G 1% /home/hiro/mnt
たとえば、swiftfsのソースツリーをマウント先にコピーしてみます。lsすると以下のようになりました。
$ ls -l mnt/
合計 0
-rw-r--r-- 1 hiro hiro 400 11月 30 23:24 Makefile
-rw-r--r-- 1 hiro hiro 2.4K 11月 30 23:24 README.en.md
-rw-r--r-- 1 hiro hiro 2.9K 11月 30 23:24 README.md
drwxr-xr-x 0 hiro hiro 4.0K 11月 30 23:24 app/
drwxr-xr-x 0 hiro hiro 4.0K 11月 30 23:24 config/
drwxr-xr-x 0 hiro hiro 4.0K 11月 30 23:24 fs/
drwxr-xr-x 0 hiro hiro 4.0K 11月 30 23:24 openstack/
-rw-r--r-- 1 hiro hiro 85 11月 30 23:24 swiftfs.go
-rw-r--r-- 1 hiro hiro 13 11月 30 23:24 swiftfs_test.go
これらはオブジェクトストレージにも同期されていて、以下のようにオブジェクトが配置されます。一見ファイルパスに見えますが、スラッシュを含むものも全てオブジェクトです。また、appやfsなどディレクトリに相当するものは、Content-typeがapplication/directoryのオブジェクトです。
# openstack object list swiftfs-container
+------------------------------+
| Name |
+------------------------------+
| Makefile |
| README.en.md |
| README.md |
| app |
| app/app.go |
| config |
| config/config.go |
| config/config_test.go |
| config/debug-transport.go |
| config/logformat.go |
| fs |
| fs/filesystem.go |
| fs/filesystem_test.go |
| fs/objectfile.go |
| fs/objectfile_test.go |
| fs/swiftfs-testrun |
| openstack |
| openstack/objectlist.go |
| openstack/objectlist_test.go |
| openstack/swift.go |
| openstack/swift_test.go |
| swiftfs.go |
| swiftfs_test.go |
| test.php |
+------------------------------+
使ってみると
さすがにNFSなどとは比較にならないほど低速で、大量のファイルにアクセスするケースや、アクセス速度が求められるケースには全く向きません・・・。やはりオブジェクトストレージの特性を考えると、、大容量を生かして大きめのファイルをガンガン放り込むような用途が良いでしょう。容量が足りなくなっても、コントロールパネルから無制限にサイズを増やせますしね。
あと、ConoHaはVPSのストレージサイズが50GBなので、「50GBじゃぁ足りないけどバックアップやログを溜め込むのに追加SSD買うのはちょっと高い」という場合にも良さそうです。事業者的にはSSD買ってもらえると良い売り上げになるのですが・・・
他には「運用中サーバーでディスク容量が足りない」なんで場合でも、SwiftFSを使えば実行ファイル一つダウンロードするだけで大容量の外部ストレージを追加でき、ストレージを圧迫しているログファイルやバックアップファイルなどを待避できます。この辺はGoのメリットですね。
ちょっと変わった使い方として、オブジェクトストレージにはバージョン管理という仕組みがあるので、これを使うと自動的に履歴を保存してくれるファイルシステムが作れます。定期バックアップなど作るときに、オブジェクトストレージ側で面倒見てくれます。(詳しくはこちらの「オブジェクトのバージョン管理」を参照)
というわけで、ファイルシステムからオブジェクトストレージを扱えのはなかなか面白いです。
SwiftFSはまだ低機能で怪しい挙動をすることもありますが、せっかく作ったので時間を見つけて改良していこうと思います。