クラウドデータ移行サービスの観点から見たMySQLの大規模テーブル抽出モードの原理分析

クラウドデータ移行サービスの観点から見たMySQLの大規模テーブル抽出モードの原理分析

概要: 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 はデフォルトでストリーミング モードを使用するため、追加の構成は必要ありません。ストリーム モードでは、インターフェイス上のFetch Size無効になることに注意してください。理由については、前のセクションを参照してください。

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をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • mysql8.0.11データディレクトリ移行の実装
  • mysql8.0.20 のデータディレクトリを移行する方法
  • ローカルのMySQLをサーバーデータベースに移行する方法
  • MySQL イベント変更イベント (ALTER EVENT)、イベントの無効化 (DISABLE)、イベントの有効化 (ENABLE)、イベント名の変更、およびデータベース イベントの移行操作の詳細な説明
  • MySQL 5.7 の Docker バージョンを MySQL 8.0.13 にアップグレードし、データを移行する
  • MySQLデータベースを別のマシンに移行する方法の詳細な説明
  • MySQLデータベース移行により、大量のデータを迅速にエクスポートおよびインポートできます
  • Python で MySQL データ移行スクリプトを作成する
  • MySQLデータ移行の概要

<<:  JavaScript プロトタイプとプロトタイプチェーンの詳細

>>:  W3C チュートリアル (2): W3C プログラム

推薦する

Vue プロジェクトを実行するときに `--fix` オプションで修正できる可能性のある警告のエラー問題を解決します。

問題: vue-cil3 は、`--fix` オプションで修正できる可能性のある警告とともに実行され...

CentOS サーバーのセキュリティ構成戦略

最近、ブルートフォース攻撃によるサーバのクラッキングが頻発しています。侵入行為を大まかに分析し、よく...

MySQL ストアド関数の詳細な紹介

目次1. ストアド関数を作成する2. ストアド関数の呼び出し3. 保存された関数を削除する4. スト...

hrefパラメータ転送における中国語の文字化けについて

パラメータを渡すために href が必要で、パラメータが中国語の場合、文字化けした文字が表示されます...

Windows で Mysql を起動したときに 1067 が表示される場合の解決策

数日前に仕事を始めて、Mysql をインストールしたところ、開くことができました。今日、会社に行った...

表面的なウェブデザイン

<br />私はいつもYahooのウェブデザインが素晴らしいと信じてきました。しかし、こ...

さまざまなターミナルで Mac が SSH 経由でリモート サーバーに接続する方法の説明

Macはシェル(ターミナル)SSHを使用してリモートサーバーに接続します前提条件: 接続する必要があ...

JS WebSocket 切断理由とハートビートの仕組みの詳しい説明

1. 切断理由WebSocket が切断される理由は多数あります。WebSocket が切断されたと...

IE6/7 における a.getAttribute(href,2) 問題の分析と解決

簡単な説明<br />IE6および7では、一般的なaタグ(HTMLで記述され、DOM操作...

Docker を使用した ELK7.3.0 ログ収集サービスの導入に関するベスト プラクティス

最初に書くこの記事では、ELK 7.3.0 の展開についてのみ説明します。展開環境:システムセントO...

Nginx シグナル制御

Nginx の紹介Nginx は、高性能な HTTP およびリバース プロキシ サーバーであり、IM...

Nginx レベルで基本的なユーザー認証を構成する手順を完了します。

序文アプリケーション シナリオ: おそらく、内部 Web サイトは外部ユーザーにアクセス可能である必...

HTML/CSSにおける記号論の詳細な説明

この記事では、ソシュールの言語哲学などの理論に基づいて、CSS の class 属性は不要であると主...

Linux でファイルの作成時間を取得する方法と実践的なチュートリアル

背景ファイルの作成時刻を取得する必要がある場合があります。例えば: 「xtrabackup スキーマ...

Linux の MySQL でリモート接続を承認する方法

注意: 他のマシン (IP) は、承認なしではクライアント経由で MySQL データベースに接続でき...