こんにちは。並河(@namikawa)です。
最近、すっかり暑くなってしまって、夏本番って感じですね。夏といえば、海に花火にラーメンと、楽しみが盛り沢山でワクワクしますね!
さて、弊社では多くのデータストアを持っておりますが、クラウドサービス上で大容量なディスクと高い性能を両立させようとすると、(費用的な意味での)コストが一気に跳ね上がることもあり、色々な工夫を試行錯誤しながらやっております。
一定量のホットデータがはっきり見えている前提であれば、高速なストレージデバイスをキャッシュとして使うことは定石であり、キャッシュと一括りにしても様々なレイヤで技術実装されています。
今回はその中でも比較的低レイヤとなるハードディスク等のディスクアレイのようなブロックデバイスに対するキャッシュとして動作する bcache について簡単な性能検証を行なってみました。
bcache とは
概要的な情報を以下に箇条書きします。
- Linux kernel に組み込まれている
- バージョン 3.10 以降で利用可能
- 特定のデバイスを他のデバイスのキャッシュとして利用することが可能
- 上位レイヤはキャッシュの存在を意識する必要がない (トランスペアレント)
- write through / write back のサポート
- 複数のデバイスを扱うことが可能
- デフォルトではシーケンシャルI/Oアクセスのキャッシュをスキップ (変更可)
- ハードディスクの苦手なランダムI/Oに絞ったキャッシュ
- レイテンシをモニタリングし、キャッシュアクセスが輻輳する場合、バイパスさせることもできる (変更可)
尚、bcacheのようなキャッシュデバイスに関する類似的な実装としては、dm-cache、Flashcache、EnhanceIOなどが挙げられます。
インストール・設定
それでは、実際に使ってみましょう。
今回は、GCE上のUbuntu(16.04)のインスタンスを使ってみました。とはいっても、上述の通り、Linux kernelに組み込まれているので、基本的には bcache を扱うためのツールをインストールして、設定を行なっていく感じになります。
バッキングデバイスにハードディスク(/dev/sdb, 500GB)、キャッシュデバイスにSSD(/dev/sdc, 300GB)を利用しています。
ハードディスクとSSDの容量がアンバランスに見えますが、今回は性能的なベンチマークを行うため、あえてIOPSに一定の差がつくような環境にしています。
# apt-get install bcache-tools
まずは bcache を扱うためのツールを apt でインストールします。
# wipefs -a /dev/sdb1 # wipefs -a /dev/sdc1
必要に応じてパーティションを作成した後、FS等メタデータが残っている場合は、上記のように wipefs コマンドでクリアします。
# make-bcache -B /dev/sdb1 -C /dev/sdc1 UUID: 86758735-1c62-43b3-8673-641f148c0926 Set UUID: 499624a7-c90f-40c1-90da-0c2f33fec267 version: 0 nbuckets: 614398 block_size: 1 bucket_size: 1024 nr_in_set: 1 nr_this_dev: 0 first_bucket: 1 UUID: bda52f6d-a658-4afa-b27d-8d004b210989 Set UUID: 499624a7-c90f-40c1-90da-0c2f33fec267 version: 1 block_size: 1 data_offset: 16
次に、上記のように make-bcache コマンドで、 "-B" オプションの後にバッキングデバイス、 "-C"オプションの後にキャッシュデバイスを指定すると、 bcache デバイス (/dev/bcacheN) が作成され、アタッチまで行なってくれます。
ここまで来ると、後は通常のデバイスブロックと同じように扱うことができます。
状況の確認等で、よく使う(気にする)ところとしては、
# cat /sys/block/bcache0/bcache/cache_mode [writethrough] writeback writearound none
上記コマンドでキャッシュモードを確認したり、
# tail /sys/block/bcache0/bcache/stats_total/* ==> /sys/block/bcache0/bcache/stats_total/bypassed <== 21.3M ==> /sys/block/bcache0/bcache/stats_total/cache_bypass_hits <== 1 ==> /sys/block/bcache0/bcache/stats_total/cache_bypass_misses <== 0 ==> /sys/block/bcache0/bcache/stats_total/cache_hit_ratio <== 24 ==> /sys/block/bcache0/bcache/stats_total/cache_hits <== 18 ==> /sys/block/bcache0/bcache/stats_total/cache_miss_collisions <== 4 ==> /sys/block/bcache0/bcache/stats_total/cache_misses <== 56 ==> /sys/block/bcache0/bcache/stats_total/cache_readaheads <== 0
こんな感じで統計情報を確認できます。
ベンチマーク
せっかくなので、上記で作成した bcache デバイスに対して、ツールを使ってIOPS的なベンチマークを取得してみます。
前提条件は以下の通りです。
- GCE で CPU 8core, メモリ 7.2GBのインスタンスを使用
- バッキングデバイスにHDD(500GB)、キャッシュデバイスにSSD(300GB)を使用
- OS は Ubuntu 16.04
- ファイルシステムは XFS
- ベンチマークツールは fio を使用
- size=20G, bs=4k, ioengine=libaio, iodepth=8, direct=1
尚、ベンチマークに利用するデータを適切にキャッシュさせるために、意図的にシーケンシャルI/Oについてもキャッシュにのせるべく、以下の設定を行なっています。
# echo 0 > /sys/block/bcache0/bcache/sequential_cutoff
で、以下がベンチマークの結果となります。
表の1行目はハードディスク (500GB) 単体のベンチマーク結果、2行目は SSD (300GB) の結果、3行目は bcache デバイス (write through) の結果、4行目は bcache デバイス (write back) の結果となります。
この結果から、 bcache デバイスは、少なくともランダムI/Oアクセスにおいては、ピュアSSDの性能とまではいかないものの、キャッシュデバイスとして一定の効果をもたらしていることがわかります。
尚、 bcache については、ドキュメントを眺めている限り、様々な設定項目があるので、もう少しユースケースやデバイス・ファイルシステム等の特性を考慮したチューニングを行うことで、また違った数値結果となるかとは思います。
さらに検証したい項目
今回は時間の都合上、本当に試しに使って軽くベンチマークを取ってみました、的なところまでしか検証できていないのですが、今後は以下の項目について確認を進めたいと思っています。
- GCE環境において、バッキングデバイスに SSD を、キャッシュデバイスに Local SSD を使用したベンチマーク
- 耐障害性のテスト
- キャッシュデバイスが急にダウンした際の振る舞い
- キャッシュデバイスが急に性能低下またはエラーレートが高くなった時の振る舞い
- キャッシュデバイスのオンラインでのアタッチやデタッチが使えるか
本題
・・・と、随分前置きが長くなりましたが、アスタミューゼでは、エンジニア・デザイナーを大募集中です。特に巨大な技術情報群のデータエンジニアリング基盤をバリバリ整備してみたい方や、巨大な技術情報群を扱ったWebサービスの開発をやってみたい方に関して、本当に明日からでも手伝っていただきたいと心から思っております。
少しでもご興味がある方は、下部バナーの採用サイトやサイドバーにある Wantedly のリンクから詳細をご確認いただいて、まずはオフィスに遊びに来ていただいて、カジュアルに情報交換できればと考えております。どうぞよろしくお願い致します。