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

推薦する

CSS3 での 2D および 3D 変換の実装

CSS3 は、要素の 2D 平面変換と視覚的な 3D 空間変換を実装します。2D 変換はより頻繁に使...

伝説的な VUE 構文シュガーは何をするのでしょうか?

目次1. 糖衣構文とは何ですか? 2. VUE の構文糖とは何ですか? 1. 最も一般的な構文シュガ...

実際のプロジェクトでElementUIを使用する手順の詳細な説明

目次1. テーブル自動ソート2. ページング機能3.el-checkbox-group 複数選択ボッ...

MySQL の主キーがクエリを高速化するために数値を使用するか UUID を使用するかについての簡単な分析

実際の開発では、MySQL の主キーは重複できず、主キーが自動的にインクリメントされることがあります...

React プロジェクトにおける TypeScript の使用の概要

序文この記事では、TS の基本的な概念ではなく、プロジェクトで TypeScript (以下、TS ...

Vue プロジェクトで mock.js を使用するための完全な手順

Vue プロジェクトで mock.js を使用する開発ツールの選択: Vscode 1. コマンドラ...

HTMLは読み取り専用のテキストボックスを実装しており、コンテンツを変更することはできません。

さっそく、コードを直接投稿します。具体的なコードは次のとおりです。 <!--方法 1: onf...

マークアップ言語 - テキストの CSS スタイルを指定する

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

MySQLの起動失敗の解決策

MySQLの起動失敗の解決策MySQLを起動できませんmysqlを停止した後、いくつかの操作(ホスト...

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

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

Linuxでテキスト比較を実現するコツを教えます

序文コードを書く過程で、必然的にコードに何らかの変更を加えることになります。しかし、変更を加えるとき...

MacでのMySQL初期化パスワード操作

Macでデータベースを操作する際に個人が遭遇するデータベース起動の問題の簡単な記録1. Apple-...

フロントエンドセキュリティの詳細な説明: JavaScript の http ハイジャック対策と XSS

目次HTTP ハイジャック、DNS ハイジャック、XSS HTTPハイジャックDNSハイジャックXS...

ウェブデザインにおけるテキスト入力ボックスのパラメータの説明

一般的なゲストブック、フォーラムなどでは、テキスト入力ボックスが使われています。これは HTML 言...