2011年7月26日火曜日

SSDがヤバい その3 SSDあれこれ

■ SSDの速度の秘密
別に秘密でも何でもありませんが、SSDの中には NANDフラッシュメモリだけが入っているわけではありません。

□ コントローラーチップ
SSDの性能と寿命を制御する、一番大切な部品と言って良いでしょう。コントローラーの進化が MLCフラッシュメモリの進化を支えています。
ウェアレベリングや読込、書込みの並列化、書き込み回数の上限の管理などを行っています。
Marvell社(Crucial, Intel)や SandForce社(Vertex)などが有名です。
尚、Crucialは Micron Technology社の SSD製造販売の子会社ですが、Micron Technologyと Intelが共同で設立した IM Technology社で製造された NANDフラッシュメモリを使用しています。つまり、Crucialと Intelが使っている技術は、コントローラーチップもNANDフラッシュメモリも同じものとなります。
※ Intelは以前は自前のコントローラーを使っていましたが、最新の510シリーズではMarvell社のコントローラーを使用しています。

□ キャッシュメモリ
16~64MB程度のDRAMを搭載して、読み書き性能を上げるために使っています。後のSSDの特性のところで述べますが、書込みをするために必須のパーツです。IO性能のパフォーマンスアップにも効いてきます。

□ NANDフラッシュメモリ
フラッシュメモリそのものです。最近は 25nmプロセスを使った製品も出ており、高速化、大容量化に寄与しています。


■ フラッシュメモリ SSDの特性を理解する

□ 消費電力
フラッシュメモリは消費電力が桁違いに小さくできています。容量辺りの消費電力を考えると MLCが有利です。
通常の 3.5" HDDが10w前後ですが、SSDの場合アイドル時 1W以下、リード値2W程度です。

□ 書込みがだんだん遅くなるのは何故?
フラッシュメモリの特性として、メモリにデータが書き込まれていると上書きでの書込みは出来ません。従って使い始めのデータが空っぽの時は良いのですが、だんだんデータが書き込まれてくると、データの消去+データの書込みの2つの動作を行う必要があるため、だんだん書込みに時間がかかるようになることになります。ちなみにデータの消去には書き込み処理の100倍くらいの時間がかかります。またデータの読み書きの単位は2~4KB程度ですが、データを消去する場合は例えば 128KB単位で行われます。ですので 1バイトの書き換えでも 128KBの消去と書込みが必要になります。そのために SSDには DRAMのキャッシュメモリが積まれており、上記1バイトの書き換えは次のようなステップで行われます。
128KBのフラッシュメモリ上のデータを DRAMにコピー (読込が 32~64回)
フラッシュメモリ上のデータの消去
DRAM上の1バイトの書き換え
128KBのデータの書き戻し (書込みが 32~64回)

これらの動作を改善するために TRIM機能が使われます。最近は TRIM機能をサポートするSSDが多く出てきています。

□ MLCの寿命は?
SLCの10分の1から 20分の1と書きましたが、実際はどれくらいあるのでしょうか。
Crucialの c300を例にとると書込み上限は 72TBでした。これは毎日 40GBの書込みをして上限に達するまで 5年間かかる大きさなのですが、DBの OLTP部分など更新の激しいデータを格納するとなると、かなり足りないかな というサイズです。

□ MLCのMTBFは?
Crucialの c300で MTBFは 200万時間でした。
HDDよりもかなり良い値なのではないでしょうか。(可動部が無いので当たり前ですが)


--
ここまで SSDの種類や特性などについて見てきましたが、結論としては MLCを使用した安価なSSDでもコントローラー機能の向上により、性能・寿命が著しく伸びています。使い方をきちんと考えて使う分にはエンタープライズ用途でも十分使えるレベルになってきていると言えます。

例えばDWHで使用するデータは、SSDに向いていると言えます。
  • データ書込みは追記書込みが主で、後は読み出しだけ。
  • 過去数年の巨大なデータを使用するが、分析するときは大量のデータに高速にアクセスが必要。
ここまで見てきたように、SSDの容量と価格は急激なスピードで進化しています。今1,000万円を出して必要な容量を確保するより、今は 500万円で直近必要な分のSSD容量をそろえ、来年もう500万円出してSSDだけを追加するとなると、同じ金額でも高速・大容量のストレージを手に入れることが出来ます。

p.s.
SSDは HDDと同じくコントローラーのファームウェアアップデートがあります。不具合修正はもちろん、性能アップしたり省電力になったりするので、時々ホームページをチェックしましょう。

2011年7月23日土曜日

SSDがヤバい その2 フラッシュメモリベースSSD

前回に引き続き、今回はフラッシュメモリベースのSSDについて


■ SLCフラッシュメモリベース 企業向けSSD

NANDフラッシュメモリは DRAMと違い電源が供給されていなくてもデータを保持できる不揮発性メモリであるため、より通常のディスクドライブと同じように扱えるといえます。そのなかでも SLC(Single Level Cell)型は、後で説明する MLC(Multi Level Cell)型と比較して
  • 書込み速度が早い
  • 書き換え可能な上限回数が多い (MLCの10~20倍とか)
  • データ保持期間が長い (寿命が長い)
  • しかし容量が少なく、単位容量あたりの価格が高い
という特徴があります。ですので速度や寿命を重視し、値段は気にしない場合は MLCではなく SLCを選択します。
(現在では SSD内部のコントローラーも性能が良くなってきているので、SSDとしての速度差は昔ほどではありません。寿命が一番の差別化ポイントとなりつつあります)

2008年11月には、インテルから SLCを使った X25-Eシリーズ、MLCを使った X25-Mシリーズが、同じ時期に発売されていますので、それらを比較してみましょう。
尚、この製品は SATA2接続ですが 2011年の第一4半期まで売られていた、バリバリ現役です。



ReadWrite価格発売時期
X25-E(SLC) 32GB250MB/s170MB/s8.0万円2008.11 (2009.1には 4.3万円)
X25-E(SLC) 64GB250MB/s170MB/s8.0万円2009.2
X25-M(MLC) 80GB240MB/s 70MB/s8.0万円2008.9 (2009.1には 4.0万円)
X25-M(MLC) 160GB240MB/s 70MB/s8.0万円2009.1


同じ値段だと容量に2.5倍ほどの差があります。SLCは価格がどうしても高くなってしまうため、寿命を重視する企業向けとなります。

また、今年の第3四半期には容量 200/400GB、PCIe接続でなんと Read 2200MB/s Write 1800MB/sの SLC使用 Intel 720シリーズ(コードネーム Ramsdale)が発売される予定です。速度の秘密は 512MBの DRAMキャッシュ。すごく高そう。


■ MLCフラッシュメモリベース コンシューマー向け? SSD

SSDが現在のように一般化したのは MLCフラッシュメモリを使用した低価格の SSDが、コントローラーの向上により耐久性、パフォーマンス、容量共に進化したことが大きいといえます。
エポックメイキングな MLCベース SSD達を列挙すると、



ReadWrite価格発売時期
Intel X25-M(MLC)
80GB
240MB/s 70MB/s8.0万円2008.9 (2009.1には 4.0万円)
Intel X25-M(MLC)
160GB
240MB/s 70MB/s8.0万円2009.1
Crucial ReadSSD C300
120GB
355MB/s215MB/s4.0万円2010.3 (現在は 1.8万円) SATA3接続
Crucial ReadSSD C300
256GB
355MB/s215MB/s8.0万円2010.3 (現在は 3.7万円) SATA3接続
OCZ Vertex3
120GB
530MB/s450MB/s3.0万円2011.3 (現在は 2.4万円) SATA3接続



これら以外にも読み書き 500MB/sを越える SSDが続々発売されています。SATA3のバス幅は 600MB/sですので、既にバス幅の限界に近い性能が出ています。ベンチマークをするとほぼスペック通りの性能が出ています。

このSSDはコンシューマー向けと書きましたが、上記に触れたとおり MLCの弱点を補う機能を持つ SSDが増えており、使い方を間違えなければ、業務でも十分使用に耐える製品に変わりました。

実は今、これらの MLC SSDを業務あるいはエンタープライズ向けに使うためのリサーチをしています。近々成果は発表できると思いますので、お楽しみに。


次回は SSDの使い方に関する注意についてまとめてみます。

2011年7月15日金曜日

SSDがヤバい

普通の人が SSD(Solid State Drive)を使い始めたのは、本当につい最近、ここ1~2年前位からではないでしょうか。一昔前までは早いけれど高価なストレージで、一般人には手が出せないシロモノでした。
それが、この1~2年での、速度の向上価格の下落大容量化半端ではないスピードで進んでおり、かつそのスピードはまだ加速していると言えます。

半導体を記憶媒体として使うという SSDの概念自体はコンピューターの黎明期からあるのだけれども (というか、きっと HDDより古いと思う。コアメモリとか言っても最近の人は知らないと思いますけど… 僕も本物を触っていた人は知ってますが、実物は見たことが無い (^^; )、実際に SSDというものがあると知ったのは10年程前でしょうか。
そこから数年を経て、実際の現場にSSDが現れ始めます。
SSDの歴史と特性についておさらいしてみましょう。


■ DRAMベース エンタープライズ向けSSD

うちの会社のOracle検証メールマガジンでも、2007年に富士ゼロックスの GigaExpressという DRAMベースのSSDを借りて、Oracleを高速化する検証を行っています。

GigaExpressは 1Uサイズの筐体に容量は 8GB~32GB、PCIe1.0 x 4レーンの外部インターフェースで接続されます。スペック上は 650MB/sの読み取り性能を持っていますが、実測値は318MB/sでした。(マシン性能に依存するので、実測値はあくまで社内で計測した値です)
検証時の結論は、以下のようでした。
1. IOネックのデータベースの性能向上にはかなり有効である。
2. ただし容量の問題があるので REDOや UNDOに使用するなど構成を考える必要がある。
3. DRAMベースなので電源瞬断や機器故障に対する対策が必須。

この時の販売定価は 200万円 ~ 500万円で、10GBあたりの価格に直すと 155万円 ~ 250万円です。


また、最近でも売っているのが Texs Memory Systemsの Ramsanシリーズです。
Ramsanシリーズの DRAMベースの Ramsan-440という製品は、4.5GB/sの外部帯域幅(あくまでI/Fのスペック。実測値は不明)を持ちますが、256MBの最小構成で 2,720万円とのこと。10GBあたりの価格は 106万 !!! (2年前の記事の価格なので、今はもっと安くなっているのかしら…)
また消費電力もかなり強烈で 650W !! でした。

この製品の場合、GigaExpressと異なり、電源遮断に対応するために内蔵バッテリーや DRAM上のデータをバックアップするHDDやフラッシュメモリを備えているのが価格を押し上げている要因となっているでしょう。
(※ Ramsanにはフラッシュメモリを使用したモデルもあります)

ここまでをまとめると、DRAMベースのSSDは、アクセスは確かに早いのですが、容量が限られていることからデータ特性に応じたきちんとした物理設計が必須であること、価格がバカ高いので簡単には購入できないこと、容量に応じて消費電力が非常に大きくなることなどが言えます。なので、あえてエンタープライズ向け と位置づけました。

2720万 というと、そんなものかと感じるかもしれませんが、10GBあたり 100万円を越えているわけですから、だったらメモリが沢山載るサーバーにしてRAMディスクとして使ったり、Oracleのバッファとして使ったほうがよっぽど良いのではと思ってしまいます。アキバのメモリだったら 10GBで 5000円位です。さすがにメーカー製は高いと思いますが、20倍としても 10万円です。

今日はここまで。
次回はアキバでも買える SLCフラッシュベースの SSDについて書きます。

ご 無 沙 汰 し て お り ま し た

ご無沙汰しておりました。

かなり間が空いてしまいましたが、その間は、会社のブログを投稿したり(このブログの焼き直しですが)、新しい事業を立ち上げるべく奔走したり、髪型を変えたりしておりました。

書きかけの TPC-Hシリーズは、会社のブログで続けることにして、こちらのブログには日々調べたり、考えたりしたことをほぼリアルタイムで書いていくことにします。

とりあえずは Commodity HW Innovation シリーズと題して、コンシューマー向けPCパーツが、今大変なことになっていることを、使い方さえ間違わなければエンタープライズンズでも使えるようになっていることを、書いていこうかと。



2011年4月11日月曜日

TPC-H USD/QphH を計算する

TPC-H検証の続き、ですが、
今後は QphHだけでなく、USD/QphHも出そうと思うので、今日はそのための準備。

値段の出し方は TPC BENCHMARK H Standard Specification の Clause 7: PRICING に定義されていますが、簡単に書くと
ハードウェアとソフトウェアの価格 + 3年間の保守(24x365)
が、システムの値段となります。

Oracleの価格を調べるなんて10年以上やってない。
今回のCPUは AMD Phenom II X6 1100T (3.3 GHz/6 core) なので、Core係数が0.5で 3CPU分。
これを Named User Plusライセンスで計算すると 813万(税込) !!! 年間サポートが 179万(税込) ! 3年分で 1,350万。 マジー!? 12万のPCで動かすのにですよーー!
サポートフィーは更に値上げされるとかいう話も...

この計算合ってますか?
しかし、こんな高い製品をみんな良く買ってますね。ごめんなさい。世間知らずでした。

これに HW価格 12万円、保守は入っていませんが、3年間の間には壊れる部品もあると思うので 8万円を追加して、合計 20万円が HW価格。

両方足して 1,370万円が、システム価格となりました。

あと、検証の途中では Partitioning Optionと Advanced Compressionを使うつもりなので、必要な時にシステム価格に反映させます。

今までの検証結果をまとめると、(為替レートは 85円/ドル)


blocksizeLinux I/O SchedulerQphH@32GBUSD/QphH@32GBPrice(Yen)
8KBcfq974163.051350万円
32KBcfq986161.041350万円
32KBnoop4,70733.731350万円

33ドル/QphHまで来たので、先日書いた

  • 1000GBで 140,181 QphH 12.15 USD/QphH
  • 3000GBで 198,907 QphH 16.58 USD/QphH

にも、もうそろそろ手が届きそうかな?

2011年4月8日金曜日

[memo] Oracle Linux 6 に Gridをインストールする... (その2) ...も玉砕

Oracle Linux 6に Oracle 11gR2を導入しようとしてハマった話の続き。
前回はこちら。


ASM環境を構築して create databaseしたところまでは出来たのですが、実際にデータをロードして selectしてみたら Corrupt Blockのエラーが多発してしまいました。
この状況はまだクリア出来ておらず、現在進行形です。
以下に状況をまとめていきます。


Oracle Linux 6 (x86_64)
Oracle Database 11.2.0.2

現象としては普通に selectすると alertlogに
Hex dump of (file 5, block 1119186) in trace file
/home/oracle/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_p004_17683.trc
Corrupt block relative dba: 0x015113d2 (file 5, block 1119186)
Bad header found during user buffer read
Data in bad block:
 type: 6 format: 2 rdba: 0x015d409a
 last change scn: 0x0000.000f1bbd seq: 0x2 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x1bbd0602
 check value in block header: 0xd126
 computed block checksum: 0x0
Reading datafile '+DATA/orcl/datafile/tpch_8k.263.747829685' for corruption at
rdba: 0x015113d2 (file 5, block 1119186)
Read datafile mirror 'DATA_0002' (file 5, block 1119186) found valid data
のメッセージが延々と続きます。
Corrupt Blockがあったのでミラーから読んだよ、というものです。
ちなみに ASMの冗長性は normalです。

調査開始。

今回の環境では iSCSIで接続しているディスクたちを ASMディスクとして使用しています。
[root@node00 ~]# iscsiadm -m session
iser: [13] 10.2.0.135:3260,1 iqn.1995-07.com.insight-tec.node15:storage.raid0
iser: [14] 10.2.0.134:3260,1 iqn.1995-07.com.insight-tec.node14:storage.raid0
iser: [15] 10.1.0.133:3260,1 iqn.1995-07.com.insight-tec.node13:storage.raid0
iser: [16] 10.1.0.131:3260,1 iqn.1995-07.com.insight-tec.node11:storage.raid0
iser: [17] 10.2.0.136:3260,1 iqn.1995-07.com.insight-tec.node16:storage.raid0
iser: [18] 10.1.0.132:3260,1 iqn.1995-07.com.insight-tec.node12:storage.raid0

[root@node00 ~]# oracleasm listdisks
VOL1
VOL2
VOL3
VOL4
VOL5
VOL6
※ ここで iscsiadmの結果の一番左に tcpではなく iserと表示されているに気づきました? iSER(iSCSI Extention for RDMA)は、iSCSIのデータ転送を TCPではなく RDMA(Remote DMA)を使うことで高速化する技術です。そのあたりの詳しいことは後日まとめるつもり。

そのディスクたちの状況を調べていきます。

SQL> select GROUP_NUMBER, DISK_NUMBER, MOUNT_STATUS, HEADER_STATUS, STATE, REDUNDANCY, FAILGROUP, PATH from v$asm_disk;

G D MOUNT_S HEADER_STATU STATE    REDUNDA FAILGROUP    PATH
- - ------- ------------ -------- ------- ------------ ---------------------------
1 5 CACHED  MEMBER       NORMAL   UNKNOWN DATA_0005    /dev/oracleasm/disks/VOL6
1 4 CACHED  MEMBER       NORMAL   UNKNOWN DATA_0004    /dev/oracleasm/disks/VOL5
1 3 CACHED  MEMBER       NORMAL   UNKNOWN DATA_0003    /dev/oracleasm/disks/VOL4
1 2 CACHED  MEMBER       NORMAL   UNKNOWN DATA_0002    /dev/oracleasm/disks/VOL3
1 1 CACHED  MEMBER       NORMAL   UNKNOWN DATA_0001    /dev/oracleasm/disks/VOL2
1 0 CACHED  MEMBER       NORMAL   UNKNOWN DATA_0000    /dev/oracleasm/disks/VOL1

SQL> select DISK_NUMBER, HOT_USED_MB+COLD_USED_MB USED_MB, READS, WRITES, READ_ERRS, WRITE_ERRS from v$asm_disk;

DISK_NUMBER    USED_MB      READS     WRITES  READ_ERRS WRITE_ERRS
----------- ---------- ---------- ---------- ---------- ----------
          5      11035      18319      63000          0          0
          4      11035      16104      61260          0          0
          3      11038      15517      64942          0          0
          2      11038      15802      66461          0          0
          1      11034      12914      67519          0          0
          0      11040      16818      66523          0          0 
READ_ERRS, WRITE_ERRS共に 0なので、ASM的なエラーは検知していないよう。
エラー内容もレイヤーとしては ASMではなく datablockのエラーに見えます。

今回報告されたブロックのダンプを取ってみます。
SQL> alter system dump datafile 5 block 1119186;

それと、トレースに吐き出されているブロックダンプを比較する。

これがトレースに吐き出されていた情報
Corrupt block relative dba: 0x015113d2 (file 5, block 1119186)
7F5048652000 0000A206 015D409A 000F1BBD 04020000  [.....@].........]
7F5048652010 0000D126 00000001 000122E0 000F0AAF  [&........"......]
....
7F5048653FF0 74756F62 65687420 65747320 1BBD0602  [bout the ste....]
Bad header found during user buffer read
Data in bad block:
 type: 6 format: 2 rdba: 0x015d409a
 last change scn: 0x0000.000f1bbd seq: 0x2 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x1bbd0602
 check value in block header: 0xd126
 computed block checksum: 0x0
Reading datafile '+DATA/orcl/datafile/tpch_8k.263.747829685' for corruption at rdba: 0x015113d2 (file 5, block 1119186)

これが自分でダンプした情報
Start dump data blocks tsn: 6 file#:5 minblk 1119186 maxblk 1119186
Block dump from cache:
Dump of buffer cache at level 4 for tsn=6, rdba=22090706
Block dump from disk:
buffer tsn: 6 rdba: 0x015113d2 (5/1119186)
scn: 0x0000.000f19dd seq: 0x02 flg: 0x04 tail: 0x19dd0602
frmt: 0x02 chkval: 0x54c9 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007FF47C991A00 to 0x00007FF47C993A00
7FF47C991A00 0000A206 015113D2 000F19DD 04020000  [......Q.........]
7FF47C991A10 000054C9 00000001 000122E0 000F0AAE  [.T......."......]
....
7FF47C9939F0 73202E73 6E656C69 65722074 19DD0602  [s. silent re....]

データの中身から Consistency value, checksum, 果てには SCNまでまるっきり異なります。当然ですが、エラーが出てからデータの更新はしていません。ミラーから読み込んだデータで上書きされたとしか考えられません。あるいは、コマンドの実行方法を間違えているのか?

今回問題のテーブルに select count(*) をかけるのですが、毎回 Corruptと報告されるブロックアドレスが異なります。ミラーデータから修復されているとしたら、そのうちエラーは出なくなりそうなものですが、何度実行しても同じくらいの数のブロックがエラーと報告されます。

dbverifyかけてみました。

$ dbv USERID=sys/*** FILE='+DATA/orcl/datafile/tpch_8k.263.747829685' FEEDBACK=100
...
Total Pages Marked Corrupt   : 6
...
$ dbv USERID=sys/*** FILE='+DATA/orcl/datafile/tpch_8k.263.747829685' FEEDBACK=100
...
Total Pages Marked Corrupt   : 13
...

何度やっても Corrupt Blockが消えないし、毎回異なるブロックが報告されるという状況は変わらず。読みながら、ブロックを修復しつつ、他のブロックを壊している ような感じです。

ここで、一応諦めました。

ASMは、OS Versionや Oracle Versionを、非常にセンシティブに選びます。
きっと 11gR2が Oracle Linux 6対応するときは、新しい必須パッチが出るのだと予想。


ここまでの収穫

ASM内部情報についてまとめたサイトを見つけました。
11gR1 から 11gR2で ASMの内部構造がかなり変更されているのがわかります。

ASM Metadata and Internals

2011年4月7日木曜日

[memo] Oracle Linux 6 に Gridをインストールする...

Oracle Linux 6 + Oracle 11gR2(11.2.0.2)で ASM環境を構築する必要があったので、
何の気なしに片手間で作り始めたら、かなりハマりました。
忘れないうちに、Oracle Linux 5.6 の時との違いについてポイントをまとめておきます。

ちなみに、このポイントをクリアしても、動作するわけでありません っっ
あるいは、解決方法知っている人がいたら大募集。

更に、Oracle 11gR2は、まだ Oracle Linux 6を正式サポートしていませんので、チャレンジャーな感じです。


Oracle Linux 6
E-Deliveryからダウンロード
デフォルトの Unbreakable Enterprise Kernelを導入
導入するときに oracleasm-support-2.1.5-1.el6.x86_64 は、必ず入れる。

逆にこれ以外は oracleasm関連パッケージはありませんでした。


Oracle Grid Infrastructure 11.2.0.2.0
ASMディスクの構成を行い、インストーラを実行。構成チェックで root.shを実行するとエラーになる。
# .../root.sh
...
ohasd failed to start
Failed to start the Clusterware. Last 20 lines of the alert log follow:
2011-04-01 11:55:49.329
[client(25625)]CRS-2101:The OLR was formatted using version 3.
2011-04-01 11:55:55.191
[client(25654)]CRS-1001:The OCR was formatted using version 3.
[client(25696)]CRS-10001:CRS-6021: No msg for has:crs-6021 [l][unlimited]
[client(25697)]CRS-10001:CRS-6021: No msg for has:crs-6021 [n][65536]

ohasd failed to start at /home/oracle/app/oracle/product/11.2.0/grid/crs/install/roothas.pl line 325.
/home/oracle/app/oracle/product/11.2.0/grid/perl/bin/perl -I/home/oracle/app/oracle/product/11.2.0/grid/perl/lib -I/home/oracle/app/oracle/product/11.2.0/grid/crs/install /home/oracle/app/oracle/product/11.2.0/grid/crs/install/roothas.pl execution failed.
#
CRS-06021: Could not set system resource limits for Clusterware: "ulimit -string string".
メッセージからすると ulimit -l と -n の変更が出来ないと言っている。
裏で取得していた strace(1)でも同じエラーが出ていた。
setrlimit( RLIMIT_MEMLOCK,{rlim_cur=RLIM_INFINITY,rlim_max=RLIM_INFINITY})
 = -1 EPERM (Operation not permitted)
setrlimit( RLIMIT_NOFILE,{rlim_cur=64*1024,rlim_max=64*1024})
 = -1 EPERM (Operation not permitted)

/etc/security/limits.confに以下を追記する
* soft nofile 2048
* hard nofile 131072
* soft memlock 64
* hard memlock unlimited




ulimitのエラーは出なくなったが、相変わらず同じ場所でエラーとなる。
root.shに strace(1)をかけて見てみると
ctsctl.binのプロセスが /var/tmp/.oracle/sOHASD_UI_SOCKET というソケットファイルが出来るのを待っている様子が見て取れる。
12964 socket(PF_FILE, SOCK_STREAM, 0)   = 5
12964 access("/var/tmp/.oracle/sOHASD_UI_SOCKET", F_OK) = -1 ENOENT (No such file or directory)
....
CRS-04124:Oracle High Availability Services startup failed.を出力
....
nanosleep(...)
...この繰り返し...

OHASが立ち上がっていないのが原因か。
なので ohasd.binというプロセスを見ていくと、
12969 mknod("/var/tmp/.oracle/npohasd", S_IFIFO|0666) = 0
12969 open("/var/tmp/.oracle/npohasd", O_WRONLY <unfinished ...>
ここが最後の行になっている。NamedPipeの open(2)が終了していない???
じゃあ、ここから吸いだしてあげたらいいじゃないか、ということで
# dd if=/var/tmp/.oracle/npohasd
を実行したら、ohasd.binが動き出した!!
一応必要なプロセスが全部動き始めたようで roo.shの実行が終了しました。

後でググったら、 CRS-4639: Could not contact Oracle High Availability Services

の資料でも ddコマンド使う という方法が載っていました。前のバージョンですが。
ddコマンドで動かすというのは、かなり乱暴だと思いますが、それが対応策で載っているあたりがオラクルです。syslogdが動作していないと発生する、というような記述もあるので、時間があれば後で調べてみようと思います。

ohasdが /var/tmp/.oracle/npohasdの open(2)で止まっていたら、dd(1)で先にすすめることが出来る。

ちなみにOS再起動するたびに dd(1)を実行しています。。トホホ


Oracle Database 11.2.0.2.0
Database自体の導入はスムーズに進みました。
また、今回のデータベースは SYSTEM表領域などはファイルシステム上に、ユーザーデータだけをASM上に作成しています。
で、データを入れてパフォーマンスを測りだしたら、Corrupt Blockのエラーが多発。。。。

データのロード方法などをいくつか試していますが、今のところ、ある程度以上のデータ量だと確実に再現しています。

詳細は次回で。

2011年4月6日水曜日

TPC-H Linux I/O Schedulreを変えてビックリ

引き続きTPC-Hの検証。

Linux I/O Schedulerには4種類ありますが、新久保君の TPC-Cの検証で Linux I/O Schedulerによるパフォーマンスの違いは無い という結果が出ています。

が、今回はおどろくべ結果が!!!


blocksizeLinux I/O SchedulerElapsedQphH@32GB
32KBcfq3,342 sec986
32KBnoop678 sec4,704


Linux I/O Schdulerを noopに変えただけで約5倍のパフォーマンスアップとなりました!

SSDの場合、ディスクヘッドのシークが無いので、何もスケジュールしない noopが有利だと言われていますが、こんなに異なるとは予想外。
リソース消費量についても処理時間を裏付ける結果となりました。




throughputは 133MB/secから 652MB/secへ。
IOPSは 1,668から 8,211へ。そのまま処理時間の差と同じです。
ちなみにトータルのディスク読み込み量は約45GBでほぼ同じでした。(IO Schedulerしか変えていないので当たり前)

この違いはどこから来ているのか。
strace(1) に -T -tttオプションを付けて、Oralceのバックグラウンドプロセスの発行する pread(2)のレスポンス時間および、pread(2)が発行されるインターバルを見てみた。

-T: system call内の滞留時間をマイクロ秒単位で出力。
-ttt: 出力各行にマイクロ秒単位の時刻を出力


Oracleバックグラウンドプロセスが読み込みをするときは pread(2)が連続して呼び出されます。
pread(2)がリターンしてきてから、次のpread(2)が発行されるまではどちらもほぼ同じ時間で、約0.1~1msec前後でした。IOサイズは 1MBで同じであり、Oracle内部処理は、IO Schedulerに左右されませんから、同じのも当たり前と言えば当たり前です。

ところが、pread(2)自体にかかる時間が cfqの場合は 10~100msecでかなりばらつきがあります。対して noopの場合は 約10msecであり、かなり安定していました。
  • この処理は Parallel Degree=6で行っているので、複数プロセスから同時にIOリクエストが来ている。
  • pread(2)にかかる時間と Oracle内部処理時間を比較すると 1/100 ~ 1/1000 のオーダーなので、読み込み処理時は、ほぼすべての時間がディスクIO待ち。つまり、ディスクには常に複数リクエストがキューイングされた状態になっている。
  • 従って cfq処理のオーバーヘッドが、今回の性能差になっている。

上記推測を元に、再度 vdbenchによる Linux IO Scheduler別の性能比較を行ってみましたが、結果は以下。




1-Threadこそ noopの方が早いですが、それにしても5倍の差はありません。4-Threadでは cfqと noopの有意な差はありませんでした。今回はパラレルクエリーなので cfq, noopの差は無いはずです。
ここまで書いてきて、もしかして Threadと Processで挙動が異なるかも、という気もしましたが、普通に考えると、リクエストキューはデバイスごとに作成されるしなぁ~
ということでまだ理由がわかっていません。



今日の結論は、
SSD上のファイルシステムにOracleデータファイルを作成する場合は、IO Schedulerは必ず noopで!

本日の結果: 4,704 QphH@32GB



次回はOracleのパラメータで filesystemio_options を調整してみる。

2011年2月28日月曜日

TPC-H blocksizeを 32kに

前回のつづき

前回は blocksizeはデフォルトの 8kで作成しましたが、今回は 32kにしてみました。
DWHは出来るだけ blocksizeを大きくするのが定石ですが、結果は、、、

blocksizeElapsedQphH@32GB
8KB3,436 sec974
32KB3,342 sec986

若干速くなってはいるものの、わずか数%良くなっただけ。

今回は Paralle Degreeを初めから 6にしてテーブルを作成しているため、ディスクへのアクセスは direct readになっています。strace(1)を使って、読み込みサイズを見ると、どちらも 1MBでしたので、処理時間が変わらないことも納得がいきます。

direct readの時の I/Oサイズは db_file_multiblock_read_count=128 から、8k x 128 = 1MBとなります。
blocksize=32kの場合も 1MBなのは _db_file_direct_io_count = 1048576 によって決められているようです。
簡単に試した結果 _db_file_direct_io_countを大きくすると、pread(2)の際のサイズも大きくなることを確認しました。このパラメータに関する検証は、後の課題にしたいと思います。

とりあえず今回の結論は、direct readでアクセスする場合、大事なのは blocksizeではなく I/Oサイズ。

本日の結果: 986 QphH@32GB

次回は Linux I/O Schdulerを、デフォルトの cfqから noopに変えてみます。
実は驚くべき結果が。。。

2011年2月23日水曜日

TPC-H QphHはどうやって計算するのか

TPC-Hでは QphHで速度性能を表現しています。

TPC-H Non-Clusteredの Oracleでの記録を見ると、現在の所の第1位は以下のような記録でした。

  • 1000GBで  140,181 QphH    12.15 $/QphH
  • 3000GBで  198,907 QphH    16.58 $/QphH 
(正確には 140,181QphH@1000GB  などと、ScaleFactor(SF)を @に続けて書きます。
 ちなみに SFが異なる値を比較するのは意味が無い と言われている。)

QphHの名前((Query-per-Hour Performance Metric))から単純に考えると 1時間あたりの何クエリー発行できるか  という値に見えるが、実際の計算はもう少し複雑。

前回、とりあえず 22個の TPC-HのSQLを実行したら
3436秒 = 57分16秒   かかったと書いたが、
では、これは  1時間あたり 約22クエリーなので   22 QphH@32GB  なのか?

実際に計算したら 22ではなく、 974 QphH だった!


詳しく見ていきましょう。

TPC-Hで表示されている QphHは、正確には "TPC-H Composite Query-per-Hour Metric"  と呼ばれており、Compositeという通り、

TPC-H Power (1セッションで、どれだけ速く処理できるか) 
TPC-H Throughput (複数セッションで、どれだけ速く処理できるか)

の2つの値から計算される値となります。
具体的には、それらの値の相乗平均が QphH となります。




では、TPC-H Powerの計算方法は、というと、3600*SF の値を、22個のSQLの処理時間の相乗平均で割った値となります。数式にするとこんな感じ。


QIは Query Intervalで、各SQLの処理時間(秒) が入ります。
分母は相乗平均なので1つでも短いクエリーがあるとかなり値は良くなってきます。
例えば、22個のSQL文が全て10秒で終了して合計220秒の場合は 11,520QphHとなります。
しかし、1個のSQLが199秒かかったが他の21個のSQLが1秒で終了して合計220秒の場合は 90,564QphHとなり約8倍のパフォーマンスとなります!!
なので、きちんと TPC-Hを測定する場合は、いくつかのSQLは捨てる代わりに、思いっきり早いSQLを作るというテクニックを使う場合もあるようです。今回はOracleの機能や構成による違いをみたいので、そこは追求しませんでした。
(本当は22個のSQLの他にインサート、デリートをする2つのSQL(Refresh Functionsと呼ばれています)があるのですが、今回は割愛。大体上記の計算式で合っています。)
で、
今回、自分は1セッションで検証したので TPC-H Powerの値を測っていることになりますが、各Queryの実行時間は
Q1   226.78 sec
Q2     18.17 sec
...
Q22 39.88 sec
で、これにエクセルで (3600 * SF) / (product(Q1~Q22) ^ (1/22) ) なんて計算をして、974 QphH  というのが出てきました。


TPC-H Throughputは、今後の複数セッションの検証の時に説明しますが、いくつかのTPC-Hのレポートを見ると、若干 TPC-H Throughputの方が高い数値となる傾向にあるようですが、概ね同じ程度の値となります。なので、エイヤーッと、 QphH と 自分の TPC-H Powerをそのまま比較することにします。

すると  14万~19万 QphHと 974QphHなので、約140倍から200倍の差  というところになります。

今回検証した環境の値段は HWは 約12万円ですが、Oracle価格と3年保守を入れないといけないので、それだけで数百万。。。    $/QphH  は多分、100 $/QphH 位でしょうか。こちらも 6~8倍とかなり負けてます。



これで一応計測の目安が出来たので、次からはいくつか構成を変えながら、出来るだけパフォーマンスアップ出来るように考えていきます。


本日の結果: 974 QphH@32GB


今回参考にした TPC-Hの仕様書
TPC BENCHMARK H  Standard Specification

リポジトリの作成と とりあえず測ってみた

今回のテストはデータがメモリから充分溢れるように、メモリサイズ16GBの倍の 32GB準備することにしました。

データのロードは外部表を使うのが一番簡単で早い。
また 6coreのCPUなのでデータを6つに分けることと、データを圧縮して速度向上を図ってみました。SSDだと圧縮効果が薄れると思うが、HDDを使う場合は圧縮することによりかなり時間が短くなります。
$ dbgen -f -C6 -S1 -s32 &
$ dbgen -f -C6 -S2 -s32 &
...
$ dbgen -f -C6 -S6 -s32 &

$ gzip *.tbl

以下が、データロードするSQL文。lineitemだけを書いているが、これを他の7つのテーブルにも行う。(元になるSQL文は Create Your Own Oracle TPC-H Playground on Linux  の情報を大いに参考にして作成しました。)

CREATE OR REPLACE DIRECTORY tpch_dir AS '/home/oracle/....'
/
CREATE OR REPLACE DIRECTORY zcat_dir AS '/bin'
/

CREATE TABLE lineitem_ext (
    l_orderkey NUMBER(10)
  , l_partkey NUMBER(10)
  , l_suppkey NUMBER(10)
  , l_linenumber NUMBER(38)
  , l_quantity NUMBER
  , l_extendedprice NUMBER
  , l_discount NUMBER
  , l_tax NUMBER
  , l_returnflag CHAR(1)
  , l_linestatus CHAR(1)
  , l_shipdate VARCHAR2(10)
  , l_commitdate VARCHAR2(10)
  , l_receiptdate VARCHAR2(10)
  , l_shipinstruct VARCHAR2(25)
  , l_shipmode VARCHAR2(10)
  , l_comment VARCHAR2(44)
  )
  ORGANIZATION EXTERNAL (
    TYPE oracle_loader
    DEFAULT DIRECTORY tpch_dir
    ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE
       PREPROCESSOR zcat_dir:'zcat'
       BADFILE 'bad_%a_%p.bad'
       LOGFILE 'log_%a_%p.log'
       FIELDS TERMINATED BY '|'
       MISSING FIELD VALUES ARE NULL
    )
    LOCATION (
        'lineitem.tbl.1.gz'
      , 'lineitem.tbl.2.gz'
      , 'lineitem.tbl.3.gz'
      , 'lineitem.tbl.4.gz'
      , 'lineitem.tbl.5.gz'
      , 'lineitem.tbl.6.gz'
    )
  ) 
  PARALLEL 6 REJECT LIMIT 0 NOMONITORING
/

CREATE TABLE lineitem (
    l_orderkey NUMBER(10) NOT NULL
  , l_partkey NUMBER(10) NOT NULL
  , l_suppkey NUMBER(10) NOT NULL
  , l_linenumber INTEGER NOT NULL
  , l_quantity NUMBER NOT NULL
  , l_extendedprice NUMBER NOT NULL
  , l_discount NUMBER NOT NULL
  , l_tax NUMBER NOT NULL
  , l_returnflag CHAR(1) NOT NULL
  , l_linestatus CHAR(1) NOT NULL
  , l_shipdate DATE NOT NULL
  , l_commitdate DATE NOT NULL
  , l_receiptdate DATE NOT NULL
  , l_shipinstruct VARCHAR2(25) NOT NULL
  , l_shipmode VARCHAR2(10) NOT NULL
  , l_comment VARCHAR2(44) NOT NULL
  )
  PCTFREE 1 PCTUSED 99 PARALLEL 6
/

INSERT /*+append*/ INTO lineitem
SELECT 
   l_orderkey
 , l_partkey
 , l_suppkey
 , l_linenumber
 , l_quantity
 , l_extendedprice
 , l_discount
 , l_tax
 , l_returnflag
 , l_linestatus
 , to_date(l_shipdate, 'yyyy-mm-dd')
 , to_date(l_commitdate, 'yyyy-mm-dd')
 , to_date(l_receiptdate, 'yyyy-mm-dd')
 , l_shipinstruct
 , l_shipmode
 , l_comment
FROM lineitem_ext
/

BEGIN
  dbms_stats.gather_table_stats(ownname => 'TPCH_&TESTID.', tabname => 'LINEITEM', degree => 6, cascade => TRUE) ;
END;
/

また、SSDなので書き込みが発生しないように、テーブルスペースを readonlyにしておくことも忘れない。
ALTER TABLESPACE tpch_&TESTID. READ ONLY;


あと、もう1つ大人な事情があった!
今回はインデックスを利用できない時の処理速度を測定したかったので、TPC-Hを正確に測定する際は必ず作成しなければいけない primary key, foreign key を全て作成しないようにしました。
なので全てのデータに対して FULL Table Scanとなります。例えば lineitemであれば、次のようなインデックスを作成する必要があるのです。

-- PK Constraints
CREATE UNIQUE INDEX lineitem_pk 
  ON lineitem(l_linenumber, l_orderkey) PARALLEL 2
/
ALTER TABLE lineitem ADD CONSTRAINT lineitem_pk 
  PRIMARY KEY(l_linenumber, l_orderkey)
  USING INDEX lineitem_pk
/

-- FK Constraints
ALTER TABLE lineitem ADD CONSTRAINT lineitem_partsupp_fk 
  FOREIGN KEY(l_partkey, l_suppkey) 
  REFERENCES partsupp(ps_partkey, ps_suppkey) NOT DEFERRABLE
/
ALTER TABLE lineitem ADD CONSTRAINT lineitem_orders_fk 
  FOREIGN KEY (l_orderkey) 
  REFERENCES orders(o_orderkey) NOT DEFERRABLE
/

まあ、正確なTPC-Hの測定にはなりませんが、余計なインデックスは邪魔なので良しとします。

で、前回説明したとおり qgenで作成したSQL文 22個を
デフォルトの blocksize=8k で作成したデータで、とりあえず実行してみた。
そしたら 3436秒 = 57分16秒 だった。

果たしてこれは速いのか。

次回は TPC-Hで使う QphHの計算方法について触れ、
上記の処理時間が、どれ位なものなのかを考えてみることにしよう。


※ 2011/4/5 追記: TPC-H用リポジトリを作成するSQL文の元ネタの場所を追記しました。

2011年2月19日土曜日

TPC-H のテスト 開始

贅沢に SSD6枚のマシンを使える機会があったので、こりゃラッキーと DWHマシンとしての検証開始!
小幡さん新久保君の構成よりかなり贅沢なので、そこで出来なかったことが出来るぞ、ということでガッツリ検証してみます。


まずは今回のマシンスペックから。 
Memory: 16GB (4GBx4)
SSD: Crucial CTFDDAC064MAG-1G1(64GB)  x 6 (1枚はOS用、あとはデータ用)




内臓(SSDx6)を引き出したところ。
SATAと電源のケーブルでいっぱい。

SSDはそれぞれSATA3 6Gb/sに接続している。
今回のSSDはカタログスペックで読み込み350MB/secとあるので、これを5枚使って、どれ位まで性能を上げられるか楽しみ。

とりあえずはDiskの性能測定から。
SSD 5枚は BIOSレベルで RAID-0(Stripe Size=64k)を組んだので、理論値では 1.5GB/secを越えるが、このCPU,MBの組み合わせで、どれ位のスループットが出るのだろう。


読み込みはカタログスペック通り350MB近く。(いや 90%しか性能が出ていないが...)
5枚のRAID-0では 読み込み1GB/sec を越えてきている。後はこの性能を出し切れるか。
ちなみにLinux I/O Schedulerは cfqにて測定。

今回のTPC-H測定は大人な事情があって、HammerOraなどのツールを使わず、TPCのサイトからダウンロード出来るクエリージェネレーター qgenで生成した生のTPC-H用SQLを使って、SQLが終了するまでの時間を測定した。

では次回から検証をスタートしてみる。