現場で役立つ実践ノウハウWeb開発の「べし」「べからず」
~性能を最大限に引き出すための設計・開発・運用~
永安 悟史
本記事は、技術評論社 WEB+DB PRESS Vol.63 で掲載されたものを、著者と出版社の許可を得て転載したものです。なお、一部 記述に変更のある箇所もあります。
アーキテクチャから理解するデータベース
データベースの技術は長い歴史の蓄積があり、その実装であるデータベース製品は非常に複雑なソフトウェアとなっています。そのため、深く理解するにはそれなりの学習期間と経験を必要とします。
本章では、データベースの中でも特にリレーショナルデータベース(RDBMS)について、理解するためのポイント/観点と、具体的に開発/運用時に注意すべき点について解説します。
データベースの理解は「立体的」に
データベースの挙動をきちんと理解するためには、データベースを構成する要素を「立体的」、つまり複数の角度/軸で理解する必要があります。
処理の流れを理解する
データベースの挙動を理解する第1の軸は「処理の流れ」です。図1に示すような一連の流れで処理を行います。まずはこの流れに沿って、データがどのように処理されていくのかを理解する必要があります。
処理の層(レイヤ)を理解する
データベースを理解するもう一つの軸は「層(レイヤ)」です。
データベース製品が動作している環境には、CPU、メモリ、ディスク、ネットワークインタフェースカードなどのハードウェアコンポーネントがあります。また、メモリ内には、実行プロセスのメモリ、共有メモリ、ディスクキャッシュなどのメモリ空間があります(図2)。これらのコンポーネントが、それぞれ重要な役割を果たしつつ相互に連携しながら動作しており、個々のコンポーネントの動作が全体のパフォーマンスなどにも大きな影響を与えます。
ディスク上のテーブルデータやインデックスのデータは、共有メモリ内の「共有バッファ」と呼ばれるメモリ空間にキャッシュされ、各クライアントの要求を受け付けている複数のサーバプロセスから共有する形で読み書きされます(図3)。ディスクに書き出す(保存する)際には、専用のプロセスが共有バッファの内容をディスクに書き戻します。
このようにデータベースの挙動を正しく理解するには、「どのような処理が、どのようなハードウェアの中を流れているのか」ということを立体的に理解する必要があります。
I/Oを制する者はデータベースを制す
データベース処理の技術は、一言でいうと「データや処理の論理的な整合性を保ちつつ、いかにI/O処理を高速化するか」という技術です。データベースで扱われるデータは、ディスク上に書き込まれて保存され、読み出す際もディスクから読み出されます 注1。
また、前述したコンポーネント(CPU、メモリ、ディスク、ネットワーク)の中では、一般的にディスクが最も低速なデバイスです。データベース内部では、ディスクへの入出力処理も多く、また性能に与える影響も大きくなるため、これらの理解は、特に性能問題に取り組む際には必須になります。「ディスクI/Oの発生状況によってクエリの実行時間が数百倍も違う」といったことも現実に発生します。
筆者は、よく「I/Oを制する者はデータベースを制す」という表現を使うのですが、それだけ「データベースにおけるI/O処理」について深く理解しておくことが、実務上は重要であると言えます。
注1:インメモリデータベースなどの技術もありますが、ここでは一般的なRDBMSについて議論します。図2はPostgreSQLのアーキテクチャを模式図にしたものですが、ほかのRDBMSでもプロセスがスレッドになるなどの違いはありますが、大きな骨格としては似た構造になっています。
データベースは「生き物」である
2番目に押さえておいてほしい点は、「データベースは生き物である」ということです。
データベースの動作状況は、時々刻々と変化します。トラフィック(トランザクション量)も変化しますが、データベース特有の点は「データ量が変化する」ということです。データ量が変化すると、ディスクI/Oの量、メモリの使用量、ネットワークのトラフィックなど、すべてが連動して変化します。その結果として、少しずつ性能が低下し、当初想定していた性能が出なくなったり、場合によってはある日突然、性能が大きく低下する、といった事態が発生します。
先にも述べたように、データベースの開発・運用では、ディスクI/O処理をいかに減らすか/高速化するか、といった点が非常に重要です。そのため、「今まで共有バッファに乗る(キャッシュできる)データサイズだったのが、ある日、共有バッファサイズを超えたためにディスクアクセスが増えて、性能が大きく低下する」といったケースも発生します。
そういった事態を避けるためにも、必ずデータベースの容量などの監視(モニタリング)を実施しておく必要があります。これを行うことによって、性能問題の対応やトラブルシューティングの際の効率が大きく改善されます。
次回は、設計編です。