KubernetesのRaw Block Volumeサポートについて考える。

# TL;DR

- KubernetesでRaw Block（Raw Deviceともいう） VolumeがBeta版になった。
- Raw Block(Device)とは何なのか。メリットは？
- Kubernetesから見たRaw Block対応の意味

# KubernetesのRaw Block VolumeサポートがBetaに
去る3/8、Kubernetesの**Raw Block Volume** サポートがBetaとなったことが発表されました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/Kubernetes?src=hash&amp;ref_src=twsrc%5Etfw">#Kubernetes</a> v1.13 moves raw block volume support to beta, allowing persistent volumes to be exposed inside containers as a block device instead of as a mounted file system. More on the blog ⬇️⬇️<a href="https://t.co/B8RsRWZWS1">https://t.co/B8RsRWZWS1</a></p>&mdash; Kubernetes (@kubernetesio) <a href="https://twitter.com/kubernetesio/status/1104062514889936897?ref_src=twsrc%5Etfw">2019年3月8日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

私（@tzkb）は「[Kubernetesでデータベースを動かそう](https://qiita.com/advent-calendar/2018/postgresonk8s)」なる活動をしていますので、今回の一報に歓喜したのですが、DBでもRawデバイスの利用は減ってきています。そこで歴史的な背景を振り返り、今KubernetesがRaw Block Volumeをサポートする意味を再考したいと思います。

# 歴史から振り返るRaw Block(Device)の意義
今回のKubernes公式の[アナウンス](https://kubernetes.io/blog/2019/03/07/raw-block-volume-support-to-beta/)をまとめると、以下が書かれています。

1. **Raw Block Volumeはファイルシステムのオーバヘッドを回避する選択肢であること**
2. **ユースケースとしてデータベースとSDS(Software Defined Storage)を想定していること**

まず、1.についてオーバーヘッドとは何のことなのかを見ていきましょう。

## ファイルシステムのオーバーヘッドとは何か？
**Why add raw block volumes to kubernetes?** の冒頭には以下のように書かれています。

> There are some specialized applications that require direct access to a block device because, for example, the file system layer introduces unneeded overhead.
> たとえば、ファイルシステム層に不要なオーバーヘッドが発生するため、ブロックデバイスに直接アクセスする必要がある特殊なアプリケーションがいくつかあります。

ファイルシステムの利用で発生するオーバーヘッドといわれて私が思いつくのは、

- ジャーナリングファイルシステムによるもの
- カーネルキャッシュによるもの

の2つです。

#### ジャーナリングファイルシステムのオーバーヘッド
私がデータベースをさわり始めた約20年前には商用UNIXにデータベースを乗せることが一般的で、Oracle（当時はOracle8の頃）利用時には、UNIXが持つジャーナリングファイルシステムを経由せずに、RAWデバイスにデータファイルを置くという構成がベストプラクティスでした。

その理由として以下があげられていたと記憶しています。

- そもそもDBレイヤでログ先行書込みがされており、ファイルシステムでジャーナルを書く必要はない
- ジャーナルログの書き出しでIOパフォーマンスが落ちる

当時のOracleはRAWデバイスを扱うことが出来たので、主に性能上の観点からRAWデバイスを選ぶというのは妥当な選択肢でした。

しかし、RAWデバイスの扱いは非常に煩雑です。そのため、利便性を下げてまで**RDBMSでRAWデバイスを使う理由は今はない**、というのが個人的な見解です。Oracle12c以降、RAWデバイスは非サポートになっていますし、他のOSSデータベースでも、私の知る限りサポートしているものはありません。

※ちなみにジャーナリングファイルシステムって何？という方は[こちら](https://www.atmarkit.co.jp/ait/articles/0307/29/news002.html)なども参考にどうぞ。

#### カーネルキャッシュのオーバーヘッド
もう一つのカーネルキャッシュについては、2010年頃にPostgreSQLのIOを説明するために記述した図を載せておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/b22d6c4b-f4ae-2da2-5333-78c6e769a3ee.png)

この図で言いたかったのは、ファイルシステム経由のIOはカーネルキャッシュ（図中ではページキャッシュ）を使う、ということです。データベースではこれが**冗長**になります。つまり、DBサーバにおいて重要な物理メモリが、データバッファ以外にカーネルキャッシュとしても使われてしまうのです。それらにバッファリングされるデータが同じものになってしまうことも良く見られます。

しかし、このメモリ部分の冗長性も、昨今のLinuxではDirectIOの対応により回避できるようにとなっています。MySQLでは[innodb_flush_method](https://dev.mysql.com/doc/refman/5.6/ja/innodb-parameters.html#sysvar_innodb_flush_method)によりDirectIOを指定することができます。PostgreSQLでは現時点でこれに対応するパラメータはありません。

※ここまでのRAW、DirectIOの関係をまとめた記事は[こちら](https://tech.nikkeibp.co.jp/it/article/Keyword/20070207/261244/)が分かりやすいです。

# KubernetesにおけるRaw Block Volumeの利用シーン
歴史的な話が長くなりました。

ここまで見てくると、データベースでRAWデバイスが必要とされてきた大きな問題は解消されており、OracleやMySQL、PostgreSQLが対応を打ち出していない点からDBレイヤでは今後もサポートする必要がない、というのが一般認識になりつつあるように見えます。

では、KubernetesにおけるRaw Block Volumeの利用シーンを上の2点以外で考えてみましょう。

## Open-Channel SSDの紹介
2019年の[SNIA-jのトレンドセミナー](https://www.snia-j.org/news/information/3037/)でも紹介されたOpen-Channel SSDというものがあります。
※[この辺り](https://openchannelssd.readthedocs.io/en/latest/)を見るとプロジェクト概要が載っています。

これはSSD側のコントローラでやっていた処理をSW化して、ホスト側に持っていこうというプロジェクトです。そうすることで、

- IOの並列度をアプリケーション側で細かく管理できる
- SSDの[ライトアンプリフィケーション](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%88%E3%82%A2%E3%83%B3%E3%83%97%E3%83%AA%E3%83%95%E3%82%A3%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)をアプリケーション側で管理することで、IOの安定化が可能
- SSDのコストが低くなる（コントローラがpoorで良い）

というメリットがあります。

#### RocksDBのOpen-Channel SSD対応
では、このOpen-Channel SSDをデータベースで利用している例を紹介しましょう。残念ながらRDBMSでの事例は見つかりませんでしたが、いわゆるNoSQLと呼ばれるRocksDBというものが見つかりました。

資料は[こちら](https://javigongon.files.wordpress.com/2011/12/rocksdbmeetup.pdf)にありますが、非常に細かくIOをアプリケーション（ここではRocksDB）から制御している様子が見てとれます。

上記のRocksDBで見られるように、データベースのIO最適化をハードウェアに近いレイヤで行うというの考え方は、OracleのExadataやAmazonのAuroraでも見られます。

さらにMySQLではストレージエンジンがPlaggableであり、PostgreSQLでもPlaggable Storageへの対応が議論されています。そのことから、RocksDBのOpen-Channel SSD対応のような形がストレージエンジンの一つの形として今後登場してくる可能性があります。

## KubernetesレイヤでのIO最適化が可能になる（かもしれない）
RocksDBでのOpen-channel SSDのように、最新デバイスのIO性能を最大限に引き出すためにファイルシステムではなくRaw Blockとして扱うケースが今後出てくるでしょう。

そして、それらの実装を**"そのまま"**Kubernetes上で動かすというワークロードで、今回のRaw Block Volumeサポートが活躍してくれるのではないか、というのが現時点での私の見解です。

今、巷ではNVMe-SSDや不揮発性メモリと呼ばれるようなIOデバイスの進化が著しいですが、それらを活かすために、DBMSだけでなく**Cloud Native Storage**でもハードウェア層まで踏み込んだ実装の形が見られるようになる、と私は考えています。

# まとめ
「Kubernetesはクラウド時代のOSになる」と言われたのは2017年だったと思いますが、今回のRaw Block VolumeサポートはこのOSとしての可能性を拡げる機能になるでしょう。

今回は書くことができませんでしたが、CSIの状況も合わせてウォッチしながら、Rawデバイスとしてのボリューム利用について今後も情報を集めていきたいと思います。