今更ストレージサーバーをFreeBSDとZFSで組んだ話

家にTimeCapsuleが2台あって、Mac miniも一部ストレージサーバーになっていて、デスクトップマシンにDVDを保存していて、しかも写真はS3にバックアップしてたんだけど、そろそろMac miniが一杯になってきて…という、まあいろいろ限界に近づいていたので我が家のストレージ用に一台新調した。


買ったもの

@Dospara 注文番号:xxxxx
------------------------------------------------------------------------
◎出荷された商品
TOSHIBA DT01ACA200 バルク[2TB]      [ 2個 ]
SanDisk SanDisk Ultra?SDSSDHII-120G-... [ 1個 ]
Intel Core i5 4590S BOX          [ 1個 ]
ASUS H97-PRO               [ 1個 ]
ADATA AX3U1600W4G11-DD (DDR3 PC3-1280... [ 2個 ]

とりあえずこれだけ買って、ふつうに組んだ。ハコは10年近く使っているものがあるので、それを流用。電源だけは先代のものを流用できたけど、Phenom X2とかAGPのグラフィックボードとかいろいろ古かったので、そのあたりはバッサリとさようなら。既存の SATA HDDが 250GB, 500GB, 500GB とあったので、そいつを利用してうまいことZFSなら…ZFSならやってくれるさ…!と思っていた。

SSDは単品でブートパーティションに。SSD内部で冗長化機構をいくつも持っているし、機械部品がないから故障率は少ないはずだ。ハズレを引かなければメモリやマザボと同等の寿命になるはず。仮にSSDが吹っ飛んでもまた買ってきて入れなおせばそれでよいのでOK。ストレージにするといっても常時起動ではなくむしろコールドストレージ(ほとんどオフにしておいて、必要なときだけ火を入れる)として運用するので可用性の要件もそんなに高くない。

memtest86

とりあえずこれ。MacBookでUSBメモリに焼いて動かせるのはこれ(公式のやつだとうまく焼けなかった)。

To burn USB stick in Mac: http://www.memtest86.com
Technical instructions: http://www.memtest86.com/technical.htm

まあそんなに頑張っても仕方がないので、2時間ほどまわして納得。

FreeBSD 10.1

いい時代になった。CD-ROMなんか焼かなくても、USBメモリがあればカンタン。16GBとか、そんなにいらねーっていう。ミラーサイトを選択してMacで焼けるように FreeBSD-10.1-RELEASE-amd64-memstick.img.xz をダウンロード。

$ sudo dd if=FreeBSD-10.1-RELEASE-amd64-memstick.img of=/dev/disk3 bs=10m

diskutil list を活用してちゃんとUSBメモリを特定する。これでUSBメモリから起動する。

FreeBSDのインストールは簡単。zrootも簡単だった。rc.confをちょっといじるだけ。IPアドレスも固定。特殊なドライバも入れない。カーネルは一応GENERICでビルドしなおしたけど、これでCPUの最近の命令とか使えてるのかな。まあどちらでもよい。しかしここからが大変だった。

ZFSに慣れる

同僚がものすごいZFS推し(Solaris推しでもある)なので、ZFSを使うことは決めていた。しかし中途半端なHDDが3枚。2TBが2枚。なんとかローコスト運用して、HDDが壊れる度に大きいサイズのもので置き換えて徐々に拡大していきたい…
とりあえず何も考えずにいきなり zpool create しちゃうと、GPTパーティションがないやつもそのまま上書きでグダっとなってしまう。そいで corrupt とかいわれるので、予め

# gpart show
...
# gpart create -s gpt ada4
# gpart add -t freebsd-zfs -a 4k  ada4

としておく。こうすると /dev/ada4p1 ができるので、基本的にはこいつを使う。こんな感じ

# zpool create tank mirror ada1p1 ada2p1 ada3p1 mirror ada4p1 ada5p1
# zpool status tank
 ... tank の構成と状態がきれいに表示される

記憶が定かでないが、たしかこういう構成にしたと思う。ada1 ~ ada3 までが不揃いのHDDたちだ。これだけで自動的に /tank にマウントまでされてしまう。便利。LinuxでVFSでウダウダ頑張っていたのがウソのようだ。

ストレージプールをバラしたいときは zpool destroy tank で一発だ。ウッカリやってしまわないように気をつけよう。

障害時の対処はこのあたりを参考にするとよいだろう。

これはメモにあったのだけど…パーティション作成の方法かな。gpartがたまに拗ねるときがある気がするんだ。

障害対応、いきなりの実践

しばらくそれでZFSで作ったり壊したりして遊んでいた。で、そろそろデータを全部移すか…ってなって、ひととおりコピーし終えた頃にやりやがった。 ada2 故障。autodetachされていた。ZFSは優秀である。とりあえず電源落としておいて、もうなんか500GBのやつをもう一度買っても切ないので秋葉原でWDのGreenを2TB 追加購入。ドスパラで買うと3年くらいの保証が無条件でついてくるのでお得だ!これが秋葉原での某DB飲み会の日だったので、4月10日だな。忘れないようにしよ。

いざ土曜日(だったっけ?)、古いHDDを何も考えずに挿して zpool add ada1p1 ada2p1 しちゃうと、セクタサイズが512Bのままになっていて…だかなんだかで zpool status の結果に "block size: 512B configured, 4096B native" と出てくる。どういうことだ。resilver は自動で動作している…が、きになる。ということでいろいろ調べる。

古いHDDはセクタサイズが512Bなのだけど、一方で最近のHDDはセクタサイズが4Kになっている。これをmirrorしちゃうと…セクタサイズが512Bのmirrorになっちゃう!スレの内容をまとめると、まあコイツが出てしまうともう戻らないってこった。新しいプールを作って import/export でやり過ごすくらいしか手はない。zpool 全体でどうなってるかは zdb -C | grep ashift でわかる。 9なら512B, 12なら4096B の模様。

僕はまだ新品のHDDもあるし、データはまあMac miniとかに散らばっているものをまた持ってくればよいので、バッサリと zpool destroy した(その前に一旦一枚ザラの単品パーティションにコピーした*1 )。いい機会なので、2TBのHDDを4本使ってふつうにサイズを揃えて運用することにした。

# zpool create data mirror ada1p1 ada2p1 mirror ada3p1 ada4p1

これだけ。RAIDZにしなかったのは特に理由はないが、仕事でErasure Codingに手を付けられていないので、いくらみんなが安定運用しているといってもちょっと怖かったのだろう。いや理由を思い出した。最初に4本スタートしてしまうと、構成をあとで変えられないからだ。

豆知識: GPT table is corrupt と /var/log/messages で言われたとき

# gpart recover <geom> 

http://yomemacs.hatenablog.jp/entry/2014/02/04/205509

TimeMachineバックアップに使う

netatalk3を入れよう

$ sudo pkg install netatalk3

参考

これでふつうにMacOSからも見れるようになるので、TimeMachine用、DVD鑑賞用、写真バックアップ用のパーティションを afp で見えるようにする。Go To Server...とかで afp://192.168.1.42:5128 とか適当にやっておけばOK

ログの監視

よく考えたらコールドストレージだから死活監視もクソもないのだが、起動時にあえてやるとしたら、いい方法がなかった(NewRelicとかそういうカッコイイのは大げさすぎる)ので、はやりのMQTTというやつを使ってみた。

$ tail -F /var/log/messages | mosquitto_pub -h lite.mqtt.shiguredo.jp -p 1883 -t "<name>/kushana/var/log/messages" -u <name> -P <passwd>  -r -l

としておけば、適当にどこからでも見れる。

$  mosquitto_sub -h lite.mqtt.shiguredo.jp -p 1883 -t <name>/# -u <name> -P <passwd>

まあ必要ないのだけどね。

電源を落とす

$ sudo shutdown -p now

電源管理機構があるとこれで動く。Linuxだと -h で電源落としてくれるのだけど、FreeBSDだと古式ゆかしい halt なので、電源ついたままシステムが止まる(コンソールがないので、停止シーケンスがいつ終わったか分からない…)。

TODO

やりたいこと

  • DVDをストリームするサーバーを立ち上げる
  • pipが動かない
  • Erlang/OTP 17.5 が --disable-hipe でコンパイルできない
  • 妻のTimeMachineをホスト

やらないこと

  • Wake on LAN: 手でボタン押したらええやん
  • TimeCapsuleの廃止: 複製はあればあるほどよいのだよ!

最後にもう一枚。よいショットだったのでどっちを使うか迷った。


*1:このときの cp -r が、ファイル名の辞書順ではない何かよくわからない順番でファイルをコピーしていたのだが、どうしてだろう? /usr/src/bin/cp のコードは3分で飽きてしまった