このページの翻訳:
ソースの表示
管理最近の変更サイトマップ

NVMe SSDのRelative Performanceについて

smartmontoolsでNVMe SSDの出力結果を見てた際、Supported LBA Sizesの「Rel_Perf」という項目に目が止まった。

調べてみたところ、NVMe規格の定める「Relative Performance」(RP)を表す値のようだ。

NVMe SSD製品には複数のLBAサイズ(セクタサイズ)に対応し、切り替えて使えるものがある。構成するハードウェアの状況に合わせ、SSDが512バイトセクタや4kセクタのように振る舞うことができるというわけ。主にエンタープライズ用途で使われる機能と思われる。

こうした複数のLBAサイズが選択可能な状況で、RP値はそのデバイスにおけるLBA設定間の相対性能を表す指標とされている。2ビット値につき、取りうる値は0~3で、意味は下表のとおりである。

RP値 意味
0 最高性能 (Best Performance)
1 より良い性能 (Better Performance)
2 良い性能 (Good Performance)
3 低下した性能 (Degraded Performance)

LBAサイズ設定時は、基本的にRPが0に近いものを選定しとけばよさそう。

Micron 9200 MAXの場合、図にあるように512バイトLBAより4k LBAの方が性能が良いことを示唆している。

ところで、なんでこのSSDはLBAサイズが4つもあるの…?それ自体はエンプラ向けでは珍しくないことだが、0~1と2~3の違いは無いように見えるんですけど……謎。

ZFSのヤバげな機能Special Allocation ClassがFreeBSD 12.2で対応されてた

OpenZFS 2.0リリースの陰でひっそりと、FreeBSD 12.2-RELEASEのZFS実装にSpecial Allocation Class(以下、SACと略すことがある)が追加されていた。

時系列的にはOpenZFS 2.0が2020年12月1日、FreeBSD 12.2Rが10月27日リリースなので、まったく陰ってはないんですけどね、インパクトありそうな機能の割にはリリースノートに記載がなく、zpool statusしたら「プールのアップグレードができるぜ!」と出たので調べてみたら追加されていたという。関連するコミットはこの辺→Rev.354382 Rev.354385 Rev.354941

Special Allocation Class自体はZoL 0.8.0で2019年5月24日にリリースされ、その後、illumosへのバックポートを経て、めでたくFreeBSDに取り込まれた模様。ZFS実装が新生OpenZFSベースに切り替わろうとしている中で、Legacy ZFSをきっちりメンテする姿勢には頭が下がります。

で、肝心のSpecial Allocation Classは何かというと、I/O性能に直結するデータを専用のvdevに格納して性能改善を図るもののようだ。多少正確さを欠く表現だが、階層化ストレージのZFS版といえる。

ZFSでは扱うデータの種類に応じてvdevをAllocation Classという概念で分類しており、OpenZFS 2.0時点では以下の5種類となっている。ちなみにAllocation Classは、元はdRAIDで導入されたもので、その後、開発コミュニティによって汎用化され現在の形となったそうだ。

クラス SAC 用途 専用vdevを割り当てた時の効果
Normal × 通常のデータを扱うvdev。ミラーとかRAIDZとか。
Log × ZILのレコード。いわゆるSLOG。 同期書き込みの高速化
Dedup 重複排除テーブル(DDT)のデータ 重複排除パフォーマンスの向上とDDTのメモリ使用量の削減
Metadata プールとファイルシステムのメタデータ メタデータ操作(ファイル一覧の取得など)パフォーマンスの向上
Small Blocks レコードサイズ以下のブロック 小さなサイズの膨大なI/O性能の改善。詳細は後述

表で〇を付けたAllocation ClassがSpecial Allocation Classとされている。それぞれのSACの役割は名前のごとくで、専用vdev (Special vdev)を割り当てるとそれなりに効果がありそうだ。とりわけSmall Blocksは劇的な性能改善の可能性(PDF)を秘めている。

ZFSのファイルI/Oは原則的に128KiB単位1)で行われ、それに満たないデータは、より小さなレコードが使われる。この小さなレコードがI/O性能にそれなりに影響するようで、Small Blocksは指定サイズ以下のブロックの読み書きをSpecial vdevにオフロードするようなイメージとなる。つまり、Special vdevとしてSSDを割り当てると、その特性を活かして膨大な小規模I/Oを捌けるようになる、というわけだ。

ここで注意が必要なのは、Small Blocksの処理はファイルサイズベースではなく、あくまでブロックサイズベースで行われるということ。なので、小さなファイルの全体がSpecial vdevに格納される訳ではない2)。そもそも、ZFSの書き込みは一旦メモリにキャッシュされ、トランザクショングループ(txg)にまとめられた上でレコードに書き出されるため、必ずしも小さいファイル=小さなレコードとは限らない。逆に、大きなファイルでもレコードサイズ以下の端数は必ず存在するわけで、これらのtxgでレコードサイズ未満となった分がSpecial vdev行きとなるようだ。この辺が一般的な階層化ストレージと大きく異なる部分である。

Small Blocksの対象となるブロックサイズは、レコードサイズ以下の2の冪を任意に指定できる。128KiB以上のレコードサイズが使えるようになるlarge_blocksフィーチャーと合わせて使うと、よりパフォーマンスチューニングの幅が広がるだろう。なお、FreeBSDはレコードサイズが128KiBを超えるデータセットからの起動には対応してないので要注意。

Special Allocation Classで性能向上が見込める一方で、その仕組み上、Special vdevが死ぬと一発でプール全体のデータが飛ぶ恐れがある、というかメタデータという極めて重要なデータが飛ぶんだから、ほぼ確実に死ぬと思われる。なので今まで以上に冗長性には留意する必要がある。信頼のおけるSSDで最低でもミラーリング、可能なら電源喪失保護付きSSDで3重ミラーにしたいところ。

Special vdevの容量が一杯になった場合は、従来通り普通のvdevの方が使われるそうなので、その辺は特に気にしなくてもよい模様。

もし試す場合は、プール(普通のvdev)とSpecial vdevのashift量を一致させること。もう修正済みかもしれないが、異なるashiftでプールに追加するとSpecial vdevの取り外せなくなるバグがあるっぽい。ashift量はvdevごとに独立してて、プール作成時は気にするもののvdev追加時はついつい忘れちゃうんだよね…。

参考サイト

1)
データセット毎にrecordsizeプロパティで変更可能
2)
Small Blocksの閾値をレコードサイズと同値にして全データをSpecial vdevに送ることは可能

Micron 9200 MAX 1.6TBのベンチマーク

MicronのU.2接続なSSD、9200 MAX 1.6TB (MTFDHAL1T6TCU)を買ったので恒例のベンチマーク。

公称スペックは以下のとおり。

  • シーケンシャル
    • 読み込み 3500 MB/s
    • 書き込み 1900 MB/s
  • ランダム
    • 読み込み 680000 IOPS
    • 書き込み 255000 IOPS
  • TBW: 17.5PB

もちろん中古購入でS.M.A.R.T.はこんな感じ。

使用時間10047時間≒418日で、電源投入回数45回ってことは間違いなくどこかのサーバに積まれてたものだろうけど、その割に投入回数が多いような気がしなくもない。単純計算で10日に1回でしょ?読み書き量が少なめなのも謎。

CrystalDiskMark 8.0.0 x64

設定:デフォルト

1GB
MB/s
IOPS
レイテンシ
------------------------------------------------------------------------------
CrystalDiskMark 8.0.0 x64 (C) 2007-2020 hiyohiyo
                                  Crystal Dew World: https://crystalmark.info/
------------------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes

[Read]
  SEQ    1MiB (Q=  8, T= 1):  2638.535 MB/s [   2516.3 IOPS] <  3175.35 us>
  SEQ    1MiB (Q=  1, T= 1):  1357.518 MB/s [   1294.6 IOPS] <   771.60 us>
  RND    4KiB (Q= 32, T= 1):   339.511 MB/s [  82888.4 IOPS] <   373.57 us>
  RND    4KiB (Q=  1, T= 1):    25.252 MB/s [   6165.0 IOPS] <   161.80 us>

[Write]
  SEQ    1MiB (Q=  8, T= 1):  2011.884 MB/s [   1918.7 IOPS] <  4159.85 us>
  SEQ    1MiB (Q=  1, T= 1):  1875.930 MB/s [   1789.0 IOPS] <   558.13 us>
  RND    4KiB (Q= 32, T= 1):   293.463 MB/s [  71646.2 IOPS] <   432.32 us>
  RND    4KiB (Q=  1, T= 1):   132.838 MB/s [  32431.2 IOPS] <    30.53 us>

Profile: Default
   Test: 1 GiB (x5) [H: 0% (0/1490GiB)]
   Mode: [Admin]
   Time: Measure 5 sec / Interval 5 sec 
   Date: 2020/11/27 20:47:10
     OS: Windows 10 Professional [10.0 Build 19041] (x64)
Comment: Micron 9200 MAX 1.6TB

設定:NVMe

1GB 32GB
MB/s
IOPS
レイテンシ
------------------------------------------------------------------------------
CrystalDiskMark 8.0.0 x64 (C) 2007-2020 hiyohiyo
                                  Crystal Dew World: https://crystalmark.info/
------------------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes

[Read]
  SEQ    1MiB (Q=  8, T= 1):  2672.030 MB/s [   2548.2 IOPS] <  3131.79 us>
  SEQ  128KiB (Q= 32, T= 1):  2520.132 MB/s [  19227.1 IOPS] <  1661.55 us>
  RND    4KiB (Q= 32, T=16):  1474.630 MB/s [ 360017.1 IOPS] <  1416.91 us>
  RND    4KiB (Q=  1, T= 1):    23.020 MB/s [   5620.1 IOPS] <   177.46 us>

[Write]
  SEQ    1MiB (Q=  8, T= 1):  2009.463 MB/s [   1916.4 IOPS] <  4157.97 us>
  SEQ  128KiB (Q= 32, T= 1):  1999.890 MB/s [  15257.9 IOPS] <  2093.33 us>
  RND    4KiB (Q= 32, T=16):  1074.929 MB/s [ 262433.8 IOPS] <  1890.13 us>
  RND    4KiB (Q=  1, T= 1):   125.642 MB/s [  30674.3 IOPS] <    32.28 us>

Profile: Default
   Test: 1 GiB (x5) [H: 0% (0/1490GiB)]
   Mode: [Admin]
   Time: Measure 5 sec / Interval 5 sec 
   Date: 2020/11/27 20:53:28
     OS: Windows 10 Professional [10.0 Build 19041] (x64)
Comment: Micron 9200 MAX 1.6TB (NVMe SSD)
------------------------------------------------------------------------------
CrystalDiskMark 8.0.0 x64 (C) 2007-2020 hiyohiyo
                                  Crystal Dew World: https://crystalmark.info/
------------------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes

[Read]
  SEQ    1MiB (Q=  8, T= 1):  3559.011 MB/s [   3394.1 IOPS] <  2354.13 us>
  SEQ  128KiB (Q= 32, T= 1):  3562.092 MB/s [  27176.6 IOPS] <  1174.93 us>
  RND    4KiB (Q= 32, T=16):  1965.045 MB/s [ 479747.3 IOPS] <  1032.14 us>
  RND    4KiB (Q=  1, T= 1):    35.869 MB/s [   8757.1 IOPS] <   113.71 us>

[Write]
  SEQ    1MiB (Q=  8, T= 1):  1989.156 MB/s [   1897.0 IOPS] <  4205.01 us>
  SEQ  128KiB (Q= 32, T= 1):  2013.703 MB/s [  15363.3 IOPS] <  2078.83 us>
  RND    4KiB (Q= 32, T=16):  1462.729 MB/s [ 357111.6 IOPS] <  1387.32 us>
  RND    4KiB (Q=  1, T= 1):   130.202 MB/s [  31787.6 IOPS] <    31.17 us>

Profile: Default
   Test: 32 GiB (x5) [H: 0% (0/1490GiB)]
   Mode: [Admin]
   Time: Measure 5 sec / Interval 5 sec 
   Date: 2020/11/27 21:05:36
     OS: Windows 10 Professional [10.0 Build 19041] (x64)
Comment: Micron 9200 MAX 1.6TB (NVMe SSD)

AS SSD Benchmark 2.0.6485.19676

1GB 10GB
MB/s
IOPS

気になった点

ベンチしてて気になったのは、S.M.A.R.T.が報告する温度が高めということ。

最初、バラック状態でやってたら70℃近くまで上がったため、急遽ファンで直接風をあてた。本当に70℃まで上がってたら熱くて触れないハズだが、実際は多少熱いくらいの温度感だった。15mm厚のSSDかつゴツい金属製筐体なので放熱性は良さそうなんですがね…。

ドライブ内部の一番ホットな部分の温度を示してるのか、センサー故障で高めの値なのか真相は不明。

それと、PCIeのリンク状態が割とシビアな気がする。2台のマシンで、PCIeスロットにマウントするタイプの変換カード、PCIe→SFF-8643→SFF-8639ケーブルのそれぞれで接続したが、どちらとも最初はPCIe 2.0でのリンクアップとなってしまった。コネクタ抜き差しでPCIe 3.0で繋がったものの、少々気がかりではある。

OpenZFS 2.0リリース!!

本日、ついにOpenZFS 2.0がリリースされた!!

リリースノート:Release OpenZFS 2.0.0 · openzfs/zfs · GitHub

ZFS環境的には、なんといってもLinuxとFreeBSD向けの実装が統合され、1つのソースツリーからビルドされるようになったのが大きい。実態としては、以前から書いてきたとおり、ZFS on LinuxプロジェクトがOpenZFSプロジェクトとなり、FreeBSD向けの修正が行われたという感じで、“統合”って感じではないんだけど、いずれにせよZFSを取り巻く環境は今後ますます発展していくことだろう。

機能面では、永続的L2ARCと圧縮アルゴリズムとしてZStandardが追加されたのが大きいかな。

これを書いている時点で、PortsのOpenZFSの方はまだ更新されてないが、遅かれ早かれ2.0になると思われる。FreeBSDのベースシステムのZFS実装が置き換わる具体的な時期は不明だが、当初の計画では13.0-RELEASEで置き換わることになってたはず。こちらも無事に進んでくれることを祈りたい。

FreeBSD 12.1のvirtioドライバはバグってるっぽい?

FreeBSD 12.1-RELEASEのvirtioドライバは何かしら不具合があるようだ。仮想環境のゲストとして動かした際に、virtio経由のデバイスが認識されなかったり正しく動かなかったりする模様。もしかすると、12.0-RELEASEや11.3でも同様かも。

このところProxmox VEにお熱で、自宅のFreeBSDサーバをP2Vすべく調査や実験を行っている。P2Vと言ってもPCIパススルーやRaw Device Mappingなどを使い、本来の仮想化とは少々毛色が違うのだが、この構成にしとけばいつでもV2P出来るというメリットがある。

そんなわけで、起動ディスクのNVMe SSDをPCIパススルーし、VMを起動して無事FreeBSDの起動シーケンスが流れてktkrと思ってたら、忌まわしき「Mounting from zfs:zroot/ROOT failed with error 5.」で止まってしまった。

ZFSでこのエラーになってしまったら、ここから復旧できる見込みはまずない。

仕方ないのでProxmoxやVMの設定、KVMのパススルーまわりのあれこれの見直し、FreeBSD側の/boot/loader.confのチェックにzpool.cacheの再生成など、知る限りのあらゆることを試しても症状は変わらず。

起動メッセージをよーく確認すると「ptnetmap-memdev0: cannot map I/O space」「device_attach: ptnetmap-memdev0 attach returned 6」がチラホラ出ていた。

それらしい単語でググるとVirtio fails as QEMU-KVM guest with Q35 chipset on Ubuntu 18.04.2 LTSがヒットした。試したVMは確かにQ35で作ってるし、自分と同じくルートプールが見つからなくて起動できない報告もあるし、このバグを踏んだか?

スレを読んでも修正されたんだかされてないんだか分らなかったが、ふと、先行実験でパススルーしたNVMe SSDにインストールした12.2-RELEASEは問題なく起動してたのを思い出した。それならばってことで、いったん通常環境でFreeBSDを起動し、12.2-RELEASEに更新。その後、改めてVMの方で試したら何事もなかったかのように動いた。マジかよ…(ヽ'ω`)

参考サイト

start.txt · 最終更新: 2019-08-19 02:45 by Decomo
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0