（このクラウド時代に）自作サーバで重複排除やストレージ階層化を試してみる話

# いつもの

皆さんこんにちは、はじめましての方ははじめまして。

[CYBIRDエンジニア Advent Calendar 2015](http://qiita.com/advent-calendar/2015/cybird) の7日目担当となりました入社4年目の @asuky です。
個人的には物理環境とか仮想化とかネットワークが担当のつもりですが、最近はそもそも自分がエンジニアに向いているのかすら怪しい気がしています。

昨日の [Mr_Kim]() さんは、大変素晴らしい技術と経験を持っているDBAです。私もこの次世代仮想化基盤の導入のお手伝いをしたのですが、Mr_Kimさんのリソースプランニングと検証、実際の移行作業の徹底ぶりは半端ではなかったです、というかDB周りをMr_Kimさんが全主導して事故無しなので流石というしか…。

私はネットワーク周りだったので分野は違うのですが、Mr_Kimさんの仕事のやり方には学ぶところが大変多いです。

ちなみにオンプレが良いかクラウドが良いか、というのは多分当面は解決しない問題だと思います。
正直その会社が技術にどこまで資源投入するかという話で、突き詰めれば「インフラ部分を自分でやる（インフラ周りのエンジニアの育成・採用する）か、クラウドベンダに任せるか？」という点です。

クラウドベンダ自身やMSPであればある意味「技術＝飯の種」なので自分でやるでしょうし、医療・製造・教育etcのような分野であればITは手段でしかないのでクラウドベンダに任せればいいでしょう。

じゃあ「Webサービス」のITはどうするか？
技術＝飯の種とも言えますし、所詮は手段とも言えると思います。
半々（任せるところは任せて注力するところを明確にする）が一番良いと思いますが、誰がそれを決めるのか、という話になるので難しいと思います。

…前置きが長くなりましたが、本題に入りたく思います。

今回はストレージの重複排除とストレージ階層化をちょっと触ってみた話をします。大変申し訳ないのですがあくまで「ちょっと」で、こういうことが出来たら良いなぁ〜という話を少しだけしようかと。

# ストレージの重複排除

ストレージ、いわゆる「（HDDやらSSDやらひっくるめて）ディスク」には、色々なデータが保存され、使っただけ容量は消費しますし、保存可能な容量には当然上限がありますし、なるべく無駄遣いはしたくないとも思います。

仮の話になって恐縮ですが、例えば1MBのExcel（…ファイルは何でも良いですが）ファイルがあったとして、それをその場で**普通に1000個のコピーを作れば、1MB*1000で1GBを消費する上、1000個分のコピーを作る時間も掛かる**ことになります。

しかしこれ、普通に考えて*（アホな事やってる、という話はさておいて）*もうちょっと気の利いた方法があると思いませんか？

コピーを作っている以上、内容は全く同じなのだから、「1000個全く同じコピーがある」という事実（メタデータ）と、1個分のオリジナル（実データ）をHDDに置いておけば事足りるはずです。
つまり、実際にディスクを消費するのは「1000個全く同じコピーがある」という事実と、1個分のオリジナル分、つまり1MBちょっと程度あれば大丈夫のはずです。

文字ばっかりで恐縮ですが、つまりはそういうことを実現するのがストレージの重複排除です。

## OpenDedupを突っ込んでみた

今回はOSSの重複排除ファイルシステムである[OpenDedup](http://opendedup.org/)を入れてみました。

ちなみにインストールには[Linux Quickstart Guide for SDFS 3.0](http://www.opendedup.org/quickstart)に書いてあったのでCentOS/RedHat (Centos 6.5)の内容をそのまま行っています、ので割愛。

今回は、テスト用のファイルとして、テンプレートとして使っているKVM仮想マシンイメージ（10GB弱）をvirt-cloneによりコピーした時間を計測してみました。
ちなみに仮想マシンのイメージ作りについては、step-by-stepで[1つ前の記事](http://qiita.com/asuky/items/e7e9dd662da117751224)で説明しましたので、そちらをご参考に願います。

### OpenDedupがない場合

スパースファイル（仮想マシン側で使ってない分は容量を食わない）にしないように…。

> [root@kensho images]# virt-clone -o c66tmplt -n test01 -f /images/test01.img --prompt --nonsparse
> Cloning tmplt.img | 9.5 GB 00:43
> 
> Clone 'test01' created successfully.

10GBのクローンに43秒掛かりました。

下記がvirt-cloneする前のdfの結果で、
> [root@kensho images]# df -kh
> Filesystem Size Used Avail Use% Mounted on
> /dev/sda3 95G 17G 73G 19% /
> tmpfs 7.8G 0 7.8G 0% /dev/shm
> /dev/sda1 7.8G 497M 6.9G 7% /var
> sdfs:/etc/sdfs/testpool-volume-cfg.xml:6442
> 31G 757M 30G 3% /deduped

こちらがvirt-cloneした後のdfの結果です、きっちり/dev/sda3のAvailが9GB程度減っています。
> [root@kensho images]# df -kh
> Filesystem Size Used Avail Use% Mounted on
> /dev/sda3 95G 27G 64G 30% /
> tmpfs 7.8G 0 7.8G 0% /dev/shm
> /dev/sda1 7.8G 497M 6.9G 7% /var
> sdfs:/etc/sdfs/testpool-volume-cfg.xml:6442
> 31G 757M 30G 3% /deduped

### OpenDedupがある場合

OpenDedupで重複排除掛けた場所(/deduped)でvirt-cloneを行いました。

> [root@kensho images]# virt-clone -o c66tmplt -n test03 -f /deduped/test03.img --prompt --nonsparse
> Cloning tmplt.img | 9.5 GB 00:25

> Clone 'test03' created successfully.

同条件のクローンが25秒、42%程度短縮されました。

/deduped上でクローンを行いましたが、/dedupedの容量が減った様子はありません。
> [root@kensho images]# df -kh
> Filesystem Size Used Avail Use% Mounted on
> /dev/sda3 95G 27G 64G 30% /
> tmpfs 7.8G 0 7.8G 0% /dev/shm
> /dev/sda1 7.8G 497M 6.9G 7% /var
> sdfs:/etc/sdfs/testpool-volume-cfg.xml:6442
> 31G 757M 30G 3% /deduped

### 感想

チュートリアル通りやっただけに過ぎませんが、（ストレージではなく）例えばサーバ自体のローカルストレージ内にテンプレートイメージがあり、それをコピーして使い回すような環境があれば使えるのではないかなと思いました。

ただ、仮想環境は現在も皆さん、商用環境としては仮想マシンが動くサーバと、ストレージでSANを組んで構築するのが普通かと思いますし、そういうストレージは大体、重複排除の機能がついていたりもします（重複排除の効率はベンダによってマチマチかと思いますが）。

そこを普通のサーバ+OpenDedupで構築するほど挑戦するような会社さんは…流石にいらっしゃらないような気がしますので、やっぱり個人用途に限られるでしょうか。
（ヘマを打つとデータ損失とかに繋がった場合、ちょっと責任取れないですね…）

# ストレージの階層化

ストレージに使うディスクはいくつか種類があります。

細かい話はさておいて、普通個人用途で使うのは「SSD」と「SATA HDD」かと思います。
商用環境であったとしてもSASという接続方式があるぐらいで、基本SSDとHDDという2種類があるというのは変わりません。

そして一般的に**SSDはランダムアクセスが高速で消費電力が低い**ですが、**容量単価が非常に高く読み書きするうちに劣化します**。

一方で**HDDはシーケンシャルアクセスが多少速く、容量単価が安くデータの長期保存に向く**のですが、**ランダムアクセスや書き込みは遅い**です。

そこで賢い人が考えたのが「**よく使うデータはSSDに置いておいて高速にアクセス**（キャッシュ）し、**あまり使わない・使わなくなったデータはHDDに退避させて、使うときだけSSDに読み込む**（バッキング）」というストレージ階層化の発想です。

## bcacheを突っ込んでみた

この手のソフト、bcacheやEnhanceIO、dm-cacheというのがあるらしいですが…とりあえずbcacheを軽く試してみました。

## 環境

ストレージとしてはAdataの128GBのSSD2本をmdによるRAID1をキャッシュとし、HGSTの500GBのSATA HDDを2本、[HDDケース](http://www.kuroutoshikou.com/product/case/35hdd/gw3_5fx2-u3e/)に入れてRAID1にしてバッキングとしました。

あとCentOSで試そうとしたのですが…、bcacheがkernel 3.10以降でしか対応しておらず、Kernel Updateをしてもうまくインストール出来なかったので、急遽Ubuntu Serverの14.04を入れて試してみました。

Ubuntuの場合は[こちら](https://jp.linux.com/news/linuxcom-exclusive/413722-lco20140225)に方法が書いてあったので、そのままやりました。

CentOSの方は…[開発サイト](http://bcache.evilpiepirate.org/)を見ながら頑張るしかなさそうです。
（私は3.10を入れたのですが、3.10 or 3.11 のlatest kernelが良いという話だったので、もしかしたらkernelが古かったのかもしれない…）


## 少しだけ測ってみた

本当はSequential/RandomでR/Wの4パターン試すべきですが…、時間の関係上Sequential ReadとRandom Writeだけ試しました。

### Sequential Read

【SSDだけの場合】
> sequential-read: (groupid=0, jobs=16): err= 0: pid=2255: Thu Dec  3 22:20:26 2015
> read : io=1600.0MB, bw=722717KB/s, iops=45169, runt=  2267msec

【SATAの場合】
> sequential-read: (groupid=0, jobs=16): err= 0: pid=2305: Thu Dec  3 22:24:03 2015
> read : io=1600.0MB, bw=77287KB/s, iops=4830, runt= 21199msec

【bcacheの場合】
> sequential-read: (groupid=0, jobs=16): err= 0: pid=8611: Mon Dec  7 00:18:27 2015
>  read : io=1600.0MB, bw=27919KB/s, iops=1744, runt= 58684msec

### Random Write

【SSDだけの場合】
> sequential-read: (groupid=0, jobs=16): err= 0: pid=1374: Thu Dec  3 23:33:51 2015
>  write: io=1600.0MB, bw=285336KB/s, iops=17833, runt=  5742msec

【SATAの場合】
> sequential-read: (groupid=0, jobs=16): err= 0: pid=1528: Thu Dec  3 23:42:56 2015
>  write: io=1600.0MB, bw=4651.4KB/s, iops=290, runt=352240msec

【bcacheの場合】
> sequential-read: (groupid=0, jobs=16): err= 0: pid=8671: Mon Dec  7 00:28:57 2015
>  write: io=1600.0MB, bw=3061.3KB/s, iops=191, runt=535201msec

## 感想

…全然性能が出ていないですね。
一通りテスト終わった後に気づいたのですが、fioのようなディスクのベンチマークだと、内容がランダムなテストファイルを該当ブロックに書き込んだり、それを読んだりするため、キャッシュの効きようがないのでは無いかと思いました（キャッシュヒット率が0だったので）。

そう考えると、仮想マシンを複数並べてfioを叩いても同じような結果になりそうです。
例えば仮想マシン複数並べてWebサーバなりDBサーバを立てて、応答時間で性能評価する等、アプリケーションレイヤーまで見ないと評価出来ないのでは無いかと考えました。

やり方が浅薄だったので、また余裕のあるときにテストシナリオから考えなおしてやり直してみます。

# 全体を通して

結果としては少々不本意でしたが、これは検証方法が甘かったということでこの技術自体が使えない、というわけではなさそうです。

Opendedupについては、VMクローン時間がきっちり減るのが分かりました。
bcacheもキャッシュヒットがきちんと確保できれば性能は出ると思います（あとwritebackにするとか）。

結局、この2つを使って何がやりたいの？という話ですが、この2つを活用して、外部ストレージを使わない仮想環境が作れるのではないかな、と思っています。
仮想マシンイメージを置くのに使うストレージの扱いは非常に面倒で、キャパシティ予測が難しく、障害時に大事故につながりやすいのでなるべく使いたくないものだと思うのです。

各仮想ホストサーバにOpenDedupやbcacheを使って仮想マシンイメージを持たせるというスタイルはもっと流行っても良いと思うのです（まぁ、そもそも論で社内にインフラ置くの？という話が付きまとうのですが）。

# 終わりに

関係者の皆様申し訳ありません、書くのが遅れた上に内容が薄いです…。

明日は同期のstksさんに[意識が高い記事](http://chroske.hatenablog.com/entry/2015/12/08/110332)を書いて頂けます。
きっと私の不手際を取り返してくれる内容に違いない…。