2016.08.12

オブジェクトストレージをパッケージを使って活用してみよう(goofys編)

160729_objectstgoofys_mv

いよいよ暑くなってきました。アイスコーヒーとホットコーヒーを交代で飲む季節ですよ。コンビニに行ってでもホットコーヒーは必須!私はホットが無ければ給湯室でドリップしてでも飲みます。
さて今回は、またまたオブジェクトストレージです。

前々回、前回と続けてオブジェクトストレージです。また違うミドルウェアを探して試してみました。
今回もビルド・インストールと必要ですが、前回同様に最近は簡単にできるようになったので、ぜひとも皆さん試してみてください。
今回のミドルは「goofys」です。前回のs3fsは速度に問題が残り、実用は難しい感じでした。
goofysもs3fsと同様に、fsとしてOSにマウントさせることができるため比較しやすいので、試してみたくなりました。s3fsはC++というプログラム言語で書かれていますが、goofysはGo言語という最近登場したプログラム言語で書かれています。かなり高速で、筆者もやり始めました。

さて、まずは使うものの整理です。

【使うもの】
・CentOS7仮想サーバー(今回もALTUS CentOS7のテンプレート)
・EPEL(Linux拡張パッケージ)
・aws cli(s3cmdみたいなパッケージです。都合上いれてみることにしました。)
・goofys (packageが無いため、公式サイトからソースコードからビルド) 今回はversion1.8.0

今回の進め方としては、こんな感じです。

※今回も、『1.CentOS7をテンプレートから作成』と『2.パッケージを最新に更新』は前回とあまり代わり映えしないため、割愛します。前々回をご参照ください。
また、いつも通りバケットはs3cmdとかで作成をお願いします。


Ⅲ.ビルド環境をインストール

最新にupdateが終われば、ビルド環境を構築します。

◆パッケージ追加

# yum install golang fuse git

Ⅳ.goofysをビルド、そしてインストール

◆Go言語のためにパス設定をいれます。

export GOPATH=$HOME/go

◆ソース入手とインストール

go get github.com/kahing/goofys
go install github.com/kahing/goofys

◆インストールのチェック

これでgoofysのヘルプが表示されるとインストールできてます。

$GOPATH/bin/goofys -h
NAME:
goofys - Mount an S3 bucket locallyUSAGE:
goofys [global options] bucket[:prefix] mountpointVERSION:
0.0.6GLOBAL OPTIONS:
--help, -h Print this help text and exit successfuly.
-o value Additional system-specific mount options. Be careful!
--dir-mode value Permissions bits for directories. (default: 0755) (default: 493)
--file-mode value Permission bits for files (default: 0644) (default: 420)
--uid value UID owner of all inodes. (default: 1000)
--gid value GID owner of all inodes. (default: 1000)
--endpoint value The non-AWS endpoint to connect to. Possible values: http://127.0.0.1:8081/
--region value The non-AWS endpoint to connect to. Possible values: us-east-1, us-west-1, us-west-2, eu-west-1, eu-central-1, ap-southeast-1, ap-southeast-2, ap-northeast-1, sa-east-1, cn-north-1 (default: "us-west-2")
--storage-class value The type of storage to use when writing objects. Possible values: REDUCED_REDUNDANCY, STANDARD, STANDARD_IA. (default: "STANDARD")
--use-path-request Use a path-style request instead of virtual host-style. (deprecated, always on)
--profile value Use a named profile from $HOME/.aws/credentials instead of "default"
--use-content-type Set Content-Type according to file extension and /etc/mime.types (default: off)
--stat-cache-ttl value How long to cache StatObject results and inode attributes. (default: 1m0s)
--type-cache-ttl value How long to cache name -> file/dir mappings in directory inodes. (default: 1m0s)
--debug_fuse Enable fuse-related debugging output.
--debug_s3 Enable S3-related debugging output.
-f Run goofys in foreground.
--version, -v print the version

ここでヘルプを見ていて、1つのオプションが気になりました。

--profile value Use a named profile from $HOME/.aws/credentials instead of "default"

プロファイルと呼ばれるものはcredentialsに書かれているようですが、defaultでは各ホームディレクトリ直下の.awsという隠しディレクトリに格納されている前提で掛かれてます。
前々回のs3cmdでは.s3cfgという隠しファイルでした。
何か仕様が違うようなので調べたところ、これはaws cliと呼ばれるs3cmdと同等の機能をもった別なパッケージのファイルと分かりました。

aws cliをインストールは下記の通りですが、実は設定ファイルを1つ作っておけば大丈夫でした。
そのため、インストールしたくない方はインストール最後に出てくるcredeitialsのファイルを手動で作成してください。

◆aws cliのインストール
どうやらaws cliはEPELにあるようなので、インストールは比較的楽です。

# yum install epel-release
# yum update
# yum install awscli

これでインストール完了です。

$ aws --version
aws-cli/1.10.1 Python/2.7.5 Linux/3.10.0-327.4.4.el7.x86_64 botocore/1.3.23

インストールできています。

◆aws cliの設定

$ aws configure
AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: シークレットキー
Default region name [None]:
Default output format [None]: text

◆aws cliのcredentialsを確認

cat .aws/credentials
[default]
aws_access_key_id = アクセスキー
aws_secret_access_key = シークレットキー

結果、このファイルだけ手動で作成しても大丈夫でした。
念には念をいれてaws cliをインストールしておきましたが、s3cmdをいれておけばあとはcredentialsを作れば良いかと思います。


Ⅴ.goofysを使ってみませう

インストールができたので初期設定したいのですが、ここまで設定できた段階であらかた準備ができてます。早速バケットをマウントしたいと思います。

◆マウント先の作成(今回はローカルユーザ配下です)

$ mkdir ~/mntgo

◆annyバケットをマウント([anny]バケットは事前作成済み)

$GOPATH/bin/goofys --endpoint https://st.gmocloud.com/ anny ./mntgo/

◆annyバケットをALTUSから使る性能限定のエンドポイントからマウントする場合

$GOPATH/bin/goofys --endpoint https://inter-st.gmocloud.com/ anny ./mntgo/

◆マウントできたか確認

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 18G 1.9G 16G 11% /
devtmpfs 7.9G 0 7.9G 0% /dev
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 8.5M 7.8G 1% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
/dev/xvda1 497M 158M 340M 32% /boot
tmpfs 1.6G 0 1.6G 0% /run/user/0
tmpfs 1.6G 0 1.6G 0% /run/user/1000
anny 1.0P 0 1.0P 0% /home/hoge/mntgo

最下段にいます。1PBに見えるのか。。。
これでファイルが読み書きできるようになりました。

◆マウント解除する

# umount ./mntgo/

もしマウントを外す場合は、umountで外します。


Ⅵ.使って気付いたこと

前評判通りs3fsよりかは早いです。特にlsが早くなっており、条件では3倍くらい体感速度が変わります。まだ人が使っていけるぐらいになりました。
とはいえ、実HDDやクラウドのプライマリストレージのようにアプリから直接読み書きする場所には向かない速度なのも事実です。そのため、運用で使う場合にはデータベースやファイルのdumpはプライマリストレージ、永続的に保管したデータはオブジェクトストレージに格納。

前回とそっくりな話になってしまいますが、やっぱりアプリから直接書くのはエラー考慮を考えると、アンチパターンだと思います。想定よりオブジェクトストレージからの速度が遅いと、プログラム側は配慮する必要がありそうです。そのため、プライマリストレージ用途はまだ避けるほうが無難でしょうか。

【方式1】 アプリ → goofys領域  (速度・通信問題にはまるため、アンチパターン)
【方式2】 アプリ → ローカルディスク/キャッシュ領域 → rsyncなどで定期的 → goofys領域

システムを取り囲む登場人物の中で、速度比較をするとこんな感じでしょうか。
160729_objectstgoofys_src01


Ⅶ.もっと活用してみる!

前回と同じようにOSでマウントされた状態になりましたので、再びpythonスクリプトを試します。

◆s3fsでも同じバケットをマウントする

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 18G 2.2G 16G 13% /
devtmpfs 7.9G 0 7.9G 0% /dev
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 8.5M 7.8G 1% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
/dev/xvda1 497M 158M 340M 32% /boot
tmpfs 1.6G 0 1.6G 0% /run/user/1000
anny 1.0P 0 1.0P 0% /home/nkt/mntgo
s3fs 256T 0 256T 0% /home/nkt/mnts3fs

最下段がs3fsですが、サイズが4分の1に見えるけど、アプリなのだと(勝手に)解釈して先へ進みます。

◆1つのアプリ(プロセス)が1つずつ順次書き込む
前回使ったpythonスクリプトを使って約300KBのgifファイルを500ファイルを書き込みます。
goofys経由させた場合とs3fsを経由させた場合で比較します。

【goofys利用】

# python imgcp.py
500
inu :This is dir.
inu [ 0 ]
…(中略)
inu [ 498 ]
inu [ 499 ]
inu :Copy done.
Elapsed:988.05082202[sec]

500個で988秒なので、平均1個あたり2秒程度。

【s3fs利用】

inu [ 97 ]
inu [ 98 ]
inu [ 99 ]
inu :Copy done.
Elapsed:2125.4718492[sec]

何度かやっての結果ですが、これでも早いほう。1時間たって終わらないなど、かなり遅くなるケースもあるので扱いが難しいです。最後のログが1つのプロセスしかないのは、他の4プロセスが先に終わって、その後圧倒的な遅れで1つのプロセスが終わったためです。

時間帯によって掛かる時間は変わるのでお気をつけください。ただ何度かやってもgoofysが早いのは変わりませんでした。

◆1つのアプリだが5プロセスに分けてそれぞれ書き込む
100個ずつファイルを書けばトータル数は同じですね。

【goofys利用】

$ python imgcp-multiproc.py
...省略
usu [ 99 ]
inu :Copy done.
kani [ 98 ]
usu :Copy done.
kani [ 99 ]
kani :Copy done.
Elapsed:681.679957151[sec]

【s3fs利用】

$ python imgcp-multiproc.py
...省略
inu [ 96 ]
inu [ 97 ]
inu [ 98 ]
inu [ 99 ]
inu :Copy done.
Elapsed:1878.27575994[sec]

ここで3倍程度の差が出ただけでなく、s3fsに比べてgoofysは各プロセスの進行状態にバラつきが少なく、プロセスの終了タイミングがかなり違いです。
s3fsの検証は時間帯もあるんでしょうが、結果1つのプロセスが終わるのが遅れることが見受けられました。
同じオブジェクトストレージでも使い方で結構差が出ますね。
また新しいものを見つけたら試したいと思います!

この記事を書いた人

GMOクラウドユーキ

GMOクラウドユーキ

GMOクラウド株式会社 営業部プロダクトグループ所属  前職がシステムエンジニア、前々職が組込プログラマ。 インフラもそうだけど、技術はアーリーアダプター。 気が付くと新しい技術で何かできないか?ばっかり考えてます。 オフはFMラジオとバイクをこよなく愛する寂しがり屋。

インタビュー記事

この記事を書いた人

GMOクラウドユーキ

GMOクラウドユーキ

GMOクラウド株式会社 営業部プロダクトグループ所属  前職がシステムエンジニア、前々職が組込プログラマ。 インフラもそうだけど、技術はアーリーアダプター。 気が付くと新しい技術で何かできないか?ばっかり考えてます。 オフはFMラジオとバイクをこよなく愛する寂しがり屋。

IoTの窓口

docker-tips_bnr

writer