概要: MySQL JDBC 抽出にはどのような方法を使用すればよいでしょうか? その方法を説明します。 最近、クラウド上の移行プロジェクトで MySQL 抽出モードに悩まされました。最初はメモリオーバーフローについて顧客から批判を受け、その後、移行効率が低いことについて再び批判を受けました。 MySQL JDBC 抽出にはどのような方法を使用すればよいでしょうか? それについてお話ししましょう。 1.1 Java-JDBC通信の原則JDBC とデータベース間の通信はソケットを介して行われます。一般的なプロセスを下の図に示します。 Mysql サーバー -> カーネル ソケット バッファー -> クライアント ソケット バッファー -> JDBC が配置されている JVM 1.2 JDBCデータ読み取りの3つのモード1.2.1 方法1: JDBCデフォルトパラメータを使用してデータを読み取る主に以下のステップに分かれます。 1) Mysql サーバーは、OutputStream を介してソケット サーバーのローカル カーネル バッファーにデータを書き込みます。これはメモリ コピーです。 2) ソケット サーバーのローカル ケンネル バッファーにデータがある場合、そのデータは TCP リンクを介してソケット クライアントが配置されているマシンのケンネル バッファーに転送されます。 3) JDBC が配置されている JVM は、InputSream を使用してローカル Kennel Buffer データを JVM メモリに読み込みます。データがない場合、読み取りはブロックされます。 次のステップは、プロセス 1、2、3 を継続的に繰り返すことです。問題は、ソケット クライアントの JVM がローカル メモリのサイズを考慮せずにデフォルト モードでケンネル バッファーを読み取り、可能な限り読み取ってしまうことです。データが大きすぎると、FULL GC が発生し、メモリ オーバーフローが発生します。 JDBC APIドキュメントを参照してください。デフォルトモードのJavaデモコードは次のとおりです。 1.2.2 方法2: カーソルクエリ方法 1 のメモリ オーバーフロー問題を解決するために、JDBC はカーソル パラメータを提供します。JDBC 接続を確立するときに、useCursorFetch=true を追加します。カーソルを設定すると、JDBC はメモリ オーバーフローを回避するために、毎回抽出するデータの量をサーバーに通知します。通信プロセスを下の図に示します。 方法 2 のカーソル クエリはメモリ オーバーフローの問題を解決しますが、方法 2 はネットワークの品質に大きく依存します。ネットワーク遅延が増加すると、各通信が 10 ミリ秒増加すると仮定すると、100,000 回の通信には 1,000 秒長くかかることになります。ここでは各リクエストの RT のみを示します。TCP はメッセージを送信するたびに、データの信頼性を確保するためにフィードバック ACK を必要とします。クライアントが 100 行をフェッチするたびに (要求される行数は構成可能)、複数の通信が発生し、レイテンシの増加によって生じる効率の問題がさらに増大します。さらに、カーソル クエリでは、MySQL はクエリの終了遅延を予測できません。独自の DML 操作に対処するために、抽出するデータを保存するための一時領域がローカルに作成されます。したがって、カーソル クエリ中に次の現象が発生します。 a. IOPS が急上昇します。Mysql はデータ転送中に一時領域にデータを書き込み、一時領域からデータを読み取るため、大量の IO 操作が発生します。 b. ディスク容量が急増します。一時領域のライフサイクルは、JDBC 読み取りフェーズ全体に存在し、クライアントが Result.close() を開始するまで、MySQL によって再利用されません。 c. CPU とメモリが一定の割合で増加します。 カーソル クエリの原理については、ブログ「MySQL JDBC StreamResult 通信原理の分析」および JDBC ソース コードを参照してください。この記事では繰り返し説明しません。 JDBC APIドキュメントを参照してください。カーソルモードのJavaデモコードは次のとおりです。 1.2.3 方法3: ストリーム読み取りデータ方法 1 では JVM メモリ オーバーフローが発生します。方法 2 では FULL GC は発生しませんが、通信効率が低く、Mysql サーバーの IOPS が急上昇してディスク領域を消費します。そこで、データを読み取るためにStreamを導入します。結果を読み取る前にストリームを設定する必要があります。 方法 3 では、通信前にサーバーとクライアント間のやり取りを行わないため、通信効率が低下することはありません。サーバーはデータを準備し、それをサーバーのケンネル バッファーに書き込みます。これらのデータは、TCP リンクを介してクライアントのケンネル バッファーに送信されます。次に、クライアントの inputStream.read() メソッドが呼び出され、データを読み取ります。方法 1 とは異なり、クライアントは一度にパッケージのサイズのデータのみを読み取ります。パッケージが 1 行でいっぱいでない場合は、別のパッケージが読み取られます。クライアントがデータ転送速度よりも遅いデータを消費すると、クライアント側のケンネル領域のデータがいっぱいになり、サーバー側のケンネルデータもいっぱいになり、OuputStream がブロックされます。このように、ストリーム モードの JDBC は 2 つの貯水池を接続する水道管のようなもので、クライアントとサーバーのバランスが取れます。 JDBC クライアントの場合、データは毎回ケンネルから読み取られるため、方法 2 よりも効率が大幅に高く、毎回少量のデータを読み取ることで JVM メモリ オーバーフローが発生することはありません。サーバーの場合、Mysql は毎回ケンネルにデータを書き込むため、一時領域を作成する必要がなく、IO 読み取りも行われず、サーバーへの負荷も軽減されます。もちろん、方法 3 にも、ストリーミング時にキャンセルできないことや、キャンセルが非ブロッキングであるなどの独自の問題があります。 JDBC API ドキュメントを参照してください。多くのオンライン チュートリアルでは、useCursorFetch=trueResultSet.FETCH_REVERSE などの設定が必要です。実際、JDBC ドライバーのソース コードを調べたところ、エディターは fetchSize=Integer.MIN_VALUE を設定するだけでよく、その他の構成はデフォルト構成と一致していることがわかりました。カーソルモードのJavaデモコードは次のとおりです。 1.3 3つのモードでクラウドデータ移行サービスを最適化するCloud Data Migration (CDM) は、Huawei Cloud 上の移行ツールです。詳細については、CDM 公式 Web サイトを参照してください。編集者は、CDM を使用して、3 つのモードを切り替えてデータを抽出する方法を紹介します。 CDM はデフォルトでストリーミング データ抽出モード 3 を使用します。モード 1 に切り替える必要がある場合は、モード 2 の追加構成が必要です。 1.3.1 設定方法1: デフォルトの読み取り新しいMysqlコネクタを作成します。作成方法の詳細については、公式Webサイトを参照してください。詳細プロパティにuseCursorFetch=falseとadopt.stream=falseを追加します。 1.3.2 設定方法2: カーソルクエリMySQL コネクタを編集し、詳細プロパティに useCursorFetch=true と adopt.stream=false を追加します。カーソル クエリのサイズは、インターフェイスのフェッチ サイズを通じて調整できます。デフォルトは 1000 です。 1.3.3 設定方法3: ストリーミングCDM はデフォルトでストリーミング モードを使用するため、追加の構成は必要ありません。ストリーム モードでは、インターフェイス上の 1.3.4 パフォーマンス比較Mysql2Hive の CDM 移行ジョブを作成します。ソース テーブルには 101 個のフィールドと 100 万行のデータがあります。構成は次のとおりです。 方法1: 100万行のデータの書き込みには1分22秒かかります 方法2: 100万行を書き込み、fetchSzieをそれぞれ1、10、100、100に調整すると、最小時間消費は2分1秒になります。 方法3: 100万行を書き込む(1分5秒かかる) エディターは、100 万項目の小さなテーブルもテストしました。方法 1 と方法 3 の速度が方法 2 よりもはるかに速いことは明らかです。また、エディターは 1000 万項目の大きなテーブルもテストしました。方法 1 はメモリ制限を超え、方法 2 は正常に移行しましたが 20 分以上かかり、方法 3 はまだ 15 分以内に完了できました。 これで、クラウドデータ移行サービスの観点から見たMySQLの大規模テーブル抽出モードの原理分析に関するこの記事は終了です。より関連性の高いMySQLの大規模テーブル抽出コンテンツについては、123WORDPRESS.COMの以前の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: JavaScript プロトタイプとプロトタイプチェーンの詳細
>>: W3C チュートリアル (2): W3C プログラム
コメントとメッセージはもともと、ウェブマスターがコミュニティと読者層を構築するための優れた手段でした...
1. まず、nginxの位置情報に関する関連知識を確認しましょう1) 位置マッチング手順: ~ #波...
MySQLの読み書き分離の落とし穴読み取りと書き込みの分離の主な目的は、メイン データベースの負荷を...
クラスを見るとき、どのような情報を得たいですか?このクラスはどこで使用され、その機能は何ですか?この...
序文この記事は主に CentOS7 で PHP スケジュールタスクを実行することに関する関連コンテン...
スワップ メモリとは、主に物理メモリが不足している場合に、システムがハード ディスク領域の一部をサー...
Vueでの監視方法時計知らせ名前: 監視する属性に同じ名前を付ける必要があります。 1. 機能Vue...
この記事では、jQueryプラグインを使用したマインスイーパゲームの最初の記事の具体的なコードを参考...
目次1. 親コンポーネントと子コンポーネントの関係2. 小道具3. $エミット4. $親V. 結論 ...
CSS スタイルを使用して表内のフォントを垂直方向に中央揃えする方法は次のとおりです。下図のようなカ...
HTML4 についてHTML (XHTML ではありません)、MIME タイプは text/html...
目次序文根拠手順1. CDから仮想マシンを起動する2. GPartedツールを使用してパーティション...
1. Ubuntu Server 18.04.5 LTS システムのインストールUbuntuはデスク...
目次MySQL 内部結合、左結合、右結合、外部結合、複数テーブルクエリビルド環境: 1. 内なる慈恩...
CSS の優先順位について話す前に、CSS とは何か、CSS が何に使用されるのかを理解する必要があ...