検索
ホームページデータベースmysql チュートリアルMySQL JDBC StreamResult の通信原理に関する簡単な説明

MySQL JDBC StreamResult の通信原理に関する簡単な説明

Oct 19, 2018 pm 04:33 PM
javajdbcmysqlデータベース

この記事では、MySQL JDBC StreamResult の通信原理について簡単に説明します。必要な方は参考にしていただければ幸いです。

MySQL JDBC を使用して大量のデータ (たとえば、1GB 以上) を読み取ったことがある人は、読み取り時にメモリが Java ヒープでオーバーフローする可能性が高いことを知っているはずです。その解決策はステートメントです。 .setFetchSize(Integer.MIN_VALUE) を使用し、カーソルが読み取り専用で前方にスクロールすることを確認します (カーソルのデフォルト値)。タイプを com.mysql.jdbc.StatementImpl にキャストしてから、その内部メソッド enableStreamingResults を呼び出すこともできます。 () この方法では、データ メモリの読み取りがハングすることはなく、この 2 つによって達成される効果は同じです。もちろん useCursorFetch も使用できますが、このメソッドのテスト結果のパフォーマンスは StreamResult のパフォーマンスよりもはるかに遅いのはなぜでしょうか。この記事ではその一般原則について説明します。

MySQL JDBC の内部処理コードが 3 つのクラスに分割されて完成していることは、これまでの記事や書籍で紹介しましたが、データベースと JDBC の関係はどのようになっているのかまでは掘り下げたことがありませんでした。彼らの間のプロセスは?しばらくの間、これはサーバー側の動作、またはクライアントとサーバー間の連携動作であると考えてきましたが、今日はそうではなく、この動作が何であるかについて説明します。

[最初に簡単な通信を確認してください]:

JDBC とデータベース間の通信は Socket を通じて完了するため、データベースを SocketServer プロバイダー Square として扱うことができます。 SocketServer がデータを返す場合 (SQL 結果セットの返しと同様)、プロセスは次のようになります。 サーバー プログラム データ (データベース) -> カーネル ソケット バッファ -> クライアント ソケット バッファ -> クライアント エンド プログラム (JVM メモリ) JDBC の場所)

これまで、IT 業界で誰もが目にしたことのある JDBC は、MySQL JDBC、SQL Server JDBC、PG JDBC、Oracle JDBC です。 NoSQL クライアント: Redis クライアント、MongoDB クライアント、Memcached の場合でも、データは基本的に同じロジックに従います。

MySQL JDBC StreamResult の通信原理に関する簡単な説明

[デフォルトで MySQL JDBC を使用してデータを直接読み取るとハングするのはなぜですか? ]

(1) MySQL Server によって開始された SQL 結果セットはすべて、OutputStream を通じてデータを出力します。つまり、データはローカル Kennel に対応するソケット バッファーに書き込まれます。これはメモリ コピーです。コピーはこの記事の焦点では​​ありません)。

(2) このとき、ケンネルのバッファにデータがある場合、TCP リンク (JDBC によってアクティブに開始されるソケット リンク) を介してデータが返送されます。 JDBC が配置されているマシンでは、最初に Kennel エリアに入り、さらに Buffer エリアに入ります。

(3) JDBC が SQL 操作を開始した後、Java コードは inputStream.read() 操作をブロックします。バッファーにデータがある場合、JDBC が起動されて、バッファー内のデータを読み取ります。 Java メモリにとって、これは JDBC 側のメモリ コピーです。

(4) 次に、MySQL JDBC は引き続きバッファ データを Java メモリに読み取り、MySQL Server はデータの送信を続けます。データが完全に組み立てられる前に、クライアントによって開始された SQL 操作は応答しないことに注意してください。これは、実際には、データがローカルに送信され、JDBC が応答しているように感じられることを意味します。最初のデータ部分が実行メソッドが呼び出された場所にまだ結果セットを返していませんが、バッファからデータを継続的に読み取ります。

(5) 重要なのは、この愚か者は、テーブル全体が自宅に保存されているかどうかに関係なく、テーブル全体の内容を Java メモリに読み込むことです。次のステップは次のステップです。メモリオーバーフロー。

[JDBC パラメータで useCursorFetch=true を設定すると問題を解決できます]

このソリューションは実際に FetchSize 設定の問題を解決できます。このソリューションは実際に MySQL に指示します。必要なサーバー データ量、毎回必要なデータ量、通信プロセスは次のようになります:

MySQL JDBC StreamResult の通信原理に関する簡単な説明

これは単なるものです。私たちの生活と同じように、私に必要なのは、スーパーに行って、必要なだけ買うことです。ただし、この種のインタラクションは、自宅に居ながらにして自宅に届けられるものとは異なります。つまり、データが 1 億件ある場合、ネットワーク時間のオーバーヘッドが必要になります。 , FetchSize を 1000 に設定すると、往復の通信が 100,000 回になります。同じコンピュータ ルーム内のネットワーク遅延が 0.02ms の場合、100,000 回の通信で 2 秒追加されますが、これは大したことではありません。したがって、コンピューター室全体の遅延時間が 2ms であれば、遅延時間は 200 秒長くなります (つまり、3 分 20 秒)。中国の都市全体の遅延時間が 10 ~ 40 ミリ秒であれば、時間は 1000 ~ 4000 秒になります。国を超えて 200 ~ 300 ミリ秒の場合はどうなるでしょうか?時間は10時間以上長くなります。

ここでの計算には、システム コールの増加、スレッドが待機およびウェイクアップするコンテキストの増加、および全体的なパフォーマンスに対するネットワーク パケットの再送信の影響は含まれていません。そのため、このソリューションは、それは妥当なようですが、確かにパフォーマンスはあまり良くありません。

さらに、MySQL はクライアントがデータの消費をいつ終了するかを認識せず、対応するテーブルに DML 書き込み操作がある可能性があるため、MySQL は削除する必要があるデータを保存するための一時テーブル スペースを作成する必要があります。したがって、useCursorFetch を有効にして大きなテーブルを読み取ると、MySQL でいくつかの現象が発生します。

(1) 通常のハードディスクの場合、大量の IO 読み取りがあるため、IOPS が急増します。ビジネス文書作成にジッターが発生する可能性があります。

(2) この一時領域がデータベース全体で大きな割合を占めると、データベースのディスク書き込みが発生する可能性があります。いっぱいの場合、結果セットが読み取られた後、またはクライアントが Result.close() を開始したときに、スペースは MySQL によって再利用されます。

(3) CPU とメモリは、CPU の能力によって決まる一定の割合で増加します。

(4) クライアント JDBC は SQL を開始した後、SQL 応答データを長時間待機します。この間、サーバーはデータを準備します。この待機は、何も設定しない本来の JDBC の方法とは異なります。内部原理は異なりますが、前者はネットワーク バッファからデータを読み取り続け、MySQL データベースは一時的なデータ領域を準備しており、JDBC に応答しません。

[データの読み取りストリーム]

最初の方法は Java をハングさせる原因となり、2 番目の方法は非効率で MySQL データベースに大きな影響を与えることがわかっています。 、クライアントの応答も遅い場合は、問題を解決することしかできないため、次にストリームの読み取りメソッドを見てみましょう。

前述したように、statement.setFetchSize(Integer.MIN_VALUE) または com.mysql.jdbc.StatementImpl.enableStreamingResults() を使用すると、開始前に FetchSize を使用して結果セットを読み取ることができなくなります。手動で設定し、カーソルが FORWARD_ONLY であることを確認してください。

この方法は素晴らしいです。メモリがハングすることはなくなり、応答も速くなり、少なくとも IOPS は大きくならず、ディスク使用量も少なくなるそうです。消えてしまいます。以前は、JDBC で個別のコードしか見ていなかったので、それが MySQL と JDBC の間の別の通信プロトコルだと思っていましたが、それが「クライアントの動作」であることが判明したとは、まったく知りませんでした。そう、それはクライアントです。行動。

enableStreamingResults() を開始するとき、サーバーとの対話はほとんど行われません。つまり、サーバーはメソッド 1 に従ってデータを返し、その後サーバーはデータをバッファにプッシュします。クライアントはどうやってプレッシャーに耐えますか?

JDBC では、ストリーム結果セット処理を有効にしても、すべてのデータが Java メモリに一度に読み込まれるわけではありません。つまり、図 1 のデータは一度に読み取られません。Java バッファは 1 つのパッケージを読み取ります。 (このパッケージは Java の byte[] 配列として理解できます)。一度に多くのデータを読み取ることができ、データの整合性を確保するために下方への読み取りを続けるかどうかを確認します。ビジネス コードはバイトに基づいて行に解析され、ビジネス側で使用されます。

サーバーはバッファーへのデータのプッシュを開始し、両側のバッファーがいっぱいになると、データがクライアントのカーネル バッファーをいっぱいにします。データが受信者に送信されると、この時点でコンシューマのバッファもいっぱいになるため、送信者のスレッドはブロックされ、相手がデータの一部を消費するのを待ちます。相手がデータの一部を消費する場合は、そのデータの一部を受信者にプッシュすることができます。それ。この接続は、JDBC ストリーム データが消費される前に、バッファ データがいっぱいの場合、データを送信する MySQL のスレッドがブロックされ、バランスが確保されるようです (このために、Java のソケットを使用して試すことができます)以下の場合はこれに当てはまりますか)。

JDBC クライアントの場合、データは毎回、コミュニティ内の宅配ボックスから少し離れたローカル カーネル バッファーで取得されるため、当然のことながら、配送されるたびに RT よりもコストが高くなります。スーパーマーケットの場合ははるかに小さく、このプロセスは準備されたデータであるため、IO ブロック プロセスはありません (MySQL サーバーによって渡されるデータがデータを処理するコンシューマほど高速でない場合、通常はコンシューマのみが実行しません)。これは、テスト コードがデータを直接破棄した場合にのみ発生します)。現時点では、コンピューター ルーム間、地域間、国間を問わず、サーバーが応答を開始する限り、データは継続的に配信されます。 、そしてこのアクションは最初のタイプでもあり、その方法は経験する必要があるプロセスでもあります。

最初の方法と比較すると、JDBC を使用するとメモリ オーバーフローが発生しませんが、メモリ オーバーフローを起こさずに大きなテーブルを読み込んだ場合でも、応答に時間がかかります。 1. データの転送プロセス中に、対応するデータ行がロックされます (変更を防ぐため)。一方、MyISAM を使用すると、テーブル全体のロックが追加されます。ビジネスブロック。

[理論的には、その気になればさらに進めることができます]

理論的にはこの方法の方が優れていますが、完璧主義の観点からは、続けることができます。怠け者にとって、私たちが考えているのは、誰かがそれを私の家に持ってきて、たとえそれを私の口に入れたかということです。私の口を分解できたら素晴らしいでしょう。

技術的には、これは確かに理論上は可能ですが、JDBC がカーネルから Java にメモリをコピーするのに時間がかかるため、別の人がこれを行うと、私が家で他のことをしている間は機能しません。必要なときは家から直接来ますので時間の節約になります。すべての間違いは確かに保存されますが、問題は誰がそれを送信するかです。

これを行うには、プログラムにスレッドを追加し、カーネル データをアプリケーション メモリにコピーし、アプリケーションが直接使用できるようにデータ行に解析する必要がありますが、これは必ずしも完璧でしょうか?実際、途中で調整の問題が発生します。たとえば、家で料理をしたいときに調味料のパックが足りない場合、階下で自分で購入することもできますが、誰かに届けてもらう必要があります。この時点で他の料理はすべて調理されており、調味料が 1 袋だけ残っている場合は、調味料が自宅に届くのを待つしかありません。料理の次のステップ。したがって、理想的な状況では、メモリのコピー時間を大幅に節約できますが、調整ロックのオーバーヘッドがいくらか増加します。

では、カーネル バッファから直接データを読み取ることは可能でしょうか?

理論的には可能です。この問題を説明する前に、まずこのメモリ コピー以外に何が存在するかを理解しましょう。

JDBC はカーネル バッファからバイナリ形式でデータを読み取ります。取得の際、さらに特定の構造化データに解析されます。この時点では、ResultSet の特定の行の構造化データをビジネス パーティに返す必要があるためです。つまり、RowData によって生成されたデータのコピーが存在する必要があります。また、JDBC は特定のオブジェクト タイプ (バイト [] 配列など) を返します。一部のシナリオの実装では、返された結果 (バイト [1) のバイト [] の内容を変更する必要はありません。 ] = 0xFF) を使用して、ResultSet 自体の内容を変更することにより、別のメモリ コピーが作成され、文字列、ネットワーク出力なども作成されます。これらはビジネスレベルでは避けられないものですが、この小さなコピーに比べれば、それは単純です。そのため、プログラムのボトルネックがここにある場合を除き、全体的にはほとんど簡単ではないと考えて、これを実行しませんでした。

したがって、全体的な観点から見ると、メモリのコピーは避けられませんが、今回はシステムレベルの呼び出しにすぎず、技術的には、カーネルから直接実行できるオーバーヘッドが大きくなります。データの読み取り中ですが、この時点では、より多くのリモート データを転送できるように、バッファからデータをバイト単位で取り出す必要があります。そうしないと、バッファからメモリ コピーに戻ります。カーネルからアプリケーションへ。

相対的に言えば、サーバーは直接 IO を通じてデータの送信を直接最適化できます (ただし、この方法でのデータ プロトコルはデータ ストレージ形式と一致しており、これは明らかに理論上のものにすぎません)。プロトコルを変更し、カーネル状態を通じてデータを直接送信する場合、変換の目的を達成するには、OS レベルのファイル システム プロトコルを変更する必要があります。


以上がMySQL JDBC StreamResult の通信原理に関する簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はsegmentfault思否で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
酸性の特性(原子性、一貫性、分離、耐久性)を説明します。酸性の特性(原子性、一貫性、分離、耐久性)を説明します。Apr 16, 2025 am 12:20 AM

酸性属性には、原子性、一貫性、分離、耐久性が含まれ、データベース設計の基礎です。 1.原子性は、トランザクションが完全に成功するか、完全に失敗することを保証します。 2.一貫性により、データベースがトランザクションの前後に一貫性を保証します。 3.分離により、トランザクションが互いに干渉しないようにします。 4.永続性により、トランザクションの提出後にデータが永久に保存されることが保証されます。

MySQL:データベース管理システムとプログラミング言語MySQL:データベース管理システムとプログラミング言語Apr 16, 2025 am 12:19 AM

MySQLは、データベース管理システム(DBMS)であるだけでなく、プログラミング言語にも密接に関連しています。 1)DBMSとして、MySQLはデータを保存、整理、取得するために使用され、インデックスを最適化するとクエリのパフォーマンスが向上する可能性があります。 2)SQLとPythonに埋め込まれたプログラミング言語とSQLalchemyなどのORMツールを使用すると、操作を簡素化できます。 3)パフォーマンスの最適化には、インデックス、クエリ、キャッシュ、ライブラリ、テーブル分割、およびトランザクション管理が含まれます。

MySQL:SQLコマンドでデータの管理MySQL:SQLコマンドでデータの管理Apr 16, 2025 am 12:19 AM

MySQLはSQLコマンドを使用してデータを管理します。 1.基本コマンドには、select、挿入、更新、削除が含まれます。 2。高度な使用には、参加、サブクエリ、および集計関数が含まれます。 3.一般的なエラーには、構文、ロジック、パフォーマンスの問題が含まれます。 4。最適化のヒントには、インデックスの使用、Select*の回避、制限の使用が含まれます。

MySQLの目的:データを効果的に保存および管理しますMySQLの目的:データを効果的に保存および管理しますApr 16, 2025 am 12:16 AM

MySQLは、データの保存と管理に適した効率的なリレーショナルデータベース管理システムです。その利点には、高性能クエリ、柔軟なトランザクション処理、豊富なデータ型が含まれます。実際のアプリケーションでは、MySQLはeコマースプラットフォーム、ソーシャルネットワーク、コンテンツ管理システムでよく使用されますが、パフォーマンスの最適化、データセキュリティ、スケーラビリティに注意を払う必要があります。

SQLとMySQL:関係を理解するSQLとMySQL:関係を理解するApr 16, 2025 am 12:14 AM

SQLとMySQLの関係は、標準言語と特定の実装との関係です。 1.SQLは、リレーショナルデータベースの管理と操作に使用される標準言語であり、データの追加、削除、変更、クエリを可能にします。 2.MYSQLは、SQLを運用言語として使用し、効率的なデータストレージと管理を提供する特定のデータベース管理システムです。

Innodb Redoログの役割を説明し、ログを元に戻します。Innodb Redoログの役割を説明し、ログを元に戻します。Apr 15, 2025 am 12:16 AM

INNODBは、レドログと非論的なものを使用して、データの一貫性と信頼性を確保しています。 1.レドログは、クラッシュの回復とトランザクションの持続性を確保するために、データページの変更を記録します。 2.Undologsは、元のデータ値を記録し、トランザクションロールバックとMVCCをサポートします。

説明出力(タイプ、キー、行、追加)で探す重要なメトリックは何ですか?説明出力(タイプ、キー、行、追加)で探す重要なメトリックは何ですか?Apr 15, 2025 am 12:15 AM

説明コマンドのキーメトリックには、タイプ、キー、行、および追加が含まれます。 1)タイプは、クエリのアクセスタイプを反映しています。値が高いほど、constなどの効率が高くなります。 2)キーは使用されているインデックスを表示し、nullはインデックスがないことを示します。 3)行はスキャンされた行の数を推定し、クエリのパフォーマンスに影響します。 4)追加の情報を最適化する必要があるというFilesortプロンプトを使用するなど、追加情報を提供します。

説明の一時的なステータスを使用し、それを回避する方法は何ですか?説明の一時的なステータスを使用し、それを回避する方法は何ですか?Apr 15, 2025 am 12:14 AM

Temporaryを使用すると、MySQLクエリに一時テーブルを作成する必要があることが示されています。これは、異なる列、またはインデックスされていない列を使用して順番に一般的に見られます。インデックスの発生を回避し、クエリを書き直し、クエリのパフォーマンスを改善できます。具体的には、expliect出力に使用を使用する場合、MySQLがクエリを処理するために一時テーブルを作成する必要があることを意味します。これは通常、次の場合に発生します。1)個別またはグループビーを使用する場合の重複排除またはグループ化。 2)Orderbyに非インデックス列が含まれているときに並べ替えます。 3)複雑なサブクエリを使用するか、操作に参加します。最適化方法には以下が含まれます。1)OrderbyとGroupB

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。