Exadataフラッシュキャッシュの謎 [アーキテクチャ]

相変わらずExadataのフラッシュキャッシュの性能問題に悩まされている。その解析を進める中で、そもそもそのアーキテクチャを書籍等で調査したので、その内容を以下に記載する。

◆Exadataフラッシュキャッシュとは

ExadataはRACを構成する複数のDBサーバと、ASM上にディスクグループを構成する複数のストレージサーバから構成される。例えば現在のモデルであるX7-2のハーフラックではDBサーバ4台、ストレージサーバ7台という具合である。このストレージサーバは12本のHDDと4本のフラッシュキャッシュで構成される。HDDは10TBのSAS、フラッシュキャッシュは6.4TBのPCIeカードである。このフラッシュキャッシュをExadata Smart Flash Cache (ESFC)という。ここでは単にフラッシュキャッシュと記す。

このフラッシュキャッシュであるが、Exadataのモデルチェンジ毎に倍になってきている。一方、HDDの方は概ね1.5倍ずつ増加していることと比べると、フラッシュキャッシュの進化の速度の早さを感じざるを得ない。また、容量の点でも、フラッシュキャッシュと言いつつ、X7-2ハーフラックでは物理で全179TBとなり、冗長度を考慮したとしてもかなりの規模のDBならすべてフラッシュキャッシュ上に載せたままにすることが可能な状況になってきている。当然、性能(IOPS)はHDDに比べて2桁程高い(Exadataのデータシート)ため、オンライン処理などのシングルブロックリードのワークロードに高い性能を発揮できる。

X4:F80 (800GB)  vs 4TB HDD
X5:F160 (1.6TB)  vs 4TB HDD
X6:F320 (3.2TB)  vs 8TB HDD
X7:F640 (6.4TB)  vs 10TB HDD

X7-2のフラッシュキャッシュはストレージサーバからどのように認識されているかはcellclie -e list physicaldisk where disktype=flashdiskで確認できる。4枚のフラッシュキャッシュがあり、1枚のフラッシュキャッシュが2.9TBの2つのデバイスで構成されていることがわかる。従って、実際は5.8TB/毎程度なので、物理の90%程度のサイズで認識されている。

◆Exadataフラッシュキャッシュのアーキテクチャ

フラッシュキャッシュのアーキテクチャを理解する上で、ここでは2ノードRAC構成を考える。DBサーバ#1でSELECTによりシングルブロックリードを行う単純なケースを考えてみよう。Exadataでは以下のように必要なブロックを探す。

(1)ローカルのバッファキャッシュ上からブロックを探す
(2)なければ、CacheFusionでクラスタ内のグローバルキャッシュから探す
(3)なければ、ストレージサーバへブロック要求を出す
(4)ストレージサーバがフラッシュキャッシュからブロックを探す。なければディスクから読む
(5)ストレージサーバはDBサーバへブロックを返却する
(6)ブロックがフラッシュキャッシュ上にないときは、フラッシュキャッシュへブロックを配置する

ここで特筆すべきは、(6)は非同期であるということである。ディスクから読み込まれてからフラッシュキャッシュに乗るまでにタイムラグがあることである。通常のブロックデバイスのストレージキャッシュはキャッシュを「経由」するアーキテクチャであるため、Exadata特有のクセとして認識しておいた方が良いだろう。
また、I/Oの特性によりフラッシュキャッシュに乗せる・乗せないを制御している点も興味深い。例えば、RMANバックアップやexpdp、アーカイブログ等のI/Oはフラッシュキャッシュに乗らない。さらに、フラッシュキャッシュに乗せたブロックは、どのテーブルやインデックスのオブジェクトなのかストレージサーバは知っている。フラッシュキャッシュ上のブロックはdba_objectsのdata_object_idで緋付けられている。従って、data_object_idが変更されるようなalter table文などを実行するとフラッシュキャッシュから落ちる。これも特性として理解しておく必要があるだろう。
そして、上記(4)~(6)の動作を制御しているのがcellservというプロセスであることも理解しておく必要がある。ストレージサーバでのオフロード機能(smartscan等)は恐らくすべてこのcellservで実現されていると言っても過言ではないだろう。

◆WriteBackについて

ストレージサーバへの書き込みは通常、ディスクまで書き込みを行ってから制御を戻すWriteThroughモードがデフォルトの挙動である。しかし、フラッシュキャッシュをWriteBackキャッシュとして構成することが可能である。これにより、ストレージサーバへの書き込み要求はフラッシュキャッシュへの書き込みで制御を戻すことが可能となり、ディスクへの書き込みは非同期となる。これによりOracleデータファイルの書き込みI/Oのボトルネックを解消することが可能となる。

WriteBackキャッシュはASMの冗長化が必要なため、WriteThroughモードより論理容量は減る(ASM3冗長ならWriteBackは1/3の容量となる)。また、そもそもDBWRに待機が発生していないような状況では、性能向上への効果は限定的であると考えるべきであろう。通常、DBは読み込み(特にシングルブロックリード)がI/Oのネックとなり易いため、通常はフラッシュキャッシュの領域が大きいメリットを享受できるWriteThroughが良いだろう。SGAに対して十分大きなセグメントの大量更新など、Free buffer waitsなどDBWRの書き込みの待機が発生する状況においては、WriteBackの効果が得られるだろう。

なお、現在どちらのモードになっているかは、cellcli -e list cell attributes flashcachemode detailでflashCacheModeを確認すればよい。また、構成方法についてはMOSのDocID:1500257.1が参考になる。

◆CELL_FLASH_CACHEストレージ句について

セグメントのSTORAGE句CELL_FLASH_CACHEでフラッシュキャッシュに乗せるブロックの優先度を制御することが可能である。具体的に指定可能なのは以下3つである。

・NONE:フラッシュキャッシュを使わない
・DEFAULT:小さいI/O(single block read)のブロックをフラッシュキャッシュに乗せる。デフォルトの挙動
・KEEP:フルスキャンのブロックをフラッシュキャッシュに乗せる。溢れた場合、KEEPされたブロックは最後に消される

ただしストレージサーバソフトウェアのバージョンによって挙動が違うので注意が必要である。少なくともX7-2ではDEFAULTであってもフルスキャンのブロックはフラッシュキャッシュに乗る。また、昔は24時間でKEEPはexpireされるという仕様も見直されており、残り続けるらしい。このあたりの細かな挙動には謎が多く、仕様も公開されていない。OOWでExadataの開発者に話を聞いた限り、最近ではほとんどのケースにおいてDEFAULTのままで問題ないそうだ。

常識的にKEEPを多用することで、フラッシュキャッシュが溢れるような使い方をすることは好ましくない。フラッシュキャッシュはブロックの変更をするために、内部的には空きブロックを新規に確保し既存ブロックは不要マークを付けて、非同期にガベージコレクトする方式となっているらしい。このため、溢れるような状況になると性能劣化の要因となる可能性がある。KEEPを使う場合は、KEEPすべきオブジェクトの選定し、十分に収まる範囲で使うのが良いだろう。

フラッシュキャッシュが一杯になったときの挙動はまったくの謎である。恐らくLRUにより古いブロックをパージし、新しいブロックを書き込むはずであるが、実際はそんなに単純ではない。まずフラッシュキャッシュ内の構造が謎である。Default/Keepバッファ等があり、各領域の比率もなんらかの制約があるだろう。また、アクセスパターンも読み込み(HDDからフラッシュキャッシュ)、書き込み(DBサーバからフラッシュキャッシュ)によって落とし方に違いがあるかもしれない。このあたりの挙動はmetriccurrent fc_XXXの統計を追いかけない限りわからないかもしれない。

なお、CELL_FLASH_CACHEストレージ句の設定方法は簡単である。alter table/index xxx storage (cell_flash_cache keep)すればよい。DBA_SEGMENTSのCELL_FLASH_CACHEカラムで現在の設定の状態が確認できる。

◆フラッシュキャッシュの確認方法

備忘まで、確認方法のコマンドを記載しておく。cellcliはストレージサーバ側で実行すること。

・フラッシュキャッシュに乗っている容量
cellcli -e list flashcache detail | grep effect
cellcli -e list metriccurrent fc_by_allocated, fc_by_used, fc_bykeep_used

・フラッシュキャッシュに乗っているオブジェクトの確認
SQL> select data_object_id from dba_objects where object_name='xxx'; ←テーブル名など
cellcli -e list flashcachecontent detail where objectNumber=999 detail ←999が上記SQLで返却されたdata_object_id
※objectNumberがdba_objectsのdata_object_idと紐付く

以上

◆参考文献

Expert Oracle Exadata

Expert Oracle Exadata

  • 作者: Martin Bach
  • 出版社/メーカー: Apress
  • 発売日: 2015/08/13
  • メディア: ペーパーバック



Oracle Exadata Expert's Handbook (English Edition)

Oracle Exadata Expert's Handbook (English Edition)

  • 出版社/メーカー: Addison-Wesley Professional
  • 発売日: 2015/06/12
  • メディア: Kindle版


nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。