クラウドデータ移行サービスの観点から見た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 プログラム

推薦する

Nofollowはコメントやメッセージ内のリンクを本当に機能させる

コメントとメッセージはもともと、ウェブマスターがコミュニティと読者層を構築するための優れた手段でした...

nginx の場所に複数の Proxy_pass メソッドがある

1. まず、nginxの位置情報に関する関連知識を確認しましょう1) 位置マッチング手順: ~ #波...

Mysql の読み取り/書き込み分離期限切れに対する一般的な解決策

MySQLの読み書き分離の落とし穴読み取りと書き込みの分離の主な目的は、メイン データベースの負荷を...

CSSはBEM命名規則の実践を使用する

クラスを見るとき、どのような情報を得たいですか?このクラスはどこで使用され、その機能は何ですか?この...

CentOS7でPHPスケジュールタスクを実行する方法

序文この記事は主に CentOS7 で PHP スケジュールタスクを実行することに関する関連コンテン...

Linux スワップメモリ​​を拡張する方法

スワップ メモリとは、主に物理メモリが不足している場合に、システムがハード ディスク領域の一部をサー...

Vueの監視方法のケースの詳細な説明

Vueでの監視方法時計知らせ名前: 監視する属性に同じ名前を付ける必要があります。 1. 機能Vue...

マインスイーパゲームを実装するための jQuery プラグイン (1)

この記事では、jQueryプラグインを使用したマインスイーパゲームの最初の記事の具体的なコードを参考...

Vueで親子コンポーネント通信を実装する方法

目次1. 親コンポーネントと子コンポーネントの関係2. 小道具3. $エミット4. $親V. 結論 ...

CSS スタイルを使用して表のフォントを垂直中央に配置する方法

CSS スタイルを使用して表内のフォントを垂直方向に中央揃えする方法は次のとおりです。下図のようなカ...

HTML減量 HTMLタグを合理化してWebページを作成する

HTML4 についてHTML (XHTML ではありません)、MIME タイプは text/html...

Vmvare 仮想マシンを使用して Ubuntu のルート ディレクトリをパーティション分割する方法の紹介

目次序文根拠手順1. CDから仮想マシンを起動する2. GPartedツールを使用してパーティション...

4種類のMySQL接続とマルチテーブルクエリの詳細な説明

目次MySQL 内部結合、左結合、右結合、外部結合、複数テーブルクエリビルド環境: 1. 内なる慈恩...

ウェブページのCSSの優先順位について詳しく説明します

CSS の優先順位について話す前に、CSS とは何か、CSS が何に使用されるのかを理解する必要があ...