SSDとSATAのベンチマーク比較 第2ラウンド:サーバアプリケーションValidation Case Study(2/2 ページ)

» 2008年08月08日 03時23分 公開
[ITmedia]
SourceForge.JP Magazine
前のページへ 1|2       

 テストで特定のインデックスを評価するときは、それ以外のインデックスが存在しない状況でテストすることにしている。そこで、SSD上のインデックスをテストするときはHDD上のインデックスを事前に削除し、HDD上のインデックスをテストするときはSSD上のインデックスを削除する。インデックスごとに3種類のselectコマンドを実行した。各コマンドはそれぞれコールドキャッシュを使う操作、ホットキャッシュを使う操作、“クロス”キャッシュを使う操作に対応する。

 コールドキャッシュによる操作では、いったんPostgreSQLデータベースを停止し、データベースとSSDテーブル空間の置かれているディスクをマウント解除してからテストを行った。ホットテストでは、同じクエリを2回実行した。クロステストのためには、ある特定の状態で最初にコールドテストとホットテストを実行してから別の状態でクエリを実行する必要がある。最初の状態のコールドテストとホットテストでPostgreSQLは、その状態に対応するインデックスページをRAMにキャッシュする。次に別の状態でクエリを実行すると、一部のインデックスページはRAMにキャッシュされているものが利用されるかもしれないが、必要なすべてのページでキャッシュが使われるわけではない。絶えずアクセスされるデータベースで、しかもパフォーマンスを気にしてインデックス用にSSDを装備しようと考えるほどのデータベースの場合、インデックスページのどれかがRAMにキャッシュされないことなど PostgreSQLではほとんどあり得ず、SSDの優位性は低下する。一方、ホットテストは現実的でない。必要なインデックスページがすべてキャッシュされる可能性が非常に高いからだ。クロステストは折衷的になるように工夫されている。つまり、一部のインデックスページはキャッシュに存在するだろうが、クエリに必要なすべてのインデックスページがキャッシュに含まれることはない。

 クエリからどれだけの数のタプルが返される見込みがあるかでデータベース側のクエリの解決方法が変化するため、PostgreSQLで常にインデックスが使われるように、あまり多くの結果を返さないようなクエリを使用した。具体的には、出生地(pob:places of birth)のリストからFlorida(pob=12)、Puerto Rico(pob=72)、Nevada(pob=32)を選択したわけだが、SQLのexplainコマンドによると、これらのクエリでpob上のインデックスが使われることが分かったからだ。これらのクエリはそれぞれ5万4445個、1万134個、4722個のタプルをテーブル内の合計245万8285個のタプルの中から見つける。クロステストの順番はFlorida、Puerto Rico、次にPuerto Rico、Nevada、次にNevada、Floridaの順である。SQLクエリは以下に示すとおり、至って簡単なものだ。PostgreSQLに不慣れなら、先頭にexplainキーワードをつけてクエリを実行するとよい。クエリを実行したとき実際にどのようなことが起こるかをPostgreSQLが教えてくれる。以下の例では、インデックスが本当に使われるか確認するためにexplainを使用している(結果はIndex Scan行に示される)。インデックススキャン後に実行されるAggregateは、返されたタプルの数をカウントするだけである。


# explain  select count(*) from census where pob = 12;
                                   QUERY PLAN
--------------------------------------------------------------------------------
 Aggregate  (cost=36740.79..36740.80 rows=1 width=0)
   ->  Index Scan using pobssd on census  (cost=0.00..36708.78 rows=12800 width=0)
         Index Cond: (pob = 12)
...
select count(*) from census where pob = 12;
select count(*) from census where pob = 72;
select count(*) from census where pob = 32;

 SSDは、XFSでフォーマットし、最大のパフォーマンスを得るためにnobarrierオプションを指定してマウントした。nobarrierオプションを指定すると、突然電源が切れた場合にジャーナル内のトランザクションが失われる恐れがあるが、サーバ環境ではUPSが突然の電源故障からマシンを保護するものと考えられるので、nobarrierオプションを指定しても問題はない。また、PostgreSQLでpobssdインデックスが使われるようにするためにテーブル空間(tablespace)としてSSDを指定した。


mkfs.xfs -f  -i size=512 -l lazy-count=1 /dev/disk/by-id/ata-MTRON_MSD-SATA3025_0HB3331303546-part1
mount -o "nobarrier" /dev/disk/by-id/ata-MTRON_MSD-SATA3025_0HB3331303546-part1 /mnt/ssd
mkdir /mnt/ssd/postgresql-data
chown postgres:postgres  /mnt/ssd/postgresql-data

psql ucicensus1990 CREATE TABLESPACE ssd LOCATION '/mnt/ssd/postgresql-data';
drop index pob; create index pobssd on census ( pob ) tablespace ssd;

 平均すると、ホットキャッシュによるパフォーマンスは、SSDとHDDのどちらのインデックスでも速度的によく似ており、SSDでの必要な時間はHDDのインデックスで同じクエリを使用したときの70〜85%になった。しかし、Nevadaに関するデータを検索したとき特異的な現象が起こり、ホットキャッシュの使用時にSSDのインデックスでは5ミリ秒しかかからないのに、HDDのインデックスでは約200ミリ秒もかかった。Nevadaだけパフォーマンスが異なる理由は、よく分からない。

SSD vs HDD for Postgres index SSD vs HDD for Postgres index

 右のグラフは、コールドキャッシュとクロスキャッシュ関して、SSDのインデックスとHDDのインデックスのパフォーマンスを比較したものだ。コールドキャッシュの場合、SSDのインデックスはHDDのインデックスのときの3〜10%程度の時間でクエリを解決できている。コールドキャッシュでパフォーマンスが最低となるクエリはFloridaで、これはほかのケースよりも多くのタプルをフェッチする必要があるからだ。また、FlordaについてはSSDインデックスで必要な時間がHDDインデックスでの時間の10%となっているが、これはたぶん、インデックスそのものよりもベーステーブルにかんする負荷が大きいせいだ。クロスキャッシュを使うクエリの結果は興味深い。前回のクエリでインデックスの一部のページがRAMにキャッシュされていても、SSDはHDDキャッシュのときの20%以下で同じクエリを実行できている。


まとめ

 SSDの最大容量は従来のHDDに比べるとまだ小さく、Gバイト当たりのコストもかなり高く付くが、1台のSSDにより得られるシークタイムは6台のHDDで構成されるハードウェアRAIDよりも優れている。データベースサーバを運用していて、インデックスページのキャッシュに使えるRAMを既に限界まで増設している場合、さらにパフォーマンスを上げる必要があるなら、データベースのインデックスのパフォーマンスを引き上げるために32Gバイトか64GバイトのSSDを増設することを検討してもよいだろう。

Ben Martinは、ここ10年以上ファイルシステムに取り組んできた。博士号を取得し、現在はlibferris、各種ファイルシステム、検索ソリューションを中心にコンサルティングサービスを手掛けている。


前のページへ 1|2       

Copyright © 2010 OSDN Corporation, All Rights Reserved.

注目のテーマ