WebサイトのバックエンドにTeradataを採用するプロジェクト
けっこう大きなWebサイトの構成立案に弊社が参加していて、バックエンドのDBの選定などがウチ担当になっている。
高速なDBが必要ということで、営業サイドはTeradataを推す案を作っている。
高速なDB -> じゃあTeradataで、という感じなのだが、アプリの実装はかなりハードルが高いのではないかと思って見ている。
「速いDB」の2つの意味
小田圭二さんの本なんかに繰り返し書かれているが、「DBが速い」という言葉には、高スループット(≒I/Oが速い)ということと、レスポンスがよい(≒同時並行性が高い)ということの、二つの意味がある。
Webのバックエンドに求められるのは後者の速さだが、Teradataは完全に前者にフォーカスしたRDBだ。
Teradataの他のDBとの相違点といえば
- 大量のディスクによる並列I/O
- ロック機構による同時実行制御
であり、これは同時接続数が多くセッション当たりのデータ量が少ないWebアプリには向いていない。
I/Oは速い
TeradataのI/Oは速い。
それまでディスク1台*1のDBしか見たことがなかった私は、Teradataにさわってみて書き込みの速さに仰天した。
100万件ぐらいのデータを insert into ... select ... で転記するのに2秒かからない。
初めてTeradataに触れたころに、本番環境からテスト環境へのデータ移行が完了しているか確認するという作業があって、1億件のテーブルの差分を以下のSQLでチェックしたことがあった。
select * from 本番.xxxx
except
select * from テスト.xxxx
このSQLに対して、Teradataはこんな実行計画を作成する:
- テーブルの全列をくっつけたものからハッシュキーを生成し
- そのハッシュキーをもとに、1億件×2テーブルをハッシングしつつディスク上に書き出す。データ量は合計40GBぐらい
- ハッシュ結合する
実行計画に「40GB」とか書いてあるのを見て、うわぁ...と思ったが実行してみると1分10秒で終了した。
私にはびびってたじろぐ速さだった。皆さんはどうでしょうか。Oracleとかでもこれぐらい当たり前なのでしょうか。
レスポンスは...
更新トランザクションが随時発生する環境では、Teradataの同時並行性は高くない。
Teradata同時実行制御をすべてロックで行うので(非MVCCなので)、readトランザクションがwriteトランザクションを、また逆にwriteがreadを止めてしまう。
さらに(クエリに特殊なオプションを付けない限り)待ち行列が必ず到着順に処理されるので、「readがreadを待たせている」ように見える現象も起きる。
WebアプリのバックエンドとしてTeradataを使うには、
- Webからの更新にはupdateを使わず、insertのみにする
- insertするレコードはPI(Primary Index)の値が極力ばらけるようにし、同じAMP(Teradataの並列処理単位)に同時に書き込みが発生しないようにする
といった、DBMSの特性を意識したアプリケーションを作らなくてはならない。
多分難しい仕事になると思うけど、国内にあまり事例がないらしいし、決まったら喜んでやってみようかと。
*1:あるいはRAID5構成のディスクが1セット