Google Cloud Platform Advent Calendar 2014の12日目の記事です。
1か月ほど前にBeta版がリリースされたGoogle Compute Engine (GCE)のLocal SSDを試してみたので、さっそくレポートしたい。
Local SSDって何?
GCEではこれまで、Persistent Diskというネットワーク ディスクのみが提供されており、ブートもデータもPDだけでまかなわれてきた。PD上のデータはすべて冗長化されているので、一般的な単体ディスクよりも高い可用性を提供する。
一方で「可用性は普通でよいのでともかく高い帯域とIOPS値を」というニーズに応えるべく新たに提供されたのがLocal SSDだ。特長をまとめると、
- 375GB SSDを1 VMあたり最大4台まで装着可能
- 4台使用時は680K IOPS (4K random read)と360K IOPS (4K random write)の性能を提供。PDのおおよそ15倍のリード性能
- PCIe接続のSSD用インタフェースNVMeに対応
- $0.218/GB/month(2014年12月現在)で、コスパが恐ろしくよい
- どんなタイプのGCEインスタンスでも使える
- GCEのライブマイグレーションにも対応予定。つまり計画メンテナンスでデータが消えたりしない
- データは暗号化される
一方で、Local SSDの制約は以下のとおり。
- 一部のゾーン(us-central1-bとeurope-west1-a)では利用不可
- PDのような冗長性やスナップショット機能、rootディスク機能はなく、また単独では作成できないのでGCEインスタンス作成時にLocal SSD作成をオプション指定する必要がある
- NVMe版を使うには専用のDebian 7イメージ(例えば
nvme-backports-debian-7-wheezy-v20141108
など)を用いる。それ以外のOSでは現在のところSCSI版のみのサポート
使ってみよう
ドキュメントに書いてある手順ですんなり使えた。GCPプロジェクトの作成やGoogle Cloud SDKのインストール等が済んでいる状態で、以下のコマンドでGCEインスタンスを作成する。
$ gcloud compute instances create YOUR_INSTANCE_NAME \
--machine-type n1-standard-16 \
--zone us-central1-f \
--local-ssd interface=nvme \
--local-ssd interface=nvme \
--local-ssd interface=nvme \
--local-ssd interface=nvme \
--image nvme-backports-debian-7-wheezy-v20141108 \
--image-project gce-nvme
このように、--local-ssd interface=nvme
というオプションを台数分だけ指定する。上記例は、
- us-central1-fゾーンにタイプn1-standard-16(16コア、60GBメモリ)のインスタンスを作成
- NVMe版のLocal SSDを4台装着
- NVMe版に対応するDebian 7イメージを指定
という意味となる。ここでポイントとなるのは「Local SSDの性能をフルに引き出すには1台あたり4もしくは8コアを割り当てる」という点だ。このSSDは速いので、CPUのコア数が少ないとCPU側がネックとなってしまう。上記のように4台用いる場合は、16コアのGCEインスタンスを割り当てないと、簡単なベンチマークを取るのでさえCPU使用率が高くなりフルな性能は引き出せない。実際にGCE + Local SSD上でApache SparkとTezの性能評価を行ったozaさんによると、SSDの2台構成でも16コアのCPUがサチってしまったそうだ。もはや"ディスク"のスピードではないね。。
もうひとつ、ドキュメントのRecommended local SSD settingsに記載のスクリプトset-interrupts.sh
を実行しておく。このスクリプトによって、SSDが発生するIRQ(割り込みリクエスト)を各CPUコアに均等に分散させることができる。
fioで性能測定、752K IOPS・3GB/s
ドキュメントのReplicating SSD Performanceの手順を実行すると、fio
コマンドを用いたSSD単体の性能測定が可能だ。
しかし単体ではつまらないので、mdadm
を使って4台のSSDをストライピングしたRAID0を組む。
$ sudo /sbin/mdadm --create /dev/md0 --chunk=256 --level=0 --raid-devices=/dev/disk/by-id/google-local-ssd-0 /dev/disk/by-id/google-local-ssd-1 /dev/disk/by-id/google-local-ssd-2 /dev/disk/by-id/google-local-ssd-3
これで/dev/md0
にソフトウェアRAID0が作成される。さっそくfio
で性能を測ってみよう。
$ sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
--filename=/dev/md0 --ioengine=libaio --randrepeat=0 \
--iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
--numjobs=16 --rw=randread --blocksize=4k --group_reporting
結果は以下のとおり。
read : io=88170MB, bw=2938.5MB/s, iops=752231 , runt= 30006msec
write: io=54744MB, bw=1824.2MB/s, iops=466947 , runt= 30013msec
ブロックサイズ4K時のrandom readは752K IOPS、random writeは467K IOPSとなった。readの帯域は3GB/s。なんかカタログスペックより速い...!
MySQLでsysbench、4,171 tps
ついでに、MySQLのパフォーマンスも測ってみよう。まずは/dev/md0
を/mnt/md0
にマウントしてフォーマットする。
$ sudo /usr/share/google/safe_format_and_mount -m "mkfs.ext4 -F" /dev/md0 /mnt/md0
つづいて、MySQL 5.6をインストールして、/mnt/md0
上にdatadirを作成。さらにLocal SSDのサイズやIOPS性能、メモリサイズに合わせてMySQLのパラメータをチューニング...しかし俺はこのあたりの経験が全然ないので、とりあえずこんな感じにしてみた:
innodb_buffer_pool_size=50G
innodb_log_file_size=2G
innodb_flush_neighbors=0
innodb_io_capacity=10000
innodb_io_capacity_max=10000
innodb_lru_scan_depth=1024
このブログを参考に、同じ条件でsysbenchを実行してみたところ、以下の結果が得られた。
- read only: 4,171 tps
- read + write: 1,893 tps
今回の構成でのGCE+Local SSDのトータルコストは$1.26/hなので、同じ4K tps程度の性能を得るために他のクラウドサービスを使う場合に比べて、およそ1/3程度のコストとなった。コスパいいね!
まとめ
Local SSDの使い勝手をまとめると:
- 冗長性がなかったり等の制約や、コア数やIRQ設定の最適化は考慮が必要(といっても設定は簡単)。
- 4台でRAID0を組むと752K IOPS・3GB/s出る。速い。
- 素人ベンチの結果、MySQL運用時のtpsあたりのコストは一般的なクラウドサービスに比べて1/3くらいっぽい。
というわけで、Local SSDお試しあれ。
Disclaimer この記事は個人的なものです。ここで述べられていることは私の個人的な意見に基づくものであり、私の雇用者には関係はありません。