Application of JDBC in Performance Testing

はじめに

HTTP プロトコルを迂回して、データベースのパフォーマンスを直接テストできるでしょうか。データベースから CSV ファイルをエクスポートして負荷テストデータを構築するのが手間だと感じたことはありませんか。負荷テスト後のデータクリーンアップはどうすればよいでしょうか。データベースへの挿入(削除)レコードで負荷テストのリクエストを検証できるでしょうか。Alibaba Cloud のパフォーマンステストツール PTS を使えば、これらの課題を簡単に解決できます。

JDBC とは

JDBC (Java Database Connectivity) は、SQL ステートメントを実行するための Java API です。複数のリレーショナルデータベースへの統一されたアクセス手段を提供します。Java で記述されたクラスとインターフェイスの集合で構成されています。JDBC は、データベース開発者がデータベースアプリケーションを構築するための基盤となるベンチマークを提供します。

簡単に言えば、JDBC は次の 3 つの機能を実現します。データベースへの接続確立、データベースを操作するステートメントの送信、そして結果の処理です。

JDBC の設計思想

全体アーキテクチャ

JDBC はデータベースとの対話のための一連の標準を策定し、データベースベンダーがこの標準を実装することで、統一された JDBC インターフェイスを通じてさまざまなデータベースに接続できます。JDBC の役割は、基盤となるデータベース間の差異を隠蔽し、JDBC に準拠して記述されたコードをさまざまなデータベース上で実行できるようにすることです。その仕組みは次の図の通りです。

JDBC は Driver インターフェイスを定義しています。これがデータベースドライバーであり、データベースに関連するすべての操作はこのインターフェイスに集約されます。データベースベンダーは Driver インターフェイスを実装することで、上位レイヤーのアプリケーションと基盤となるデータベース間の対話を実現します。ドライバーは JDBC が提供する DriverManager を通じて登録されます。登録コードはドライバーの static ブロックに記述されます。以下の MySQL の登録コードの例を参照してください。

DriverManager はドライバーの管理を担い、ドライバーの登録と解除だけでなく、接続の直接取得も行えます。その仕組みを確認しましょう。以下のコードを見ると、実際の処理では登録済みのすべてのドライバーを走査し、接続を正常に確立できるドライバーを見つけ、Connection を返しています。DriverManager はプロキシのように機能し、実際の接続確立処理を個々のドライバーに委任します。

Connection の設計

前節で確認したように、データベースベンダーは Driver インターフェイスを実装してユーザーにサービスを提供します。Driver インターフェイスの中心的なメソッドは接続の取得です。Connection はデータベースとの対話におけるコアインターフェイスです。その設計を確認しましょう。

設計図を確認すると、主に DataSource と Connection の 2 つのインターフェイスタイプがあることがわかります。それぞれについて説明します。

・DataSource

ソースコードを直接確認すると、Driver と同様に、そのコアメソッドは接続の取得です。では、なぜ DataSource が必要なのでしょうか。Driver 自体も接続を取得するためのものではないでしょうか。DataSource が実際にどのように接続を取得するのか見ていきましょう。



ただし、JDBC は DataSource のインターフェイス定義のみを行い、具体的な実装は提供していません。次に、Spring が実装する SimpleDriverDataSource を例に、その仕組みを確認します。以下のコードの通り、DataSource の getConnection() メソッドは最終的に driver.connect() を呼び出して実際の接続を確立しています。冒頭で説明した通り、Driver がデータベースとの実際の対話を行うインターフェイスなのです。

ここで疑問が生じます。なぜ DataSource というインターフェイスが追加で必要なのでしょうか。不要ではないでしょうか。もちろんそうではありません。DataSource は強化版ドライバーです。接続確立のコア処理はドライバーに委任し、キャッシュの構築、分散トランザクションの処理、接続プールといった付随する処理を独自に担当します。クラスの設計図に示す通り、PTS で使用している Druid 接続プールを例に説明します。

・ConnectionPoolDataSource:接続プールを実装するデータソースです。データベースへの物理接続を直接作成するのではなく、物理接続をプール管理する論理的な実装です。

・PooledConnection:ConnectionPoolDataSource と連携して、プールされたオブジェクト PooledConnection を取得し、それを通じて間接的に物理接続を取得します。

接続プールを利用することで、接続管理の煩雑さから解放され、接続の利用効率が向上し、負荷テストの再現能力も向上します。

Statement の設計

接続を確立した後、SQL ステートメントを記述してデータベースに実行させます。これらは Statement を通じて実装されます。主に以下のタイプに分かれます。

・Statement:静的な SQL ステートメントを定義します。実行のたびに再コンパイルが必要で、通常は単一のクエリを実行して結果を返す場面に適しています。

・PreparedStatement:パラメーター付きの事前コンパイル済み SQL ステートメントを定義します。2 回目以降の実行ではキャッシュからステートメントが取得されるため、再コンパイルが不要です。同じロジックの SQL ステートメントを複数回実行する場合に適しています。また、SQL インジェクション防止機能も備え、セキュリティと効率性の両面で優れており、頻繁に使用されます。パフォーマンステストでは、PreparedStatement を選択するのが最適です。

・CallableStatement:ストアドプロシージャの呼び出しに使用します。

ResultSet の設計

JDBC は ResultSet インターフェイスを使用して Statement の実行結果を受け取ります。ResultSet はポインター (next()) を通じて検索結果を 1 件ずつ取得できます。ポインターが特定のデータを指した時点で、任意の列のデータを自由に取得できます。PTS は ResultSet を CSV ファイルに変換することで、単一の SQL ステートメントで複雑な負荷テストデータの構築をサポートします。

JDBC アーキテクチャのまとめ

以上の説明から、JDBC の設計は階層的であることがわかります。

(1) Driver と DriverManager はデータベースを対象としており、Java によるデータベースアクセスの仕様を設計しています。データベースベンダーはこの仕様を実装するだけで済みます。

(2) DataSource と Connection はアプリケーション開発者を対象としており、JDBC が具体的にデータベースとどのように対話するかを気にする必要はありません。統一された DataSource インターフェイスを通じて Connection を取得し、その Connection を通じてユーザーのデータ操作を実装できます。

(3) Statement は具体的な SQL コマンドを運び、ユーザーはさまざまなステートメントを定義してデータベースに指示を送れます。

(4) ResultSet は SQL コマンドの実行結果を運ぶために使用されます。

これで、ドライバーの読み込み → 接続の確立 → コマンドの実行 → 結果の返却という、データベースとの対話の全プロセスが完了しました。このプロセスを PTS のパフォーマンステストに柔軟に組み込めば、冒頭で挙げたさまざまな課題を解決できます。

パフォーマンステストにおける JDBC の活用

データベースのパフォーマンステスト

・背景

ほとんどのデータベース操作は HTTP、FTP、またはその他のプロトコル経由で実行されますが、中間プロトコルを迂回してデータベースを直接テストすることにも意義があります。たとえば、すべての関連クエリをトリガーするのではなく、特定の重要なクエリのみを対象にパフォーマンスをテストする場合や、高負荷状態での新規データベースの動作を検証する場合です。また、データベース接続プールパラメーター(最大接続数など)を検証する必要がある場合や、時間とリソースを節約したい場合にも有効です。SQL の最適化において、コード内の SQL ステートメントやその他のデータベース操作を変更するのは非常に手間がかかりますが、JDBC を使った負荷テストならコードへの侵入を避け、SQL チューニングに集中できます。

・手順

1. シナリオを作成します。PTS コンソールの「負荷テストセンター」→「シナリオの作成」で PTS 負荷テストシナリオを作成します。

2. シナリオを設定します。PTS は MySQL や PostgreSQL を含む 4 種類のデータベースの負荷テストをサポートしています。JDBC URL、ユーザー名、パスワード、SQL ステートメントを入力するだけで負荷テストを開始できます。また、PTS は ResultSet からデータを抽出して出力パラメーターとして下流の API で利用したり、応答のアサーションを実行したりすることもできます。

3. 負荷テスト中の監視とテストレポート。PTS は ApsaraDB RDS のクラウドリソース監視との連携をサポートしており、負荷テスト中に RDS のリアルタイムパフォーマンス指標を確認できます。さらに、PTS は見やすく包括的な負荷テストレポートとサンプリングログを提供し、いつでも確認できます。

負荷テストデータの構築

・背景

異なるユーザーログインのシミュレーションやサービスパラメーター転送の負荷テストなどのシナリオでは、負荷テストリクエストのさまざまな動的な操作を実現するためにパラメーター機能が必要です。従来の CSV ファイルパラメーターを使用すると、ファイルサイズの制限や手動作成の手間がかかります。JDBC を使って負荷テストデータを構築すれば、これらの問題を回避できます。

・手順

1. データソースを追加します。シナリオ編集 - データソース管理で、DB データソースの追加を選択し、URL、ユーザー名、パスワード、SQL を入力します。

2. パラメーターを追加します。カスタムパラメーター名と列インデックスを入力します。

3. デバッグ検証を行います。デバッグシナリオをクリックして、抽出された結果セットが期待通りか確認します。

その後、任意のパラメーターを ${} 参照で利用できます。

負荷テストのダーティデータクリーンアップ

・背景

書き込みリクエストの負荷テストでは、データベースに大量のダーティデータが発生する可能性があります。負荷テスト後に自動的にクリーンアップするにはどうすればよいでしょうか。

・手順

PTS はユーザーにソリューションを提供します。PTS はシリアルリンクの論理的な順序付けをサポートしており、プレリンク、通常リンク、後続リンクの 3 つのリンクタイプがあります。実行順序は先頭から末尾です。後続リンクとして設定するには、反復回数を入力します。

Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00

phone お問い合わせ
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.