ブログのしゅーくりーむ

技術的なメモとかライフログとか。

F2FS(Flash-Friendly File System) を試してみる。

このエントリは、 カーネル/VM Advent Calendar 2013 の 19日目の記事として書いています。

こんにちは、 @syu_cream です。 本記事では SSD に特化したファイルシステムであるところのF2FS(Flash-Friendly File System) の軽い説明を入れつつ、試しに使ってみて軽くベンチマークを取ってみた結果を掲載します。

大分ざっくりと書いてるので、誤った点など多々あるかと思います。適当にご指摘頂けると幸いです。

F2FS とは

F2FS(Flash-Friendly File System) は Linux カーネル 3.8 でマージされた、Samsung が中心となって開発した、主にSSDに特化したファイルシステムです。 生のフラッシュメモリ 特化のファイルシステムは、既存のものが幾つか存在するのですが、F2FS はそれらとはまた違った構造のストレージを想定して設計されています。

で、ざっくりと結論を出してしまうと、F2FS は SSDにとって苦手なランダムライト性能を、ログ構造ファイルシステム的なデータの書き出し方をすることで向上する ファイルシステムと言えます。 実際にベンチマークしてみたところ、確かに F2FS の導入によりランダムライト性能が向上する傾向が見られました。

SSD に有効なファイルシステムとは

先述の通り、 F2FS は NANDフラッシュベースのストレージ 、例えばSSDに特化したファイルシステムだと主張されています。 生のフラッシュメモリ特化 のファイルシステムはこれまで幾つか、例えば jffs2 や logfs などが存在するのですが、これらはNANDフラッシュメモリを直接アクセスするような環境で使用されることを想定されています。

さて、NANDフラッシュベースのストレージであるSSDはしかし、ソフトウェアのレイヤから見た時に生のフラッシュメモリではなくハードディスクで使われるようなSATAなどをしゃべるディスクのように振る舞います。 しかしながら、NANDフラッシュメモリはモノからして磁気ディスクとは違うものです。 そのため、配線や材料の特性上、ハードディスクには無い以下のような特徴を持ちます。

  • 読み書きと削除の 粒度が異なる

    • ページ : 読み書きの単位。一般的なSSD なら、4kB~ であることが多い。
    • ブロック : 削除の単位。一般的なSSD なら、1MB~ くらい?
  • メモリセルへの 上書き処理が直接出来ない

    • そのため、まず削除を行う必要がある。巻き込まれるデータは退避させる
    • この処理のコストが大きいため、上書きするような小サイズのランダムライトの性能は出にくい
  • メモリセルに 書込み回数の上限(寿命) が存在する

このように、NANDフラッシュメモリは根本的にハードディスクと違うストレージである(そもそも内部的にはセクタ区切りにされていない!)ため、SSDはファームウェアで実装されている FTL(Flash Translation Layer) によって、これらの特性の隠蔽や改善を行っています。 このFTLは名前通りの変換処理以外にも、以下に挙げるような様々な役割を持っています。

  • セクタ単位のアドレスから、NANDフラッシュメモリに対応する物理アドレスへの変換
  • メモリセル延命のための ウェアレベリング
  • 削除処理の発生を抑制するための使用済みページの ガベージコレクション
  • オーバープロビジョニング(OSには隠された予備領域) を使った性能向上

この辺は Software Design 2013年11月号のFusion-io解説記事 とか、僕が昔書いた資料を読むと良いと思われます(宣伝)

さて、F2FS の話に戻します。 F2FSが謳っている NANDフラッシュベースのストレージ特化 というのは、「FTLがなんか色々勝手に処理しているのを想定した上で的確に振る舞う」ファイルシステムとなります。

F2FS の仕組み

F2FS は以下のような特徴、機能を持つファイルシステムです。 基本的に、ログ構造的な書込み方式を採用しつつ、副次的な問題を抑制することにより書き込み性能を向上するところが大きなメリットであると思われます。

  • LFS(Log-structured File System) 的なデータ書込み方式による、書込み性能の向上
  • LFSのネックを抑制する設計

  • フラッシュメモリの処理単位に合わせたログ書き出し

LFS(Log-structured File System) について


Log-structured File System はパーティション全体を連続した記憶領域として扱います。 LFSへの書込みはその連続した領域に"ログ"として書き残されます。

LFS はディスクへの書込みをシーケンシャルライトで行うため、SSDに導入することでランダムライトの発生を抑制し、性能向上をねらうことができます。 しかしながら、ある程度使い込まれた際に不要になったログを回収(ガベージコレクション)して、新たにログを書き出せる連続した空き領域を作る必要があり、この処理のコストが高い問題があります。

LFSのモダンな実装として、NILFS2 などが挙げられます。

F2FS の工夫


F2FSでは、上記のLFSのようなログ構造的なデータの書き出しを行い、SSDに対して発行されるランダムライトの頻度を低下させる(シーケンシャルライトとして書き出させる)ことにより性能を向上させつつ、LFSのデメリットを解消する工夫がなされています。 ちょっと調べたところ、以下のような特徴があるようです。詳しくはF2FSの紹介スライドなどを参照してみてください。

1. バックグラウンドガベージコレクション

後述のブロック割当のポリシーにもよるのですが、ログのガベージコレクションを基本的にバックグラウンドで行います。

2. ブロック割当のポリシー

ログのガベージコレクション処理は非常にコストのかかる重い処理ですが、これを行わなければ連続した空き領域を確保できずランダムライトが発生してしまいます。 F2FSでは、これを考慮し、ガベージコレクションを行う/行わないポリシーを提供し、デフォルトではこれを状況に応じて使い分けるような挙動をします。 具体的には、通常は以下に挙げる Copy-and-compaction を採用し、空き領域が十分に無い場合には Threaded logging に動的に切り替わります。

3. Hot/Cold データの分離

F2FSでは、データの書き込み頻度の偏りにより、書き出すログをそれぞれ別の場所に分離し、性能向上のためそれぞれフラッシュメモリの処理単位にまとまるように書き出します。 書込み頻度の高いデータの局所性を高めることにより、ガベージコレクションのオーバーヘッドを低減している模様?

F2FS の性能

ここまでの流れから、確かに F2FS でランダムライトの性能を向上できる気がしてきます。 しかしながら、他のファイルシステムと比較して性能がどれくらい伸びるのか、ランダムライト以外の性能はどうなのかという点も気になってきます。

F2FSの性能に関しては、既に幾つかのファイルシステムとの性能比較データがあります。 が、SSDはベンダーや型番により中身が大きくことなるのに合わせ、最近のカーネルだと性能がどうなのかという辺りが気になったので、fio でベンチマークを行い性能比較を行ってみました。

実験環境

ベンチマークを行った環境は以下の通りです。

各項目 詳細
CPU Intel Core i5 760 @ 2.80GHz
Mem 8GB
SSD Intel 320 80GB (ファームウェア最新)
OS Ubuntu 13.10
Kernel 3.12.5 (バニラカーネル)

実験方法

ここでは、fio を用いてベンチマークを行ってみます。 *.fio ファイルは以下の通り記述しました。 各項目については、man を読むなどして確かめてみてください。

ここでは以下の4つのアクセスパターンに絞ってベンチマークを行ってみました。 アクセスパターンは、上の *.fio ファイルの値を適宜修正することで変更しました。

  • シーケンシャルリード
  • シーケンシャルライト
  • 4k ランダムリード
  • 4k ランダムライト

また、ファイルシステムの差異による性能の違いを見たいため、以下のようなファイルシステムを対象にそれぞれベンチマークを回しました。

  • F2FS
  • ext4
  • XFS
  • btrfs
  • btrfs(ssd_spread オプション有効)
  • NILFS2

btrfs については、SSD の最適化をより強化するためのマウントオプション ssd_spread があるようなので、これが有効/無効である場合でそれぞれ測定を行いました。

実験結果

fio による性能測定結果は、以下のグラフの通りになりました。 グラフの縦軸の単位ですが、シーケンシャルリード/ライトは Mbps 単位で、ランダムリード/ライトは IOPS 単位で出しています。

この実験結果から、だいたい次のことが言えるかなと思います。

  • F2FS、本当に性能が出た。特にランダムライトが顕著
  • XFS、btrfs もかなり検討している。

    • ただし、btrfs の ssd_spread オプションによる性能向上は今回は見られなかった
  • NILFS2 の性能があまり出ない・・・何かミスっているだろうか

シーケンシャルリードの性能


ファイルシステム毎の差はほとんど見られない値になりました。

f:id:syu_cream:20131219214953p:plain

シーケンシャルライトの性能


ext4、次いで NILFS2 が性能が落ち、他はほぼ同じくらいの性能となりました。

f:id:syu_cream:20131219215002p:plain

ランダムリードの性能


ext4、btrfs、NILFS2の性能があまり伸びす。 F2FS とXFSの性能が目立ちます。

f:id:syu_cream:20131219215009p:plain

ランダムライトの性能


F2FSが抜きん出て性能が良いです。 次いで btrfs、XFSの性能が目立ちます。

f:id:syu_cream:20131219215017p:plain

さいごに

性能だけ見ると、F2FSは悪くないように思えます。 おそらく、安価でファームウェアがあまり賢く無いSSDに使うには良いかと。導入もそれほど難しくなくお手軽なので。 ただし、実際の運用が楽なのかどうかという点も気になりますね。

最近、SSD自体やSSDをハードディスクのキャッシュとして用いる性能向上手法がやたら出てきて群雄割拠の状態かと思います。 更に、Fusion-io みたいな余計なレイヤ挟まないことにより性能を出すみたいな道も一般化してきていて。。。 F2FSがこの先生きのこるにはどうするか、どうなっていくのか気になってくるところですね。

ATSのドキュメント翻訳活動とその周辺

このエントリーは、 Doc-ja Advent Calendar 2013 の 17日目の記事として書いています。 前日の担当者は、@okano_t さんです。

どうもこんにちは、 @syu_cream です。

主に、最近やっている Apache Traffic Server のドキュメント翻訳についてつらつらと書いてゆきます。 翻訳作業に着手して3ヶ月程度しか経過しておらず、まだまだ初心者の域を脱せていないと思うのですが、何か参考になることがあれば幸いです。

Apache Traffic Server is 何

Apache Traffic Server (以下、ATS)は、オープンソースの高性能 HTTP キャッシュプロキシサーバです。 元々は Yahoo!(米社) が自社で使用していたキャッシュサーバがOSS化されたもので、現在は Apache の Top level projects の一つとして開発が進められています。 使用している企業として、Yahoo! や Taobao 、LinkedIn、国内では Yahoo! JAPAN や pixiv が挙げられます。
また、類似する機能を持つソフトウェアに、 nginx, Squid, Vernish などが存在します。 (これらキャッシュサーバの比較については、IIJの記事が纏まっていて良さげです。)

ATSは日本国内ではユーザは少なめなのか、日本語の資料が不足しています。 そこで本家のドキュメントを翻訳し、最低限利用可能な情報を手に入れ易くしたい、という辺りが本活動のモチベーションです。

ATSの翻訳活動について

規模

現在、アクティブな翻訳参加者は 4 人と、小規模な活動となっております。

翻訳のフロー

現在 ATS ドキュメントの日本語化の作業は、Sphinx のドキュメント国際化のフローに則り、GetText の PO(Portable Object) ファイルを編集することで行っております。 PO ファイルの管理やレビューは、 GitHub ベースで行われています。

現在の基本的な翻訳作業のフローは下図の通りになります。 まず前提として、日本語翻訳専用の Organization アカウント(trafficserver-doc-ja)が存在し、このアカウントが本家ATSのリポジトリを fork したリポジトリを持ち、その中に翻訳済みドキュメントを集約するブランチ(doc-ja) を持ちます。 各翻訳者は、このリポジトリを個々で更に fork します。

各翻訳者はまずドキュメント翻訳作業ブランチを切り、手元で PO ファイルを編集することで作業を進めます。 その後、 trafficserver-doc-ja の doc-ja ブランチに Pull-Request を送ります。 これを他の翻訳者がレビューし、不適当な訳文は指摘して修正し、適当になったタイミングでマージを行います。 ある程度ドキュメントの翻訳が進んだら、trafficserver-doc-ja のオーナーとなる翻訳者が本家ATSリポジトリに Pull-Request を送ります。(本家リポジトリへの貢献は現在は計画段階であり、実行するまでには至っておりません)

f:id:syu_cream:20131217002308p:plain

翻訳のツール

エディタ


各翻訳者が思い思いのエディタを使います。 ちなみに僕は Vim を使って翻訳作業をしています。

コミュニケーション


基本的なコミュニケーションは IRC 上で行っております。 また、翻訳作業に関する issue などは、GitHub でやり取りします。

レビュー


レビューは GitHub 上で Pull-Request に対してコメントを付けることで行っています。 指定の行にサクッとコメントを付けて良いです。 しかし一方で、長文になると読みにくい、指摘された箇所の原文・訳文対応がパッと見た時に分かりにくいという難点もあります。

翻訳の進捗どうですか?

進捗ダメです! ・・・というほどでは無いとは思います。着々とは進んでいるはず。

しかし未だ、必要最低限の日本語のドキュメントが揃っているとは言いがたい状態です。。。

翻訳作業を通して思い付いた開発ネタ

翻訳作業をしていくうちに、翻訳作業自体の効率化についても興味が湧いてきます。

直近では、Vim 上でPOファイルのシンタックスチェックができるよう、シンタックスチェックプラグインの Syntastic に Pull-Request を投げたりしました。

最近は、poedit 風の編集画面を Vim 上でも使えるようになりたいなーなどと考えております。 えっ Vim を捨てて poedit を素直に使えば良い?そういう手段もあるのか!思い付かなかったぜ!

翻訳活動に関する悩み

  • 英語力が無さ過ぎ て翻訳が難しい・・・
  • ギッハブの Pull-Request ベースのレビューが読みにくくてつらい・・・
  • 編集環境がまだ最適化の余地がある気がする・・・
  • モチベーションの維持が大変・・・

この辺り、アドバイス等お待ちしております!

さいごに

ATSのドキュメント翻訳に興味のある方がいらっしゃいましたら、ぜひ活動に参加してみてください。 翻訳したドキュメントのPR投げるなり、既に翻訳されているドキュメントの間違いを指摘して頂けるだけでも大助かりです! また、ATS自体に興味を持って触れて頂けたりしても、嬉しく思います。:)

Doc-ja Advent Calendar 2013 18日目の記事は @naru0ga さん担当です。宜しくお願いしますー。

ChefのcookbookでLXCのコンテナのパッケージや設定を管理する

みんな大好きコンテナ仮想化。LXC非常に便利です。

しかし込み入った環境を作る際、コンテナを作り直したりリストアしたい場合、パッケージ導入を繰り返すのはなかなかしんどいと思われます。

そこで、Chefのcookbookでコンテナに入れるパッケージや設定を管理しましょう。

環境

以下、さくらVPSの2GプランでUbuntu 12.04をインストールした環境で試しています。

また、基本的にVPSのインスタンス上で作業をすることを想定しています。

コンテナへのcookbookの流し込みは、knife-soloで行います。

手順

1. LXCとChef 、knife-solo のインストール

apt でLXCを、gem でknife-solo をそれぞれインストールしておいてください。

2. LXC コンテナ用の、ローカルDNS設定を用意

コンテナを作成するたびに、コンテナのIPを調べるのは面倒なので、コンテナ名でアクセスができるようdsnmasqの設定を変更しておきます。

参考: http://orangain.hatenablog.com/entry/multi-node-serves-using-lxc-on-sakura-vps

3. knife-solo が利用可能な、ベースとなるコンテナを作成

knife-solo では基本的にsshでcookbookを流し込むので、事前に鍵設定を入れておくと便利です。

ここでは、鍵設定や、knife-soloのセットアップに必要なwgetを入れたコンテナを事前に作り、以降それをcloneして使おうと思います。

(コンテナ外で)
$ sudo lxc-create -n ubuntu-chef-base -t ubuntu
$ sudo lxc-start -n ubuntu-chef-base -d
$ ssh-keygen  -t rsa -b 4096 -f ~/.ssh/chef_key
$ ssh ubuntu@ubuntu-chef-base.local.example.com

(コンテナ内で)
$ mkdir .ssh
$ cat > .ssh/authorized_keys
chef_key.pub を貼付けてCtrl-D
$ chmod 600 .ssh/authorized_keys
$ sudo apt-get install wget
$ exit

(コンテナ外で)
$ sudo lxc-shutdown -n ubuntu-chef-base

4. ベースコンテナからclone してknife-solo を準備する

cookbookを流し込むコンテナをcloneし起動、chef-soloを実行出来るようprepareします。

$ sudo lxc-clone -o ubuntu-chef-base -n test
$ sudo lxc-start -n test -d
$ knife solo prepare ubuntu@test.local.example.com

5. Chef リポジトリを作成

手元にChefリポジトリを作ります。基本的にこのリポジトリ以下にcookbookを配置することになります。

$ knife solo init <リポジトリ名>

knife.rb (knifeの設定ファイル)に、cookbook_path などの記述が無ければ追記します。

$ vim ~/.chef/knife.rb
以下の記述がなかったら追記する。
role_path '/path/to/chef-repo/roles'
cookbook_path  '/path/to/chef-repo/cookbooks'
data_bag_path '/path/to/chef-repo/data_bags'

6. cookbook を用意

コンテナに流し込むcookbookを用意しましょう。

サードパーティ製 cookbook を持ってくる場合

例えば、opscode の提供するnginxのcookbookを持ってくる場合は以下のようにします

$ knife cookbook site vendor nginx

自分で cookbook を用意する場合

以下のようにして、新規にcookbook を作成します

$ knife cookbook create <cookbook名>

あるいは、既に作成した cookbook を chef-repo/cookbooks/ 以下に配置しましょう。

7. cookbook をコンテナに送り、実行させる

実行するrecipeを、nodes/ 以下のrun_listか、knife solo cook のoオプションで指定します。 以下はnginxのrecipeを実行する場合。

$ knife solo cook -i ~/.ssh/chef_key -o "recipe[nginx]" ubuntu@test.local.example.com

雑感

LXC、Chef周辺は補助的なツールが多くて、どういった構成が良いのかなかなか悩みます。

dockerとか、Berkshelf とか使うともっと楽になるのかしら。

本記事は以下の記事を参考に、手順をまとめました。: http://inokara.hateblo.jp/entry/2013/04/01/005519

ここ最近の勉強会の資料をSlideShare に掲載しました

ただし,あまり真面目に作り込んでない. テーマは以下の通り.

  • 「Nested VMMとはなんぞや」

* 「Nested VMM環境でBitVisor を動かしてみるテスト」

* 「SSDの基礎」  

HLS(Http Live Streaming)形式のストリーミング動画を、Android のVideoView で再生する

HLS(Http Live Streaming)はApple の提唱するストリーミング用プロトコルの一種です。

https://developer.apple.com/resources/http-streaming/

iOS端末向けに開発されている模様ですが、Android でも3.0 以上なら再生できる模様。

http://developer.android.com/guide/appendix/media-formats.html

HLSを再生するアプリ側のコードとしては、VideoView のsetVideoPath でHLSプレイリストのURLを渡してやるだけでOKです。 例えば以下のような感じ。

VideoView videoView = (VideoView)findViewById(R.id.videoview);
videoView.setVideoPath("http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8");
videoView.start();

電話の着信やSMSの受信を、Twitter のDMで通知するAndroid アプリ作りました

タイトルの通り。

電話の着信やSMSの受信時、Twitter にて自分自身のアカウントに向けてDMを送信することで通知を行うAndroid アプリ「Call Notifier」を作成し、Google Play にて公開しました。

 

https://play.google.com/store/apps/details?id=jp.syucream.callnotifier

 

初回起動時、OAuth のアプリ認証画面が出るので、自分のTwitter アカウントで認証して下さい。

この処理が終わった後は、基本的にバックグラウンドで動作し続けてくれます。

二回目以降のアプリ起動時は、設定画面が表示されるようになるので、通知機能のON/OFFや認証をし直したい場合、ここからお願いします。

 

投稿に成功すると,以下の画像のようなダイレクトメッセージが、自分のアカウント向けに届きます。 

ダイレクトメッセージで送信する文字列は今の所固定で、受信を通知する内容のみとなっております。

 

f:id:syu_cream:20120903151327p:plain

 

ところで自分で自分のアカウントに向けてDMを送信すると、勝手に既読扱いになるっぽい?ですね。

未読にして各クライアントで未読通知してもらいたい場合にはどうすればいいのか。うーん。 

 

 

実装の話も軽く。

BroadcastReceiver で着信とSMS受信時のintent を捕まえ、Twitter4j で自分自身に向けてDMを送信しているだけ。

DM送信処理はService として投げてます。

設定画面はPreferenceActivity を継承する形で実装。